From bb7f4c79e03883b05550e4d4c9ab11ec5ba4b08a Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Tue, 2 Jul 2024 15:47:00 +0200 Subject: [PATCH] Added pagination support. --- inventory_provider/gap.py | 71 ++++++++++++++++++++++++--------------- test/test_gap.py | 9 ++++- 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/inventory_provider/gap.py b/inventory_provider/gap.py index 35ecd020..31816ea5 100644 --- a/inventory_provider/gap.py +++ b/inventory_provider/gap.py @@ -125,33 +125,48 @@ def extract_router_info(device: dict, token: str, app_config: dict) -> dict or N def load_routers_from_orchestrator(app_config: dict) -> dict: """Gets devices from the orchestrator and returns a dictionary of FQDNs and vendors.""" token = get_token(app_config['aai']) - query = """ - { - subscriptions( - filterBy: {field: "status", value: "PROVISIONING|ACTIVE"}, - first: 500, - query: "tag:(RTR|OFFICE_ROUTER|Super_POP_SWITCH)" - ) { - page { - subscriptionId - product { - tag - } - } - } - } - """ routers = {} - response = make_request(body={'query': query}, token=token, app_config=app_config) - try: - devices = response['data']['subscriptions']['page'] - except (TypeError, KeyError): - devices = [] - - with concurrent.futures.ThreadPoolExecutor() as executor: - futures = [executor.submit(extract_router_info, device, token, app_config) for device in devices] - for future in concurrent.futures.as_completed(futures): - router_info = future.result() - if router_info is not None: - routers[router_info['fqdn']] = router_info['vendor'] + end_cursor = 0 + has_next_page = True + + while has_next_page: + query = f""" + {{ + subscriptions( + filterBy: {{field: "status", value: "PROVISIONING|ACTIVE"}}, + first: 100, + after: {end_cursor}, + query: "tag:(RTR|OFFICE_ROUTER|Super_POP_SWITCH)" + ) {{ + pageInfo {{ + hasNextPage + endCursor + }} + page {{ + subscriptionId + product {{ + tag + }} + }} + }} + }} + """ + + response = make_request(body={'query': query}, token=token, app_config=app_config) + try: + devices = response['data']['subscriptions']['page'] + page_info = response['data']['subscriptions']['pageInfo'] + end_cursor = page_info['endCursor'] + has_next_page = page_info['hasNextPage'] + except (TypeError, KeyError): + devices = [] + has_next_page = False + + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = [executor.submit(extract_router_info, device, token, app_config) for device in devices] + for future in concurrent.futures.as_completed(futures): + router_info = future.result() + if router_info is not None: + routers[router_info['fqdn']] = router_info['vendor'] + return routers diff --git a/test/test_gap.py b/test/test_gap.py index 3bb88330..27b5a60a 100644 --- a/test/test_gap.py +++ b/test/test_gap.py @@ -71,7 +71,14 @@ def test_load_routers_from_orchestrator(mocker): 'page': [ {'subscriptionId': '1', 'product': {'tag': 'RTR'}}, {'subscriptionId': '2', 'product': {'tag': 'OFFICE_ROUTER'}} - ] + ], + "pageInfo": { + "totalItems": 2, + "startCursor": 0, + "hasPreviousPage": False, + "hasNextPage": False, + "endCursor": 2 + } } } }) -- GitLab