Skip to content

Commit

Permalink
Merge pull request #20 from ByteInternet/fix_setting_job
Browse files Browse the repository at this point in the history
service/settings: Fix job polling mechanism
  • Loading branch information
tdgroot authored Apr 29, 2024
2 parents 2c7a821 + 9235483 commit 144a1cf
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 31 deletions.
9 changes: 9 additions & 0 deletions src/Defaults.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Hypernode\Api;

class Defaults {
const HYPERNODE_API_URL = 'https://api.hypernode.com/';
}
4 changes: 1 addition & 3 deletions src/HypernodeClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

class HypernodeClientFactory
{
public const HYPERNODE_API_URL = 'https://api.hypernode.com/';

public static function create(string $authToken, ?ClientInterface $httpClient = null): HypernodeClient
{
$httpHeaders = [
Expand All @@ -29,7 +27,7 @@ public static function create(string $authToken, ?ClientInterface $httpClient =
'Accept' => 'application/json',
'Content-Type' => 'application/json',
];
$httpClient = self::getHttpClient(self::HYPERNODE_API_URL, $httpHeaders, $httpClient);
$httpClient = self::getHttpClient(Defaults::HYPERNODE_API_URL, $httpHeaders, $httpClient);

$apiClient = new HttpMethodsClient(
$httpClient, Psr17FactoryDiscovery::findRequestFactory(), Psr17FactoryDiscovery::findStreamFactory()
Expand Down
58 changes: 42 additions & 16 deletions src/Resource/Logbook/Job.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Hypernode\Api\HypernodeClient;
use Hypernode\Api\Resource\AbstractResource;
use Hypernode\Api\Service\App;

/**
* @property-read string $result
Expand All @@ -15,17 +16,19 @@
*/
class Job extends AbstractResource
{
private string $url;
private string $id;
private string $appName;
private bool $exists = false;
private bool $running = false;
private bool $success = false;
private bool $complete = false;

protected HypernodeClient $client;

public function __construct(HypernodeClient $client, string $urlOrId, array $data = [])
public function __construct(HypernodeClient $client, string $appName, string $id, array $data = [])
{
$this->client = $client;
$this->url = $urlOrId;
$this->appName = $appName;
$this->id = $id;
$this->data = $data;
}

Expand All @@ -37,37 +40,60 @@ public function __construct(HypernodeClient $client, string $urlOrId, array $dat
*/
public function refresh()
{
$response = $this->client->api->get($this->url);
$url = sprintf(App::V1_APP_FLOWS_URL, $this->appName) . '?' . http_build_query(['tracker_uuid' => $this->id]);
$response = $this->client->api->get($url);
$this->data = $this->client->getJsonFromResponse($response);

if ($response->getStatusCode() === 404) {
if ($response->getStatusCode() === 404 || $this->data['count'] === 0) {
$this->data = [];
$this->exists = false;
$this->running = false;
return;
}

if ($response->getStatusCode() === 303) {
$this->data = [];
$this->exists = true;
$this->running = false;
$this->complete = true;
return;
$this->exists = true;

$result = $this->data['results'][0];
switch ($result['state']) {
case 'running':
$this->running = true;
break;
case 'success':
$this->success = true;
$this->running = false;
$this->complete = true;
break;
case 'reverted':
$this->running = false;
$this->complete = true;
break;
}

$this->client->maybeThrowApiExceptions($response);
}

$this->data = $this->client->getJsonFromResponse($response);
$this->exists = true;
$this->running = true;
public function id()
{
return $this->id;
}

public function exists(): bool
{
return $this->exists;
}

public function running(): bool
{
return $this->running;
}

public function completed(): bool
{
return $this->complete;
}
}

public function success(): bool
{
return $this->success;
}
}
9 changes: 8 additions & 1 deletion src/Service/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

namespace Hypernode\Api\Service;

use Hypernode\Api\Defaults;
use Hypernode\Api\Resource\Logbook\Job;

class Settings extends AbstractService
{
public const JOB_URL_REGEX = '#' . Defaults::HYPERNODE_API_URL. 'logbook/v1/jobs/(.*)/#';

public function set(string $app, string $key, string $value): ?Job
{
return $this->setBatch($app, [$key => $value]);
Expand All @@ -21,7 +24,11 @@ public function setBatch(string $app, array $settings): ?Job
$this->client->maybeThrowApiExceptions($response);

if ($response->getStatusCode() === 202) {
$job = new Job($this->client, $response->getHeaderLine('Location'));
$location = $response->getHeaderLine('Location');
if (!preg_match(self::JOB_URL_REGEX, $location, $matches)) {
return null;
}
$job = new Job($this->client, $app, $matches[1]);
return $job;
}

Expand Down
101 changes: 92 additions & 9 deletions tests/unit/Resource/Logbook/JobTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ class JobTest extends HypernodeClientTestCase
protected function setUp(): void
{
parent::setUp();
$this->jobUrl = "https://api.hypernode.com/logbook/v1/jobs/abcd/";
$this->job = new Job($this->client, $this->jobUrl);
$this->job = new Job($this->client, 'johndoe', 'abcd');
}

public function testIsInstanceOfAbstractResource()
Expand All @@ -29,17 +28,100 @@ public function testRefresh()
{
$this->responses->append(
new Response(404, [], json_encode([])),
new Response(200, [], json_encode(['count' => 0, 'results' => []])),
new Response(200, [], json_encode([
'result' => 'pending',
'flow_name' => 'update_node',
'app_name' => 'johndoe'
'count' => 1,
'results' => [
[
'uuid' => 'abcd',
'state' => NULL,
'name' => 'update_node'
]
]
])),
new Response(200, [], json_encode([
'result' => 'running',
'flow_name' => 'update_node',
'app_name' => 'johndoe'
'count' => 1,
'results' => [
[
'uuid' => 'abcd',
'state' => 'running',
'name' => 'update_node'
]
]
])),
new Response(200, [], json_encode([
'count' => 1,
'results' => [
[
'uuid' => 'abcd',
'state' => 'success',
'name' => 'update_node'
]
]
])),
);

$this->job->refresh();

$this->assertFalse($this->job->exists());
$this->assertFalse($this->job->completed());

$this->job->refresh();

$this->assertFalse($this->job->exists());
$this->assertFalse($this->job->completed());

$this->job->refresh();

$this->assertTrue($this->job->exists());
$this->assertFalse($this->job->completed());

$this->job->refresh();

$this->assertTrue($this->job->exists());
$this->assertFalse($this->job->completed());

$this->job->refresh();

$this->assertTrue($this->job->exists());
$this->assertTrue($this->job->completed());
$this->assertTrue($this->job->success());
}

public function testRefreshFailedJob()
{
$this->responses->append(
new Response(404, [], json_encode([])),
new Response(200, [], json_encode([
'count' => 1,
'results' => [
[
'uuid' => 'abcd',
'state' => NULL,
'name' => 'update_node'
]
]
])),
new Response(200, [], json_encode([
'count' => 1,
'results' => [
[
'uuid' => 'abcd',
'state' => 'running',
'name' => 'update_node'
]
]
])),
new Response(200, [], json_encode([
'count' => 1,
'results' => [
[
'uuid' => 'abcd',
'state' => 'reverted',
'name' => 'update_node'
]
]
])),
new Response(303, [], json_encode([])),
);

$this->job->refresh();
Expand All @@ -61,6 +143,7 @@ public function testRefresh()

$this->assertTrue($this->job->exists());
$this->assertTrue($this->job->completed());
$this->assertFalse($this->job->success());
}

public function testExistsReturnsFalseByDefault()
Expand Down
6 changes: 4 additions & 2 deletions tests/unit/Service/SettingsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ public function testSetSingleSettingToDifferentValue()
{
$jobUrl = 'https://api.hypernode.com/logbook/v1/jobs/abcd/';
$this->responses->append(
new Response(202, ['Location: ' . $jobUrl], null),
new Response(202, ['Location' => $jobUrl], null),
);

$job = $this->client->settings->set('johndoe', 'php_version', '8.1');

$request = $this->responses->getLastRequest();

$this->assertNotNull($job);
$this->assertEquals('abcd', $job->id());
$this->assertEquals('PATCH', $request->getMethod());
$this->assertEquals('/v2/app/johndoe/', $request->getUri());
$this->assertJson((string)$request->getBody());
Expand All @@ -54,7 +55,7 @@ public function testSetMultipleSettings()
{
$jobUrl = 'https://api.hypernode.com/logbook/v1/jobs/abcd/';
$this->responses->append(
new Response(202, ['Location: ' . $jobUrl], null),
new Response(202, ['Location' => $jobUrl], null),
);

$job = $this->client->settings->setBatch(
Expand All @@ -68,6 +69,7 @@ public function testSetMultipleSettings()
$request = $this->responses->getLastRequest();

$this->assertNotNull($job);
$this->assertEquals('abcd', $job->id());
$this->assertEquals('PATCH', $request->getMethod());
$this->assertEquals('/v2/app/johndoe/', $request->getUri());
$this->assertJson((string)$request->getBody());
Expand Down

0 comments on commit 144a1cf

Please sign in to comment.