SO response build module updated 93/39293/1
authorAnkitkumar Patel <ankit@research.att.com>
Tue, 27 Mar 2018 21:19:26 +0000 (17:19 -0400)
committerAnkitkumar Patel <ankit@research.att.com>
Tue, 27 Mar 2018 21:22:42 +0000 (17:22 -0400)
SO response build module is updated based on the HAS API.

Issue-ID: OPTFRA-208
Change-Id: I57ed198967d2dc9a58f1221eb57fda56fcb5fd2d
Signed-off-by: Ankitkumar Patel <ankit@research.att.com>
osdf/optimizers/placementopt/conductor/conductor.py
test/placement-tests/conductor_response.json [new file with mode: 0644]
test/test_so_response_gen.py [new file with mode: 0644]

index dc67517..8f286ec 100644 (file)
@@ -126,27 +126,32 @@ def conductor_response_processor(conductor_response, raw_response, req_id):
     """
     composite_solutions = []
     name_map = {"physical-location-id": "cloudClli", "host_id": "vnfHostName",
-                "cloud_version": "cloudVersion", "cloud_owner": "cloudOwner"}
+                "cloud_version": "cloudVersion", "cloud_owner": "cloudOwner",
+                "cloud": "cloudRegionId", "service": "serviceInstanceId", "is_rehome": "isRehome",
+                "location_id": "locationId", "location_type": "locationType"}
     for reco in conductor_response['plans'][0]['recommendations']:
         for resource in reco.keys():
             c = reco[resource]['candidate']
             solution = {
                 'resourceModuleName': resource,
-                'serviceResourceId': reco[resource]['service_resource_id'],
-                'inventoryType': c['inventory_type'],
-                'serviceInstanceId': c['candidate_id'] if c['inventory_type'] == "service" else "",
-                'cloudRegionId': c['location_id'],
+                'serviceResourceId': reco[resource].get('service_resource_id', ""),
+                'solution': {"identifier": c['inventory_type'],
+                             'identifiers': [c['candidate_id']],
+                             'cloudOwner': c.get('cloud_owner', "")},
                 'assignmentInfo': []
             }
+            for key, value in c.items():
+                if key in ["location_id", "location_type", "is_rehome", "host_id"]:
+                    try:
+                        solution['assignmentInfo'].append({"key": name_map.get(key, key), "value": value})
+                    except KeyError:
+                        debug_log.debug("The key[{}] is not mapped and will not be returned in assignment info".format(key))
 
             for key, value in reco[resource]['attributes'].items():
                 try:
-                    solution['assignmentInfo'].append({"variableName": name_map[key], "variableValue": value})
+                    solution['assignmentInfo'].append({"key": name_map.get(key, key), "value": value})
                 except KeyError:
                     debug_log.debug("The key[{}] is not mapped and will not be returned in assignment info".format(key))
-
-            if c.get('host_id'):
-                solution['assignmentInfo'].append({'variableName': name_map['host_id'], 'variableValue': c['host_id']})
             composite_solutions.append(solution)
 
     request_state = conductor_response['plans'][0]['status']
@@ -155,14 +160,15 @@ def conductor_response_processor(conductor_response, raw_response, req_id):
 
     solution_info = {}
     if composite_solutions:
-        solution_info['placementInfo'] = composite_solutions
+        solution_info.setdefault('placementSolutions', [])
+        solution_info['placementSolutions'].append(composite_solutions)
 
     resp = {
         "transactionId": transaction_id,
         "requestId": req_id,
         "requestState": request_state,
         "statusMessage": status_message,
-        "solutionInfo": solution_info
+        "solutions": solution_info
     }
     return resp
 
diff --git a/test/placement-tests/conductor_response.json b/test/placement-tests/conductor_response.json
new file mode 100644 (file)
index 0000000..e7037c2
--- /dev/null
@@ -0,0 +1,64 @@
+{
+  "plans": [
+    {
+      "status": "done",
+      "id": "plan_id",
+      "name": "Plan Name 1",
+      "links": [
+        [
+          {
+            "href": "http://conductor:8091/v1/plans/plan_id",
+            "rel": "self"
+          }
+        ]
+      ],
+      "recommendations": [
+        {
+          "vG": {
+            "inventory_provider": "aai",
+            "candidate": {
+              "candidate_id": "DLLSTX1A",
+              "cloud_owner": "CloudOwner1",
+              "inventory_type": "cloud",
+              "location_id": "DLLSTX1A",
+              "location_type": "openstack-cloud"
+            },
+            "attributes": {
+              "flavors": {
+                "flavor_label_1": "vim_flavor_X",
+                "flavor_label_2": "vim_flavor_Y"
+              },
+              "cloud_owner": "CloudOwner1",
+              "physical-location-id": "DLLSTX1A",
+              "cloud_version": "3.0",
+              "vim-id": "CloudOwner1_DLLSTX1A"
+            }
+          }
+        },
+        {
+          "vGMuxInfra": {
+            "attributes": {
+              "host_id": "vgmux_host_name",
+              "cloud_owner": "CloudOwner1",
+              "physical-location-id": "DLLSTX1A",
+              "service_instance_id": "21d5f3e8-e714-4383-8f99-cc480144505a",
+              "cloud_version": "3.0",
+              "vim-id": "CloudOwner1_DLLSTX1A"
+            },
+            "inventory_provider": "aai",
+            "service_resource_id": "12345",
+            "candidate": {
+              "is_rehome": "false",
+              "location_id": "DLLSTX1A",
+              "inventory_type": "service",
+              "candidate_id": "21d5f3e8-e714-4383-8f99-cc480144505a",
+              "host_id": "vgmux_host_name",
+              "cloud_owner": "CloudOwner1",
+              "location_type": "openstack-cloud"
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/test/test_so_response_gen.py b/test/test_so_response_gen.py
new file mode 100644 (file)
index 0000000..ab73ef6
--- /dev/null
@@ -0,0 +1,39 @@
+# -------------------------------------------------------------------------
+#   Copyright (c) 2017-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 unittest
+import json
+import yaml
+from osdf.utils.interfaces import json_from_file
+from osdf.optimizers.placementopt.conductor.conductor import conductor_response_processor
+from osdf.utils.interfaces import RestClient
+
+
+class TestSoResponseGen(unittest.TestCase):
+    def setUp(self):
+        main_dir = ""
+        conductor_response_file = main_dir + "test/placement-tests/conductor_response.json"
+        self.conductor_res = json_from_file(conductor_response_file)
+        self.rc = RestClient()
+
+    def test_so_response_gen(self):
+        res = conductor_response_processor(self.conductor_res, self.rc, "test")
+        self.assertEqual(len(res['solutions']['placementSolutions'][0]), 2)
+
+
+if __name__ == "__main__":
+    unittest.main()
\ No newline at end of file