diff --git a/pyproject.toml b/pyproject.toml index a689bb9..22b22be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "pika >= 1.2.0", "dataset", "pymongo > 3.0", - "sdx-pce @ git+https://github.com/atlanticwave-sdx/pce@3.0.0.dev2", + "sdx-pce @ git+https://github.com/atlanticwave-sdx/pce@3.0.0.dev3", ] [project.optional-dependencies] diff --git a/sdx_controller/controllers/l2vpn_controller.py b/sdx_controller/controllers/l2vpn_controller.py index dfefc9b..9a11e52 100644 --- a/sdx_controller/controllers/l2vpn_controller.py +++ b/sdx_controller/controllers/l2vpn_controller.py @@ -140,10 +140,12 @@ def place_connection(body): reason, code = connection_handler.place_connection(current_app.te_manager, body) - if code == 200: + if code // 100 == 2: db_instance.add_key_value_pair_to_db( "connections", service_id, json.dumps(body) ) + # Service created successfully + code = 201 logger.info( f"place_connection result: ID: {service_id} reason='{reason}', code={code}" @@ -151,7 +153,7 @@ def place_connection(body): response = { "service_id": service_id, - "status": "OK" if code == 200 else "Failure", + "status": "OK" if code // 100 == 2 else "Failure", "reason": reason, } @@ -163,7 +165,7 @@ def place_connection(body): # response = body # response["id"] = service_id - # response["status"] = "success" if code == 200 else "failure" + # response["status"] = "success" if code == 2xx else "failure" # response["reason"] = reason # `reason` is not present in schema though. return response, code @@ -203,16 +205,18 @@ def patch_connection(service_id, body=None): # noqa: E501 f"Placing new connection {service_id} with te_manager: {current_app.te_manager}" ) reason, code = connection_handler.place_connection(current_app.te_manager, body) - if code == 200: + if code // 100 == 2: db_instance.add_key_value_pair_to_db( "connections", service_id, json.dumps(body) ) + # Service created successfully + code = 201 logger.info( f"place_connection result: ID: {service_id} reason='{reason}', code={code}" ) response = { "service_id": service_id, - "status": "OK" if code == 200 else "Failure", + "status": "OK" if code // 100 == 2 else "Failure", "reason": reason, } except Exception as e: diff --git a/sdx_controller/handlers/connection_handler.py b/sdx_controller/handlers/connection_handler.py index e2a8e00..034bc1a 100644 --- a/sdx_controller/handlers/connection_handler.py +++ b/sdx_controller/handlers/connection_handler.py @@ -6,6 +6,7 @@ from sdx_pce.load_balancing.te_solver import TESolver from sdx_pce.topology.temanager import TEManager +from sdx_pce.utils.exceptions import TEError from sdx_controller.messaging.topic_queue_producer import TopicQueueProducer from sdx_controller.models.simple_link import SimpleLink @@ -143,7 +144,7 @@ def place_connection( connection_request=connection_request ) if traffic_matrix is None: - return "Could not generate a traffic matrix", 400 + return "Could not generate a traffic matrix", 402 logger.info(f"Generated graph: '{graph}', traffic matrix: '{traffic_matrix}'") @@ -152,7 +153,7 @@ def place_connection( logger.debug(f"TESolver result: {solution}") if solution is None or solution.connection_map is None: - return "Could not solve the request", 400 + return "Could not solve the request", 410 try: breakdown = te_manager.generate_connection_breakdown( @@ -166,6 +167,8 @@ def place_connection( ) logger.debug(f"Breakdown sent to LC, status: {status}, code: {code}") return status, code + except TEError as te_err: + return te_err except Exception as e: err = traceback.format_exc().replace("\n", ", ") logger.error(f"Error when generating/publishing breakdown: {e} - {err}") diff --git a/sdx_controller/test/test_l2vpn_controller.py b/sdx_controller/test/test_l2vpn_controller.py index f9f54f9..590483d 100644 --- a/sdx_controller/test/test_l2vpn_controller.py +++ b/sdx_controller/test/test_l2vpn_controller.py @@ -69,7 +69,7 @@ def test_delete_connection_with_setup(self): print(f"Response body: {connection_response.data.decode('utf-8')}") - self.assertStatus(connection_response, 200) + assert connection_response.status_code // 100 == 2 service_id = connection_response.get_json().get("service_id") print(f"Deleting request_id: {service_id}") @@ -99,7 +99,7 @@ def test_getconnection_by_id(self): # The service_id we've supplied above should not exist. # TODO: test for existing service_id. See # https://github.com/atlanticwave-sdx/sdx-controller/issues/34. - self.assertStatus(response, 404) + assert response.status_code // 100 == 4 def test_place_connection_no_topology(self): """ @@ -120,7 +120,7 @@ def test_place_connection_no_topology(self): # Expect 400 failure because the request is incomplete: the # bare minimum connection request we sent does not have # ingress port data, etc., for example. - self.assertStatus(response, 400) + assert response.status_code // 100 == 4 def test_place_connection_v2_no_topology(self): """ @@ -141,7 +141,7 @@ def test_place_connection_v2_no_topology(self): # Expect 400 failure because the request is incomplete: the # bare minimum connection request we sent does not have # ingress port data, etc., for example. - self.assertStatus(response, 400) + assert response.status_code // 100 == 4 def __test_with_one_topology(self, topology_file): """ @@ -163,7 +163,7 @@ def __test_with_one_topology(self, topology_file): # Expect 400 failure, because TEManager do not have enough # topology data. - self.assertStatus(response, 400) + assert response.status_code // 100 == 4 def test_place_connection_with_amlight(self): """ @@ -206,7 +206,7 @@ def test_place_connection_no_id(self): # Expect a 400 response because the required ID field is # missing from the request. - self.assertStatus(response, 400) + assert response.status_code // 100 == 4 # JSON response should have a body like: # @@ -218,7 +218,6 @@ def test_place_connection_no_id(self): # } response = response.get_json() - self.assertEqual(response["status"], 400) self.assertIn("is not valid under any of the given schemas", response["detail"]) def test_place_connection_with_three_topologies(self): @@ -242,7 +241,7 @@ def test_place_connection_with_three_topologies(self): # Expect 200 success because TEManager now should be properly # set up with all the expected topology data. - self.assertStatus(response, 200) + assert response.status_code // 100 == 2 def test_place_connection_with_three_topologies_added_in_sequence(self): """ @@ -276,11 +275,11 @@ def test_place_connection_with_three_topologies_added_in_sequence(self): if idx in [0, 1]: # Expect 400 failure because TEManager do not have all # the topologies yet. - self.assertStatus(response, 400) + assert response.status_code // 100 == 4 if idx == 200: # Expect 200 success now that TEManager should be set # up with all the expected topology data. - self.assertStatus(response, 200) + assert response.status_code // 100 == 2 def test_place_connection_v2_with_three_topologies_400_response(self): """ @@ -313,7 +312,7 @@ def test_place_connection_v2_with_three_topologies_400_response(self): # Expect a 400 response because PCE would not be able to find # a solution for the connection request. - self.assertStatus(response, 400) + assert response.status_code // 100 == 4 self.assertEqual( response.get_json().get("status"), "Failure", @@ -327,7 +326,7 @@ def test_place_connection_v2_with_three_topologies_400_response(self): service_id = response.get_json().get("service_id") self.assertNotEqual(service_id, original_request_id) - def test_place_connection_v2_with_three_topologies_200_response(self): + def test_place_connection_v2_with_three_topologies_201_response(self): """ Test case for connection request format v2. This request should be able to find a path. @@ -366,7 +365,7 @@ def test_place_connection_v2_with_three_topologies_200_response(self): # Expect a 200 response because PCE should be able to find a # solution for the connection request. - self.assertStatus(response, 200) + assert response.status_code // 100 == 2 self.assertEqual( response.get_json().get("status"), "OK", @@ -414,7 +413,7 @@ def test_place_connection_v2_with_any_vlan_in_request(self): print(f"POST response body is : {response.data.decode('utf-8')}") print(f"POST Response JSON is : {response.get_json()}") - self.assertStatus(response, 200) + assert response.status_code // 100 == 2 service_id = response.get_json().get("service_id") @@ -426,7 +425,7 @@ def test_place_connection_v2_with_any_vlan_in_request(self): print(f"GET response body is : {response.data.decode('utf-8')}") print(f"GET response JSON is : {response.get_json()}") - self.assertStatus(response, 200) + assert response.status_code // 100 == 2 # Expect a response like this: # @@ -513,7 +512,7 @@ def test_z100_getconnection_by_id_expect_404(self): print(f"Response body is : {response.data.decode('utf-8')}") - self.assertStatus(response, 404) + assert response.status_code // 100 == 4 def test_z100_getconnection_by_id_expect_200(self): """ @@ -533,7 +532,7 @@ def test_z100_getconnection_by_id_expect_200(self): print(f"Response body: {post_response.data.decode('utf-8')}") - self.assertStatus(post_response, 200) + assert post_response.status_code // 100 == 2 service_id = post_response.get_json().get("service_id") print(f"Got service_id: {service_id}") @@ -546,7 +545,7 @@ def test_z100_getconnection_by_id_expect_200(self): print(f"Response body: {get_response.data.decode('utf-8')}") - self.assertStatus(get_response, 200) + assert get_response.status_code // 100 == 2 @patch("sdx_controller.utils.db_utils.DbUtils.get_all_entries_in_collection") def test_z105_getconnections_fail(self, mock_get_all_entries): @@ -556,7 +555,7 @@ def test_z105_getconnections_fail(self, mock_get_all_entries): f"{BASE_PATH}/l2vpn/1.0", method="GET", ) - self.assertStatus(response, 404) + assert response.status_code // 100 == 4 def test_z105_getconnections_success(self): """Test case for getconnections.""" @@ -566,7 +565,7 @@ def test_z105_getconnections_success(self): ) print(f"Response body is : {response.data.decode('utf-8')}") - self.assertStatus(response, 200) + assert response.status_code // 100 == 2 assert len(response.get_json()) != 0