From 59e935401ad9ef629d70c256033173b842f70df4 Mon Sep 17 00:00:00 2001 From: Shishir Suvarna Date: Mon, 29 Jan 2024 19:21:12 +0530 Subject: [PATCH 1/5] Retrieving the next list items based on nextpagetoken flag --- .../Controller/PaginationHelperTrait.php | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/Api/ApigeeX/Controller/PaginationHelperTrait.php b/src/Api/ApigeeX/Controller/PaginationHelperTrait.php index 4afe9b09..eb14b351 100644 --- a/src/Api/ApigeeX/Controller/PaginationHelperTrait.php +++ b/src/Api/ApigeeX/Controller/PaginationHelperTrait.php @@ -25,7 +25,7 @@ /** * Utility methods for those controllers that supports paginated listing. * - * @see \Apigee\Edge\Api\ApigeeX\Controller\PaginatedEntityListingControllerInterface + * @see \PaginatedEntityListingControllerInterface */ trait PaginationHelperTrait { @@ -35,7 +35,7 @@ trait PaginationHelperTrait /** * {@inheritdoc} */ - public function createPager(int $limit = 0, string $pageToken = null): PagerInterface + public function createPager(int $limit = 0, ?string $pageToken = null): PagerInterface { // Create an anonymous class here because this class should not exist and be in use // in those controllers that do not work with entities that belongs to an organization. @@ -90,7 +90,7 @@ public function setLimit(int $limit): int /** * Loads paginated list of entities from Apigee X. * - * @param \Apigee\Edge\Api\ApigeeX\Structure\PagerInterface|null $pager + * @param \Structure\PagerInterface|null $pager * Pager. * @param array $query_params * Additional query parameters. @@ -103,7 +103,7 @@ public function setLimit(int $limit): int * @psalm-suppress PossiblyNullArrayOffset $tmp->id() is always not null here. * @psalm-suppress PossiblyFalseArgument $tmp not be false. */ - protected function listEntities(PagerInterface $pager = null, array $query_params = [], string $key_provider = 'id'): array + protected function listEntities(?PagerInterface $pager = null, array $query_params = [], string $key_provider = 'id'): array { if ($pager) { $responseArray = $this->getResultsInRange($pager, $query_params); @@ -115,6 +115,8 @@ protected function listEntities(PagerInterface $pager = null, array $query_param } else { // Pass an empty pager to load all entities. $responseArray = $this->getResultsInRange($this->createPager(), $query_params); + // Check flag 'nextPageToken' to get next items from the list. + $nextPageToken = array_key_exists('nextPageToken', $responseArray) ? $responseArray['nextPageToken'] : false; // Ignore entity type key from response, ex.: developer, apiproduct, // etc. $responseArray = reset($responseArray); @@ -123,30 +125,25 @@ protected function listEntities(PagerInterface $pager = null, array $query_param return []; } $entities = $this->responseArrayToArrayOfEntities($responseArray, $key_provider); - $lastEntity = end($entities); - $lastId = $lastEntity->{$key_provider}(); - do { - $tmp = $this->getResultsInRange($this->createPager(0, $lastId), $query_params); - // Ignore entity type key from response, ex.: developer, - // apiproduct, etc. - $tmp = reset($tmp); - // Remove the first item from the list because it is the same - // as the last item of $entities at this moment. - // Apigee X response always starts with the requested entity - // (pageToken). - array_shift($tmp); - $tmpEntities = $this->responseArrayToArrayOfEntities($tmp, $key_provider); - - if (count($tmpEntities) > 0) { + if ($nextPageToken) { + do { + $tmp = $this->getResultsInRange($this->createPager(0, $nextPageToken), $query_params); + // Check the flag 'nextPageToken' to get next items from the list. + $nextPageToken = array_key_exists('nextPageToken', $tmp) ? $tmp['nextPageToken'] : false; + // Ignore entity type key from response, ex.: developer, + // apiproduct, etc. + $tmp = reset($tmp); + // Remove the first item from the list because it is the same + // as the last item of $entities at this moment. + // Apigee X response always starts with the requested entity + // (pageToken). + array_shift($tmp); + $tmpEntities = $this->responseArrayToArrayOfEntities($tmp, $key_provider); // The returned entity array is keyed by entity id which // is unique so we can do this. $entities += $tmpEntities; - $lastEntity = end($tmpEntities); - $lastId = $lastEntity->{$key_provider}(); - } else { - $lastId = false; - } - } while ($lastId); + } while ($nextPageToken); + } return $entities; } @@ -155,7 +152,7 @@ protected function listEntities(PagerInterface $pager = null, array $query_param /** * Gets entities and entity ids in a provided range from Apigee X. * - * @param \Apigee\Edge\Api\ApigeeX\Structure\PagerInterface $pager + * @param \Structure\PagerInterface $pager * limit object with configured pageToken and limit. * @param array $query_params * Query parameters for the API call. From 9ab2de31d91b78ed8f2e0710b31494d2e1936bc4 Mon Sep 17 00:00:00 2001 From: Shishir Suvarna Date: Mon, 29 Jan 2024 19:28:14 +0530 Subject: [PATCH 2/5] Retrieving the next list items based on nextpagetoken flag --- src/Api/ApigeeX/Controller/PaginationHelperTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Api/ApigeeX/Controller/PaginationHelperTrait.php b/src/Api/ApigeeX/Controller/PaginationHelperTrait.php index eb14b351..f0c3075a 100644 --- a/src/Api/ApigeeX/Controller/PaginationHelperTrait.php +++ b/src/Api/ApigeeX/Controller/PaginationHelperTrait.php @@ -90,7 +90,7 @@ public function setLimit(int $limit): int /** * Loads paginated list of entities from Apigee X. * - * @param \Structure\PagerInterface|null $pager + * @param \Apigee\Edge\Api\ApigeeX\Structure\PagerInterface|null $pager * Pager. * @param array $query_params * Additional query parameters. From 29d693caa7de1302ab8aeeb6a71498319fc176fa Mon Sep 17 00:00:00 2001 From: Shishir Suvarna Date: Mon, 29 Jan 2024 19:30:33 +0530 Subject: [PATCH 3/5] PHPCS fix --- src/Api/ApigeeX/Controller/PaginationHelperTrait.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Api/ApigeeX/Controller/PaginationHelperTrait.php b/src/Api/ApigeeX/Controller/PaginationHelperTrait.php index f0c3075a..dbaf24cf 100644 --- a/src/Api/ApigeeX/Controller/PaginationHelperTrait.php +++ b/src/Api/ApigeeX/Controller/PaginationHelperTrait.php @@ -90,7 +90,7 @@ public function setLimit(int $limit): int /** * Loads paginated list of entities from Apigee X. * - * @param \Apigee\Edge\Api\ApigeeX\Structure\PagerInterface|null $pager + * @param PagerInterface|null $pager * Pager. * @param array $query_params * Additional query parameters. @@ -152,7 +152,7 @@ protected function listEntities(?PagerInterface $pager = null, array $query_para /** * Gets entities and entity ids in a provided range from Apigee X. * - * @param \Structure\PagerInterface $pager + * @param PagerInterface $pager * limit object with configured pageToken and limit. * @param array $query_params * Query parameters for the API call. From 688bc04a6342f1b4018f99991531309a0eef467a Mon Sep 17 00:00:00 2001 From: Shishir Suvarna Date: Wed, 7 Feb 2024 11:12:07 +0530 Subject: [PATCH 4/5] Fix AppGroups App pagination issue --- src/Api/ApigeeX/Controller/PaginationHelperTrait.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Api/ApigeeX/Controller/PaginationHelperTrait.php b/src/Api/ApigeeX/Controller/PaginationHelperTrait.php index dbaf24cf..fcc860a7 100644 --- a/src/Api/ApigeeX/Controller/PaginationHelperTrait.php +++ b/src/Api/ApigeeX/Controller/PaginationHelperTrait.php @@ -113,8 +113,12 @@ protected function listEntities(?PagerInterface $pager = null, array $query_para return $this->responseArrayToArrayOfEntities($responseArray, $key_provider); } else { + // Default page size set to 1000, because the AppGroupApps endpoint + // does not return nextPageToken unless a pageSize is specified + // in the request parameters. + $pageSize = 1000; // Pass an empty pager to load all entities. - $responseArray = $this->getResultsInRange($this->createPager(), $query_params); + $responseArray = $this->getResultsInRange($this->createPager($pageSize), $query_params); // Check flag 'nextPageToken' to get next items from the list. $nextPageToken = array_key_exists('nextPageToken', $responseArray) ? $responseArray['nextPageToken'] : false; // Ignore entity type key from response, ex.: developer, apiproduct, @@ -125,9 +129,10 @@ protected function listEntities(?PagerInterface $pager = null, array $query_para return []; } $entities = $this->responseArrayToArrayOfEntities($responseArray, $key_provider); + if ($nextPageToken) { do { - $tmp = $this->getResultsInRange($this->createPager(0, $nextPageToken), $query_params); + $tmp = $this->getResultsInRange($this->createPager($pageSize, $nextPageToken), $query_params); // Check the flag 'nextPageToken' to get next items from the list. $nextPageToken = array_key_exists('nextPageToken', $tmp) ? $tmp['nextPageToken'] : false; // Ignore entity type key from response, ex.: developer, From dfa2bf03b9d8f70a97c220be8049acf9037f6d64 Mon Sep 17 00:00:00 2001 From: Shishir Suvarna Date: Wed, 7 Feb 2024 11:31:10 +0530 Subject: [PATCH 5/5] Fix AppGroup apps pagination issue and testcase --- .../phpunit/appgroups/GET_pageSize=1000.json | 69 ++++++ .../phpunit/apps/GET_pageSize=1000.json | 206 ++++++++++++++++++ 2 files changed, 275 insertions(+) create mode 100644 tests/offline-test-data/v1/organizations/phpunit/appgroups/GET_pageSize=1000.json create mode 100644 tests/offline-test-data/v1/organizations/phpunit/appgroups/phpunit/apps/GET_pageSize=1000.json diff --git a/tests/offline-test-data/v1/organizations/phpunit/appgroups/GET_pageSize=1000.json b/tests/offline-test-data/v1/organizations/phpunit/appgroups/GET_pageSize=1000.json new file mode 100644 index 00000000..5085a7b2 --- /dev/null +++ b/tests/offline-test-data/v1/organizations/phpunit/appgroups/GET_pageSize=1000.json @@ -0,0 +1,69 @@ +{ + "appGroups": [ + { + "name": "phpunit", + "displayName": "A PHPUnit appgroup", + "status": "active", + "attributes": [ + { + "name": "foo", + "value": "bar" + } + ], + "createdAt": 1691588699000, + "lastModifiedAt": 1691588699617 + }, + { + "name": "1phpunit", + "displayName": "A PHPUnit appgroup", + "status": "active", + "attributes": [ + { + "name": "foo", + "value": "bar" + } + ], + "createdAt": 1691588699000, + "lastModifiedAt": 1691588699617 + }, + { + "name": "2phpunit", + "displayName": "A PHPUnit appgroup", + "status": "active", + "attributes": [ + { + "name": "foo", + "value": "bar" + } + ], + "createdAt": 1691588699000, + "lastModifiedAt": 1691588699617 + }, + { + "name": "3phpunit", + "displayName": "A PHPUnit appgroup", + "status": "active", + "attributes": [ + { + "name": "foo", + "value": "bar" + } + ], + "createdAt": 1691588699000, + "lastModifiedAt": 1691588699617 + }, + { + "name": "4phpunit", + "displayName": "A PHPUnit appgroup", + "status": "active", + "attributes": [ + { + "name": "foo", + "value": "bar" + } + ], + "createdAt": 1691588699000, + "lastModifiedAt": 1691588699617 + } + ] +} diff --git a/tests/offline-test-data/v1/organizations/phpunit/appgroups/phpunit/apps/GET_pageSize=1000.json b/tests/offline-test-data/v1/organizations/phpunit/appgroups/phpunit/apps/GET_pageSize=1000.json new file mode 100644 index 00000000..e3c1950c --- /dev/null +++ b/tests/offline-test-data/v1/organizations/phpunit/appgroups/phpunit/apps/GET_pageSize=1000.json @@ -0,0 +1,206 @@ +{ + "app": [ + { + "appFamily": "default", + "appId": "a47891c5-ca20-4f2f-975e-0e7588ec81f0", + "attributes": [ + { + "name": "DisplayName", + "value": "PHP Unit: Test app" + }, + { + "name": "Notes", + "value": "This is a test app created by PHP Unit." + }, + { + "name": "foo", + "value": "foo" + }, + { + "name": "bar", + "value": "baz" + } + ], + "callbackUrl": "http://foo.example.com", + "createdAt": 648345600000, + "createdBy": "phpunit@example.com", + "credentials": [ + { + "apiProducts": [], + "attributes": [], + "consumerKey": "Zww6GKaGRxQFGkfE36vgSN0eoac1Ymk3", + "consumerSecret": "LtdYkcmgDYV7kzxz", + "issuedAt": 648345600000, + "scopes": [], + "status": "approved" + } + ], + "appGroup": "phpunit", + "lastModifiedAt": 648345600000, + "lastModifiedBy": "phpunit@example.com", + "name": "phpunit_test_app", + "scopes": [], + "status": "approved" + }, + { + "appFamily": "default", + "appId": "b3e71cbb-7eb5-1111-b384-ac82bca1d9dc", + "attributes": [ + { + "name": "DisplayName", + "value": "PHP Unit: Test app" + }, + { + "name": "Notes", + "value": "This is a test app created by PHP Unit." + }, + { + "name": "foo", + "value": "bar" + } + ], + "callbackUrl": "http://example.com", + "createdAt": 648345600000, + "createdBy": "phpunit@example.com", + "credentials": [ + { + "apiProducts": [], + "attributes": [], + "consumerKey": "Zww6GKaGRxQFGkfE36vgSN0eoac1Ymk3", + "consumerSecret": "LtdYkcmgDYV7kzxz", + "issuedAt": 648345600000, + "scopes": [], + "status": "approved" + } + ], + "appGroup": "phpunit", + "lastModifiedAt": 648345600000, + "lastModifiedBy": "phpunit@example.com", + "name": "1phpunit_test_app", + "scopes": [], + "status": "approved" + }, + { + "appFamily": "default", + "appId": "b3e71cbb-7eb5-2222-b384-ac82bca1d9dc", + "attributes": [ + { + "name": "DisplayName", + "value": "PHP Unit: Test app" + }, + { + "name": "Notes", + "value": "This is a test app created by PHP Unit." + }, + { + "name": "foo", + "value": "foo" + }, + { + "name": "bar", + "value": "baz" + } + ], + "callbackUrl": "http://example.com", + "createdAt": 648345600000, + "createdBy": "phpunit@example.com", + "credentials": [ + { + "apiProducts": [], + "attributes": [], + "consumerKey": "wAXAIiOr2oJOVGqFltnm3Jwr2LE0GEuY", + "consumerSecret": "S8YjnsjmdBqDAegR", + "issuedAt": 648345600000, + "scopes": [], + "status": "approved" + } + ], + "appGroup": "phpunit", + "lastModifiedAt": 648345600000, + "lastModifiedBy": "phpunit@example.com", + "name": "2phpunit_test_app", + "scopes": [], + "status": "approved" + }, + { + "appFamily": "default", + "appId": "b3e71cbb-7eb5-3333-b384-ac82bca1d9dc", + "attributes": [ + { + "name": "DisplayName", + "value": "PHP Unit: Test app" + }, + { + "name": "Notes", + "value": "This is a test app created by PHP Unit." + }, + { + "name": "foo", + "value": "bar" + } + ], + "callbackUrl": "http://example.com", + "createdAt": 648345600000, + "createdBy": "phpunit@example.com", + "credentials": [ + { + "apiProducts": [], + "attributes": [], + "consumerKey": "wAXAIiOr2oJOVGqFltnm3Jwr2LE0GEuY", + "consumerSecret": "S8YjnsjmdBqDAegR", + "issuedAt": 648345600000, + "scopes": [], + "status": "approved" + } + ], + "appGroup": "phpunit", + "lastModifiedAt": 648345600000, + "lastModifiedBy": "phpunit@example.com", + "name": "3phpunit_test_app", + "scopes": [], + "status": "approved" + }, + { + "appFamily": "default", + "appId": "b3e71cbb-7eb5-4444-b384-ac82bca1d9dc", + "attributes": [ + { + "name": "DisplayName", + "value": "PHP Unit: Test app" + }, + { + "name": "Notes", + "value": "This is a test app created by PHP Unit." + }, + { + "name": "foo", + "value": "foo" + }, + { + "name": "bar", + "value": "baz" + } + ], + "callbackUrl": "http://example.com", + "createdAt": 648345600000, + "createdBy": "phpunit@example.com", + "credentials": [ + { + "apiProducts": [], + "attributes": [], + "consumerKey": "wAXAIiOr2oJOVGqFltnm3Jwr2LE0GEuY", + "consumerSecret": "S8YjnsjmdBqDAegR", + "issuedAt": 648345600000, + "scopes": [], + "status": "approved" + } + ], + "appGroup": "phpunit", + "lastModifiedAt": 648345600000, + "lastModifiedBy": "phpunit@example.com", + "name": "4phpunit_test_app", + "scopes": [], + "status": "approved" + } + ] +}