diff options
author | A200231121 <abhimanyu-kumar@t-systems.com> | 2024-01-05 15:18:46 +0530 |
---|---|---|
committer | Michal Jagiello <michal.jagiello@t-mobile.pl> | 2024-01-18 15:32:15 +0100 |
commit | 21c7d95ef3c079c068dd98c1a19b3dbd8295139a (patch) | |
tree | f5fd67b103dd794d4e062c4e39dcdb3a0b6394e8 | |
parent | da58d669b07dfe85053e6a49a74a65e5d364a5dd (diff) |
Added resource related API in NBI class
Add Resource class
Issue-ID: TEST-404
Signed-off-by: Michal Jagiello <michal.jagiello@t-mobile.pl>
Change-Id: I9b972f94aa613bbddb65f5492a1209ea0702b083
-rw-r--r-- | src/onapsdk/nbi/__init__.py | 2 | ||||
-rw-r--r-- | src/onapsdk/nbi/nbi.py | 113 | ||||
-rw-r--r-- | src/onapsdk/onap_service.py | 2 | ||||
-rw-r--r-- | tests/test_nbi.py | 138 |
4 files changed, 251 insertions, 4 deletions
diff --git a/src/onapsdk/nbi/__init__.py b/src/onapsdk/nbi/__init__.py index d3ceaf6..6d4470a 100644 --- a/src/onapsdk/nbi/__init__.py +++ b/src/onapsdk/nbi/__init__.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -from .nbi import Nbi, Service, ServiceOrder, ServiceSpecification +from .nbi import Nbi, Service, ServiceOrder, ServiceSpecification, Resource diff --git a/src/onapsdk/nbi/nbi.py b/src/onapsdk/nbi/nbi.py index 3af85f6..502a4f2 100644 --- a/src/onapsdk/nbi/nbi.py +++ b/src/onapsdk/nbi/nbi.py @@ -14,7 +14,7 @@ # limitations under the License. from abc import ABC from enum import Enum -from typing import Iterator, Optional +from typing import Iterator, Optional, List from uuid import uuid4 from onapsdk.aai.business.customer import Customer @@ -493,3 +493,114 @@ class ServiceOrder(Nbi, WaitForFinishMixin): # pylint: disable=too-many-instanc """ return self.status not in [self.StatusEnum.ACKNOWLEDGED, self.StatusEnum.IN_PROGRESS] + + +# Import the Nbi class +class Resource(Nbi): # pylint: disable=too-many-instance-attributes, too-many-arguments + """A class representing resource-related operations using NBI.""" + + def __init__(self, # pylint: disable=too-many-instance-attributes, too-many-arguments + unique_id: str, + href: str, + resource_type: Optional[str], + base_type: str, + value: str, + life_cycle_state: str, + resource_specification: dict, + resource_characteristics: Optional[List[dict]], + related_party: list, + note: Optional[List[dict]], + place: Optional[dict], + serial_number: Optional[str], + version_number: Optional[str]) -> None: + """Service object initialization. + + Args: + unique_id (str): Resource id , + href (str): Resource object href, + resource_type (str, optional): Type of resource, + base_type (str): Base type of resource, + value (str): Name of resource, + life_cycle_state (str): current state of resource, + resource_specification (dict): Resource specification, + resource_characteristics (list[dict], optional): List of resource characteristics, + related_party (list): List of related party in current resource, + note (list[dict], optional): List of note, + place (dict, optional): resource location + serial_number(str, optional), + version_number(str, optional) + """ + super().__init__() + self.unique_id: str = unique_id + self.href: str = href + self.resource_type: Optional[str] = resource_type + self.base_type: str = base_type + self.value: str = value + self.life_cycle_state: str = life_cycle_state + self.resource_specification: dict = resource_specification + self.resource_characteristics: Optional[List[dict]] = resource_characteristics + self.related_party: list = related_party + self.note: Optional[List[dict]] = note + self.place: Optional[dict] = place + self.serial_number: Optional[str] = serial_number + self.version_number: Optional[str] = version_number + + @classmethod + def get_all_resources(cls) -> Iterator["Resource"]: + """ + Get a list of all resource from the NBI. + + Returns: + Iterator[Resource]: This function will return list of resource object + """ + resource_json = cls.send_message_json("GET", "Get resources from NBI", + f"{cls.base_url}{cls.api_version}/resource/") + + # Converting response json to list of Response object + for resource in resource_json: + + yield Resource( + resource["id"], + resource["href"], + resource.get("@type"), + resource["@baseType"], + resource["value"], + resource["lifeCyleState"], + resource["resourceSpecification"], + resource.get("resourceCharacteristics"), + resource["relatedParty"], + resource.get("note"), + resource.get("place"), + resource.get("serialNumber"), + resource.get("versionNumber") + ) + + + @classmethod + def get_specific_resource(cls, resource_id: str) -> "Resource": + """ + Get a specific resource by ID from the NBI. + + Args: + resource_id (str): The ID of the resource to retrieve. + + Returns: + Resource: An instance of the Resource class representing the specific resource. + """ + response = cls.send_message_json("GET", "Get resources from NBI", + f"{cls.base_url}{cls.api_version}/resource/{resource_id}") + return Resource( + response["id"], + response["href"], + response.get("@type"), + response["@baseType"], + response["value"], + response["lifeCyleState"], + response["resourceSpecification"], + response.get("resourceCharacteristics"), + response["relatedParty"], + response.get("note"), + response.get("place"), + response.get("serialNumber"), + response.get("versionNumber") + ) diff --git a/src/onapsdk/onap_service.py b/src/onapsdk/onap_service.py index a219f5a..566c9bc 100644 --- a/src/onapsdk/onap_service.py +++ b/src/onapsdk/onap_service.py @@ -224,7 +224,7 @@ class OnapService(ABC): requests can be used here. Raises: - InvalidResponse: if JSON coudn't be decoded + InvalidResponse: if JSON couldn't be decoded RequestError: if other exceptions weren't caught or didn't raise APIError/ResourceNotFound: send_message() got an HTTP error code ConnectionFailed: connection can't be established diff --git a/tests/test_nbi.py b/tests/test_nbi.py index 97aef13..a2545d6 100644 --- a/tests/test_nbi.py +++ b/tests/test_nbi.py @@ -14,9 +14,11 @@ from collections import namedtuple from unittest import mock +import pytest from onapsdk.aai.business import Customer from onapsdk.exceptions import RequestError -from onapsdk.nbi import Nbi, Service, ServiceOrder, ServiceSpecification +from onapsdk.nbi import Nbi, Service, ServiceOrder, ServiceSpecification, Resource + SERVICE_SPECIFICATION = { "id": "a80c901c-6593-491f-9465-877e5acffb46", @@ -297,6 +299,115 @@ SERVICE_ORDER_STATE_UNKNOWN = { 'state': 'lalala' } +RESOURCES = [ + { + "id": "0efe5f46-7233-495d-826e-9d177b1866b4", + "href": "/nbi/api/v4/resource/0efe5f46-7233-495d-826e-9d177b1866b4", + "@type": "test_pnf_rollback/null", + "@baseType": "LogicalResource", + "value": "vnf-name-test-19-12", + "lifeCyleState": "Active", + "resourceSpecification": { + "id": "22e67c4a-f652-43d0-8975-63006c442718" + }, + "resourceCharacteristics": [ + { + "name": "prov-status", + "value": "NVTPROV" + }, + { + "name": "in-maint", + "value": "false" + } + ], + "relatedParty": [ + { + "id": "pnf_macro_customer", + "role": "ONAPcustomer" + } + ], + "note": [ + { + "text": "vnf-name-test-19-12 is available on k8sregionfour" + } + ], + "place": { + "id": "k8sregionfour", + "name": "gnb-cucp-sim-76d58f7bd7-sq8g5", + "role": "e728fdf9dc5914e2595d6cb9444da113f6042e29d52058c1424434879b600794" + } + }, + { + "id": "cf7b9996-1ae5-49b2-baf6-797599f5d89b", + "href": "/nbi/api/v4/resource/cf7b9996-1ae5-49b2-baf6-797599f5d89b", + "@type": "Demo service/null", + "@baseType": "LogicalResource", + "value": "test_abhimanyu_04", + "lifeCyleState": "Active", + "resourceSpecification": { + "id": "836398af-de68-404f-bf39-5d3cacfe92ae" + }, + "resourceCharacteristics": [ + { + "name": "prov-status", + "value": "NVTPROV" + }, + { + "name": "in-maint", + "value": "false" + } + ], + "relatedParty": [ + { + "id": "pnf_macro_customer", + "role": "ONAPcustomer" + } + ], + "note": [ + { + "text": "test_abhimanyu_04 is available on " + } + ] + } +] + +RESOURCE = { + "id": "0efe5f46-7233-495d-826e-9d177b1866b4", + "href": "/nbi/api/v4/resource/0efe5f46-7233-495d-826e-9d177b1866b4", + "@type": "test_pnf_rollback/null", + "@baseType": "LogicalResource", + "value": "vnf-name-test-19-12", + "lifeCyleState": "Active", + "resourceSpecification": { + "id": "22e67c4a-f652-43d0-8975-63006c442718" + }, + "resourceCharacteristics": [ + { + "name": "prov-status", + "value": "NVTPROV" + }, + { + "name": "in-maint", + "value": "false" + } + ], + "relatedParty": [ + { + "id": "pnf_macro_customer", + "role": "ONAPcustomer" + } + ], + "note": [ + { + "text": "vnf-name-test-19-12 is available on k8sregionfour" + } + ], + "place": { + "id": "k8sregionfour", + "name": "gnb-cucp-sim-76d58f7bd7-sq8g5", + "role": "e728fdf9dc5914e2595d6cb9444da113f6042e29d52058c1424434879b600794" + } +} @mock.patch.object(Nbi, "send_message") def test_nbi(mock_send_message): @@ -553,3 +664,28 @@ def test_service_order_wait_for_finish(): rv = namedtuple("Value", ["return_value"]) service_order._wait_for_finish(rv) assert rv.return_value + +@mock.patch.object(Resource, "send_message_json") +def test_query_resource_get_all(mock_query_resource_get_all): + mock_query_resource_get_all.return_value = RESOURCES + resources = Resource.get_all_resources() + resource = next(resources) + assert type(resource) == Resource + assert resource.unique_id is not None + mock_query_resource_get_all.return_value = [] + resources = Resource.get_all_resources() + with pytest.raises(StopIteration): + next(resources) + mock_query_resource_get_all.return_value = [] + resources = Resource.get_all_resources() + resource = next(resources, None) + assert resource is None + +@mock.patch.object(Resource, "send_message_json") +def test_query_resource_get_specific_resource(mock_specific_resource): + resource_id = "0efe5f46-7233-495d-826e-9d177b1866b4" + mock_specific_resource.return_value = RESOURCE + resource = Resource.get_specific_resource(resource_id) + assert type(resource) == Resource + assert resource.unique_id == RESOURCE.get("id") + assert resource.href == RESOURCE.get("href")
\ No newline at end of file |