From 715fdf699fbdefebd7706d474539bb5f307934ca Mon Sep 17 00:00:00 2001 From: Kaori Mitani Date: Wed, 21 Feb 2024 11:24:38 +0000 Subject: [PATCH] Fix output regarding PM Job/Threshold response There are two corrections: First, according to SOL003, "authentication" should not appear in the PmJobModifications response. Therefore, it has been removed from the output obtained when running "openstack vnfpm job update". Second, the data type of PmJob href, as defined in SOL003, has been changed to match the format of the Uri and Link href defined in SOL013. This adjustment ensures that the endpoints will now be displayed correctly. Closes-Bug: #2054420 Change-Id: Id79ed19090271de4e32742f37cf54b6853acba2e --- doc/source/cli/cli-etsi-vnfpm.rst | 69 +++++++++---------- .../user/v2/cnf/auto_scale_pm_job/index.rst | 1 - tacker/sol_refactored/common/pm_job_utils.py | 8 +-- .../conductor/vnfpm_driver_v2.py | 7 +- tacker/sol_refactored/controller/vnfpm_v2.py | 12 ++-- .../objects/v2/pm_job_modification.py | 4 +- .../functional/common/fake_grant_server.py | 2 +- .../common/test_pm_job_utils.py | 6 +- .../conductor/test_vnfpm_driver_v2.py | 2 +- .../controller/test_vnfpm_v2.py | 26 ++++++- 10 files changed, 81 insertions(+), 56 deletions(-) diff --git a/doc/source/cli/cli-etsi-vnfpm.rst b/doc/source/cli/cli-etsi-vnfpm.rst index a7a29259c..2cbdc4886 100644 --- a/doc/source/cli/cli-etsi-vnfpm.rst +++ b/doc/source/cli/cli-etsi-vnfpm.rst @@ -131,7 +131,6 @@ Result: +----------------+---------------------------------------------------------+ | Field | Value | +----------------+---------------------------------------------------------+ - | Authentication | | | Callback Uri | http://localhost:9990/notification/callback/callbackUri | +----------------+---------------------------------------------------------+ @@ -298,40 +297,40 @@ Result: .. code-block:: console - +-------------------------+------------------------------------------------------------------------------------------------------------------------+ - | Field | Value | - +-------------------------+------------------------------------------------------------------------------------------------------------------------+ - | Callback Uri | http://localhost:9990/notification/callback/callbackUri | - | Criteria | { | - | | "performanceMetric": [ | - | | "VCpuUsageMeanVnf.{7749c637-6e8d-4b6c-a6f4-563aa73744dd}" | - | | ], | - | | "collectionPeriod": 5, | - | | "reportingPeriod": 10 | - | | } | - | ID | ca9b58cf-8493-44e3-9e76-678ea0e80a80 | - | Links | { | - | | "self": { | - | | "href": "http://127.0.0.1:9890/vnfpm/v2/pm_jobs/ca9b58cf-8493-44e3-9e76-678ea0e80a80" | - | | }, | - | | "objects": [ | - | | { | - | | "href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/7749c637-6e8d-4b6c-a6f4-563aa73744dd" | - | | } | - | | ] | - | | } | - | Object Instance Ids | [ | - | | "7749c637-6e8d-4b6c-a6f4-563aa73744dd" | - | | ] | - | Object Type | Vnf | - | Reports | [ | - | | { | - | | "href": "/vnfpm/v2/pm_jobs/ca9b58cf-8493-44e3-9e76-678ea0e80a80/reports/53aafe25-7124-4880-8b58-47a93b3dc371", | - | | "readyTime": "2022-08-30T08:02:58Z" | - | | } | - | | ] | - | Sub Object Instance Ids | | - +-------------------------+------------------------------------------------------------------------------------------------------------------------+ + +-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------+ + | Field | Value | + +-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------+ + | Callback Uri | http://127.0.0.1:9990/notification/callbackuri/5c5985e3-9f28-4e80-9ed8-66c18cca50e5 | + | Criteria | { | + | | "performanceMetric": [ | + | | "VCpuUsageMeanVnf.5c5985e3-9f28-4e80-9ed8-66c18cca50e5" | + | | ], | + | | "collectionPeriod": 30, | + | | "reportingPeriod": 60 | + | | } | + | ID | 8a1979b3-29dc-4ba3-aeb5-acce07607648 | + | Links | { | + | | "self": { | + | | "href": "http://127.0.0.1:9890/vnfpm/v2/pm_jobs/8a1979b3-29dc-4ba3-aeb5-acce07607648" | + | | }, | + | | "objects": [ | + | | { | + | | "href": "http://127.0.0.1:9890/vnflcm/v2/vnf_instances/5c5985e3-9f28-4e80-9ed8-66c18cca50e5" | + | | } | + | | ] | + | | } | + | Object Instance Ids | [ | + | | "5c5985e3-9f28-4e80-9ed8-66c18cca50e5" | + | | ] | + | Object Type | Vnf | + | Reports | [ | + | | { | + | | "href": "http://127.0.0.1:9890/vnfpm/v2/pm_jobs/8a1979b3-29dc-4ba3-aeb5-acce07607648/reports/e138a740-039c-40d2-9467-85bef9819c90", | + | | "readyTime": "2024-02-21T09:00:53Z" | + | | } | + | | ] | + | Sub Object Instance Ids | | + +-------------------------+---------------------------------------------------------------------------------------------------------------------------------------------+ Help: diff --git a/doc/source/user/v2/cnf/auto_scale_pm_job/index.rst b/doc/source/user/v2/cnf/auto_scale_pm_job/index.rst index 828440974..39bc94043 100644 --- a/doc/source/user/v2/cnf/auto_scale_pm_job/index.rst +++ b/doc/source/user/v2/cnf/auto_scale_pm_job/index.rst @@ -585,7 +585,6 @@ Here is an example of changing target PM job: +----------------+--------------------------------------------------------------------------------------------+ | Field | Value | +----------------+--------------------------------------------------------------------------------------------+ - | Authentication | | | Callback Uri | http://127.0.0.1:9990/notification/callbackuri/a0205e7c-fdeb-4f6c-b266-962246e32626-update | +----------------+--------------------------------------------------------------------------------------------+ diff --git a/tacker/sol_refactored/common/pm_job_utils.py b/tacker/sol_refactored/common/pm_job_utils.py index 38645d755..4cd2de422 100644 --- a/tacker/sol_refactored/common/pm_job_utils.py +++ b/tacker/sol_refactored/common/pm_job_utils.py @@ -26,11 +26,11 @@ LOG = logging.getLogger(__name__) CONF = config.CONF -def update_report(context, job_id, report, timestamp): +def update_report(context, job_id, report, timestamp, endpoint): # update reports in the pmJob pm_job = get_pm_job(context, job_id) - job_report = _gen_job_report(job_id, report, timestamp) + job_report = _gen_job_report(job_id, report, timestamp, endpoint) if pm_job.obj_attr_is_set('reports'): pm_job.reports.append(job_report) @@ -40,9 +40,9 @@ def update_report(context, job_id, report, timestamp): return pm_job -def _gen_job_report(job_id, report, timestamp): +def _gen_job_report(job_id, report, timestamp, endpoint): return objects.VnfPmJobV2_Reports( - href=f'/vnfpm/v2/pm_jobs/{job_id}/reports/{report.id}', + href=f'{endpoint}/vnfpm/v2/pm_jobs/{job_id}/reports/{report.id}', readyTime=timestamp ) diff --git a/tacker/sol_refactored/conductor/vnfpm_driver_v2.py b/tacker/sol_refactored/conductor/vnfpm_driver_v2.py index 535c91c36..3de6ee193 100644 --- a/tacker/sol_refactored/conductor/vnfpm_driver_v2.py +++ b/tacker/sol_refactored/conductor/vnfpm_driver_v2.py @@ -42,7 +42,7 @@ class VnfPmDriverV2(): job_id = report.jobId timestamp = report.entries[0].performanceValues[0].timeStamp pm_job = self._update_job_reports( - context, job_id, report, timestamp) + context, job_id, report, timestamp, self.endpoint) # Send a notify pm job request to the NFVO client. # POST /{pmjob.callbackUri} @@ -79,10 +79,11 @@ class VnfPmDriverV2(): report.create(context) return report - def _update_job_reports(self, context, job_id, report, timestamp): + def _update_job_reports( + self, context, job_id, report, timestamp, endpoint): # update reports in the pmJob update_job = pm_job_utils.update_report( - context, job_id, report, timestamp) + context, job_id, report, timestamp, endpoint) with context.session.begin(subtransactions=True): update_job.update(context) return update_job diff --git a/tacker/sol_refactored/controller/vnfpm_v2.py b/tacker/sol_refactored/controller/vnfpm_v2.py index a68de60b1..df4f648c2 100644 --- a/tacker/sol_refactored/controller/vnfpm_v2.py +++ b/tacker/sol_refactored/controller/vnfpm_v2.py @@ -244,9 +244,9 @@ class VnfPmControllerV2(sol_wsgi.SolAPIController): with context.session.begin(subtransactions=True): pm_job.update(context) - pm_job_modifications = objects.PmJobModificationsV2( - callbackUri=pm_job.callbackUri, - ) + pm_job_modifications = objects.PmJobModificationsV2() + if body.get("callbackUri"): + setattr(pm_job_modifications, "callbackUri", body["callbackUri"]) resp = pm_job_modifications.to_dict() return sol_wsgi.SolResponse(200, resp, @@ -418,8 +418,10 @@ class VnfPmControllerV2(sol_wsgi.SolAPIController): with context.session.begin(subtransactions=True): pm_threshold.update(context) - pm_threshold_modifications = objects.ThresholdModificationsV2( - callbackUri=pm_threshold.callbackUri) + pm_threshold_modifications = objects.ThresholdModificationsV2() + if body.get("callbackUri"): + setattr( + pm_threshold_modifications, "callbackUri", body["callbackUri"]) resp = pm_threshold_modifications.to_dict() return sol_wsgi.SolResponse(200, resp, version=api_version.CURRENT_PM_VERSION) diff --git a/tacker/sol_refactored/objects/v2/pm_job_modification.py b/tacker/sol_refactored/objects/v2/pm_job_modification.py index 16e4ac20a..d28188de3 100644 --- a/tacker/sol_refactored/objects/v2/pm_job_modification.py +++ b/tacker/sol_refactored/objects/v2/pm_job_modification.py @@ -26,7 +26,7 @@ class PmJobModificationsV2(base.TackerObject, base.TackerObjectDictCompat): VERSION = '1.0' fields = { - 'callbackUri': fields.StringField(nullable=False), + 'callbackUri': fields.StringField(nullable=True), 'authentication': fields.ObjectField( - 'SubscriptionAuthentication', nullable=False), + 'SubscriptionAuthentication', nullable=True), } diff --git a/tacker/tests/functional/common/fake_grant_server.py b/tacker/tests/functional/common/fake_grant_server.py index b7d68ac31..48adf6f6c 100644 --- a/tacker/tests/functional/common/fake_grant_server.py +++ b/tacker/tests/functional/common/fake_grant_server.py @@ -320,7 +320,7 @@ def get_common_resp_info(request_body): return glance_image, flavour_vdu_dict, zone_name_list -@GrantServer.app.route('v1/grant/v1/grants', methods=['POST']) +@GrantServer.app.route('/v1/grant/v1/grants', methods=['POST']) def grant(): body = request.json request_body = Grant.convert_body_to_dict(body) diff --git a/tacker/tests/unit/sol_refactored/common/test_pm_job_utils.py b/tacker/tests/unit/sol_refactored/common/test_pm_job_utils.py index 93aabb3f2..33e5c67fb 100644 --- a/tacker/tests/unit/sol_refactored/common/test_pm_job_utils.py +++ b/tacker/tests/unit/sol_refactored/common/test_pm_job_utils.py @@ -63,8 +63,12 @@ class TestPmJobUtils(base.BaseTestCase): ) result = pm_job_utils.update_report(self.context, 'pm_job_1', - report, '2008-01-03 08:04:34') + report, '2008-01-03 08:04:34', + 'endpoint') + href = result.reports[0].href self.assertEqual('pm_job_1', result.id) + self.assertEqual( + f'endpoint/vnfpm/v2/pm_jobs/pm_job_1/reports/{report.id}', href) @mock.patch.object(objects.base.TackerPersistentObject, 'get_all') def test_get_pm_job_all(self, mock_pm): diff --git a/tacker/tests/unit/sol_refactored/conductor/test_vnfpm_driver_v2.py b/tacker/tests/unit/sol_refactored/conductor/test_vnfpm_driver_v2.py index f509ba6dc..9b7dc4681 100644 --- a/tacker/tests/unit/sol_refactored/conductor/test_vnfpm_driver_v2.py +++ b/tacker/tests/unit/sol_refactored/conductor/test_vnfpm_driver_v2.py @@ -145,5 +145,5 @@ class TestVnfPmDriverV2(base.BaseTestCase): mock_update.return_value = None result = VnfPmDriverV2()._update_job_reports( context=self.context, job_id='pm_job_1', report='report', - timestamp='timestamp') + timestamp='timestamp', endpoint='endpoint') self.assertEqual('pm_job_1', result.id) diff --git a/tacker/tests/unit/sol_refactored/controller/test_vnfpm_v2.py b/tacker/tests/unit/sol_refactored/controller/test_vnfpm_v2.py index d15d22a22..4c4856b6e 100644 --- a/tacker/tests/unit/sol_refactored/controller/test_vnfpm_v2.py +++ b/tacker/tests/unit/sol_refactored/controller/test_vnfpm_v2.py @@ -349,14 +349,23 @@ class TestVnfpmV2(base.BaseTestCase): } } body = { - 'objectType': 'Vnf', - 'callbackUri': 'callbackuri', + 'callbackUri': 'callbackUri', 'authentication': _SubscriptionAuthentication } result = self.controller.update(request=self.request, id='id', body=body) self.assertEqual(200, result.status) + self.assertEqual("callbackUri", result.body["callbackUri"]) + self.assertNotIn("authentication", result.body) + + body = { + 'authentication': _SubscriptionAuthentication + } + + result = self.controller.update(request=self.request, id='id', + body=body) + self.assertEqual({}, result.body) @mock.patch.object(objects.base.TackerPersistentObject, 'get_by_filter') @mock.patch.object(objects.base.TackerPersistentObject, 'get_by_id') @@ -609,7 +618,7 @@ class TestVnfpmV2(base.BaseTestCase): } } body = { - 'callbackUri': 'callbackuri_update', + 'callbackUri': 'callbackUri', 'authentication': _SubscriptionAuthentication } @@ -617,6 +626,17 @@ class TestVnfpmV2(base.BaseTestCase): request=self.request, thresholdId='id', body=body) self.assertEqual(200, result.status) + self.assertEqual('callbackUri', result.body['callbackUri']) + self.assertNotIn("authentication", result.body) + + body = { + 'authentication': _SubscriptionAuthentication + } + + result = self.controller.update_threshold( + request=self.request, thresholdId='id', + body=body) + self.assertEqual({}, result.body) @mock.patch.object(objects.base.TackerPersistentObject, 'get_by_id') def test_pm_threshold_update_not_exist(self, mock_pm):