diff --git a/src/Api/ApigeeX/Controller/PaginationHelperTrait.php b/src/Api/ApigeeX/Controller/PaginationHelperTrait.php index 4afe9b09..fcc860a7 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 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); @@ -113,8 +113,14 @@ protected function listEntities(PagerInterface $pager = null, array $query_param 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, // etc. $responseArray = reset($responseArray); @@ -123,30 +129,26 @@ 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($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, + // 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 +157,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 PagerInterface $pager * limit object with configured pageToken and limit. * @param array $query_params * Query parameters for the API call. 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" + } + ] +}