diff --git a/README.md b/README.md index 5886086..cc7b8a7 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,13 @@ while ($job && !$job->completed()) { Here's a list of Hypernode API features implemented in the client. +- Listing Hypernodes related to your API key - Updating one or multiple Hypernode settings at once. - Querying/polling the logbook for the status of a job. -- Creating and cancelling Brancher Hypernode instances. +- Listing, creating and cancelling Brancher Hypernode instances. + +## Related projects + +- The official [Hypernode API Python Client](https://github.com/byteinternet/hypernode-api-python) +- The official [Hypernode Deploy](https://github.com/byteinternet/hypernode-deploy-configuration) tool +- The official [Hypernode Docker](https://github.com/byteinternet/hypernode-docker) image diff --git a/composer.json b/composer.json index 9a0ef24..ff00b0a 100644 --- a/composer.json +++ b/composer.json @@ -19,6 +19,7 @@ } ], "require": { + "composer-runtime-api": "^2.0", "ext-curl": "*", "ext-json": "*", "nesbot/carbon": "^2.0", diff --git a/src/HypernodeClient.php b/src/HypernodeClient.php index 629cb56..0774f76 100644 --- a/src/HypernodeClient.php +++ b/src/HypernodeClient.php @@ -15,8 +15,6 @@ class HypernodeClient { - public const VERSION = '0.1.0'; - public HttpMethodsClientInterface $api; public App $app; public BrancherApp $brancherApp; diff --git a/src/HypernodeClientFactory.php b/src/HypernodeClientFactory.php index dfda8ca..e25be4b 100644 --- a/src/HypernodeClientFactory.php +++ b/src/HypernodeClientFactory.php @@ -4,6 +4,7 @@ namespace Hypernode\Api; +use Composer\InstalledVersions; use Http\Client\Common\HttpMethodsClient; use Http\Client\Common\Plugin\AddHostPlugin; use Http\Client\Common\Plugin\AddPathPlugin; @@ -21,7 +22,10 @@ public static function create(string $authToken, ?ClientInterface $httpClient = { $httpHeaders = [ 'Authorization' => sprintf('Token %s', $authToken), - 'User-Agent' => sprintf('Hypernode API PHP Client v%s', HypernodeClient::VERSION), + 'User-Agent' => sprintf( + 'Hypernode API PHP Client v%s', + InstalledVersions::getVersion('hypernode/api-client'), + ), 'Accept' => 'application/json', 'Content-Type' => 'application/json', ]; diff --git a/src/Service/App.php b/src/Service/App.php index ad34de8..29dedfe 100644 --- a/src/Service/App.php +++ b/src/Service/App.php @@ -9,7 +9,7 @@ class App extends AbstractService public const V2_APP_LIST_URL = "/v2/app/"; public const V2_APP_DETAIL_URL = "/v2/app/%s/"; public const V2_APP_CANCEL_URL = "/v2/app/%s/cancel/"; - public const V2_APP_BRANCHER_URL = "/v2/app/%s/brancher/"; + public const V2_BRANCHER_APP_URL = "/v2/brancher/app/%s/"; public const V1_APP_FLOWS_URL = "/logbook/v1/logbooks/%s/flows/"; /** diff --git a/src/Service/BrancherApp.php b/src/Service/BrancherApp.php index 94a238e..aca7489 100644 --- a/src/Service/BrancherApp.php +++ b/src/Service/BrancherApp.php @@ -9,6 +9,28 @@ class BrancherApp extends AbstractService { + /** + * List all brancher nodes for given parent app. + * + * @param string $app Name of the parent app + * @param array|null $data Extra data to be provided + * @return array Array containing brancher nodes + * @throws HypernodeApiClientException + * @throws HypernodeApiServerException + */ + public function list(string $app, ?array $data = null): array + { + $url = sprintf(App::V2_BRANCHER_APP_URL, $app); + + $response = $this->client->api->get($url, [], $data ? json_encode($data) : null); + + $this->client->maybeThrowApiExceptions($response); + + $data = $this->client->getJsonFromResponse($response); + + return $data['branchers']; + } + /** * Create a brancher app for given parent app. * @@ -20,7 +42,7 @@ class BrancherApp extends AbstractService */ public function create(string $app, ?array $data = null): string { - $url = sprintf(App::V2_APP_BRANCHER_URL, $app); + $url = sprintf(App::V2_BRANCHER_APP_URL, $app); $response = $this->client->api->post($url, [], $data ? json_encode($data) : null); diff --git a/tests/unit/Service/BrancherAppTest.php b/tests/unit/Service/BrancherAppTest.php index 36d9461..80f55c8 100644 --- a/tests/unit/Service/BrancherAppTest.php +++ b/tests/unit/Service/BrancherAppTest.php @@ -11,6 +11,49 @@ class BrancherAppTest extends HypernodeClientTestCase { + public function testListBrancherApp() + { + $this->responses->append( + new Response(200, [], json_encode([ + 'name' => 'johndoe-eph123456', + 'parent' => 'johndoe', + 'type' => 'brancher', + 'branchers' => [] + ])), + ); + + $branchers = $this->client->brancherApp->list('johndoe'); + + $request = $this->responses->getLastRequest(); + $this->assertEquals('GET', $request->getMethod()); + $this->assertEquals('/v2/brancher/app/johndoe/', $request->getUri()); + $this->assertEquals([], $branchers); + } + + public function testListBrancherAppRaisesClientExceptions() + { + $badRequestResponse = new Response(400, [], json_encode([ + 'non_field_errors' => ['Your request was invalid.'] + ])); + $this->responses->append($badRequestResponse); + + $this->expectExceptionObject(new HypernodeApiClientException($badRequestResponse)); + + $this->client->brancherApp->list('johndoe'); + } + + public function testListBrancherAppRaisesServerExceptions() + { + $badRequestResponse = new Response(500, [], json_encode([ + 'non_field_errors' => ['Something went wrong processing your request.'] + ])); + $this->responses->append($badRequestResponse); + + $this->expectExceptionObject(new HypernodeApiServerException($badRequestResponse)); + + $this->client->brancherApp->list('johndoe'); + } + public function testCreateBrancherApp() { $this->responses->append( @@ -25,7 +68,7 @@ public function testCreateBrancherApp() $request = $this->responses->getLastRequest(); $this->assertEquals('POST', $request->getMethod()); - $this->assertEquals('/v2/app/johndoe/brancher/', $request->getUri()); + $this->assertEquals('/v2/brancher/app/johndoe/', $request->getUri()); $this->assertEquals('johndoe-eph123456', $brancherAppName); } @@ -46,7 +89,7 @@ public function testCreateBrancherAppWithData() $request = $this->responses->getLastRequest(); $this->assertEquals('POST', $request->getMethod()); - $this->assertEquals('/v2/app/johndoe/brancher/', $request->getUri()); + $this->assertEquals('/v2/brancher/app/johndoe/', $request->getUri()); $this->assertEquals('johndoe-eph123456', $brancherAppName); $this->assertJson((string)$request->getBody()); $this->assertEquals(