Skip to content

Commit

Permalink
Merge pull request #2 from spinen/feature/builderForScheduledTasks
Browse files Browse the repository at this point in the history
builder for scheduled tasks
  • Loading branch information
jimmypuckett authored Dec 13, 2023
2 parents 1ed2f18 + c4492c0 commit a4e1dec
Show file tree
Hide file tree
Showing 10 changed files with 307 additions and 78 deletions.
67 changes: 47 additions & 20 deletions src/Api/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

namespace Spinen\Ncentral\Api;

use Exception;
use GuzzleHttp\Client as Guzzle;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Str;
use RuntimeException;
use Spinen\Ncentral\Exceptions\ApiException;
use Spinen\Ncentral\Exceptions\ClientConfigurationException;
use Spinen\Ncentral\Exceptions\TokenException;
use Spinen\Version\Version;

/**
Expand All @@ -31,8 +33,9 @@ public function __construct(
/**
* Shortcut to 'DELETE' request
*
* @throws ApiException
* @throws GuzzleException
* @throws TokenException
* @throws RuntimeException
*/
// TODO: Enable this once they add endpoints that support delete
// public function delete(string $path): ?array
Expand All @@ -43,8 +46,9 @@ public function __construct(
/**
* Shortcut to 'GET' request
*
* @throws ApiException
* @throws GuzzleException
* @throws TokenException
* @throws RuntimeException
*/
public function get(string $path): ?array
{
Expand All @@ -54,6 +58,7 @@ public function get(string $path): ?array
/**
* Get, return, or refresh the token
*
* @throws ApiException
* @throws GuzzleException
* @throws RuntimeException
*/
Expand All @@ -72,11 +77,38 @@ public function getVersion()
return new Version(__DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'VERSION');
}

/**
* Process exception
*
* @throws ApiException
* @throws GuzzleException
* @throws RuntimeException
*/
protected function processException(GuzzleException $e): void
{
if (! is_a($e, RequestException::class)) {
throw $e;
}

/** @var RequestException $e */
$body = $e->getResponse()->getBody()->getContents();

$results = json_decode($body, true);

throw new ApiException(
body: $body,
code: $results['status'],
message: $results['message'],
previous: $e,
);
}

/**
* Shortcut to 'POST' request
*
* @throws ApiException
* @throws GuzzleException
* @throws TokenException
* @throws RuntimeException
*/
public function post(string $path, array $data): ?array
{
Expand All @@ -86,8 +118,9 @@ public function post(string $path, array $data): ?array
/**
* Shortcut to 'PUT' request
*
* @throws ApiException
* @throws GuzzleException
* @throws TokenException
* @throws RuntimeException
*/
// TODO: Enable this once they add endpoints that support put
// public function put(string $path, array $data): ?array
Expand All @@ -98,8 +131,9 @@ public function post(string $path, array $data): ?array
/**
* Make an API call to Ncentral
*
* @throws ApiException
* @throws GuzzleException
* @throws TokenException
* @throws RuntimeException
*/
public function request(?string $path, ?array $data = [], ?string $method = 'GET'): ?array
{
Expand All @@ -115,18 +149,15 @@ public function request(?string $path, ?array $data = [], ?string $method = 'GET
'Content-Type' => 'application/json',
'User-Agent' => 'SPINEN/'.$this->getVersion(),
],
// 'body' => empty($data) ? null : json_encode($data),
'body' => empty($data) ? null : json_encode($data),
],
uri: $this->uri($path),
)
->getBody()
->getContents(),
);
} catch (GuzzleException $e) {
// TODO: Figure out what to do with this error
// TODO: Consider returning [] for 401's?
throw $e;
$this->processException($e);
}
}

Expand All @@ -135,6 +166,7 @@ public function request(?string $path, ?array $data = [], ?string $method = 'GET
/**
* Refresh a token
*
* @throws ApiException
* @throws GuzzleException
* @throws RuntimeException
*/
Expand Down Expand Up @@ -165,16 +197,14 @@ public function refreshToken(): Token

return $this->token;
} catch (GuzzleException $e) {
// TODO: Figure out what to do with this error
// TODO: Consider returning [] for 401's?
throw $e;
$this->processException($e);
}
}

/**
* Request a token
*
* @throws ApiException
* @throws GuzzleException
* @throws RuntimeException
*/
Expand Down Expand Up @@ -204,10 +234,7 @@ public function requestToken(): Token

return $this->token;
} catch (GuzzleException $e) {
// TODO: Figure out what to do with this error
// TODO: Consider returning [] for 401's?
throw $e;
$this->processException($e);
}
}

Expand Down Expand Up @@ -287,7 +314,7 @@ public function setToken(Token|string $token): self
* in the configs, but if a url is passed in as a second parameter then it is used.
* If no url is found it will use the hard-coded v2 Ncentral API URL.
*/
public function uri(string $path = null, string $url = null): string
public function uri(?string $path = null, ?string $url = null): string
{
if ($path && Str::startsWith($path, 'http')) {
return $path;
Expand Down
50 changes: 50 additions & 0 deletions src/DetailedScheduledTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Spinen\Ncentral;

use Spinen\Ncentral\Support\Model;

/**
* Class DetailedScheduledTask
*
* @property int $deviceId
* @property int $taskId
* @property string $deviceName
* @property string $message
* @property string $output
* @property string $outputFileName
* @property string $status
* @property string $taskName
*/
class DetailedScheduledTask extends Model
{
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'deviceId' => 'int',
'taskId' => 'int',
];

/**
* Path to API endpoint.
*/
protected string $extra = '/status/details';

/**
* Path to API endpoint.
*/
protected string $path = '/scheduled-tasks';

/**
* The primary key for the model.
*/
protected string $primaryKey = 'taskId';

/**
* Is the model readonly?
*/
protected bool $readonlyModel = true;
}
29 changes: 29 additions & 0 deletions src/Exceptions/ApiException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Spinen\Ncentral\Exceptions;

use RuntimeException;
use Throwable;

class ApiException extends RuntimeException
{
protected string $body;

protected int $status;

public function __construct(
string $message,
int $code,
?Throwable $previous = null,
?string $body = null,
) {
parent::__construct(message: $message, code: $code, previous: $previous);

$this->body = $body;
}

public function getBody(): string
{
return $this->body;
}
}
9 changes: 0 additions & 9 deletions src/Exceptions/TokenException.php

This file was deleted.

75 changes: 73 additions & 2 deletions src/ScheduledTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,95 @@

namespace Spinen\Ncentral;

use Spinen\Ncentral\Exceptions\NoClientException;
use Spinen\Ncentral\Support\Builder;
use Spinen\Ncentral\Support\Model;

/**
* Class ScheduledTask
*
* @property
* @property ?array $deviceIds
* @property ?bool $isEnabled
* @property ?bool $isReactive
* @property ?int $applianceId
* @property ?int $customerId
* @property ?int $deviceId
* @property ?int $itemId
* @property ?int $parentId
* @property ?string $name
* @property ?string $type
* @property int $taskId
*/
class ScheduledTask extends Model
{
/**
* The model's attributes.
*
* @var array
*/
protected $attributes = [
// TODO: Should we set these defaults?
'credential' => [
'type' => 'LocalSystem',
'username' => null,
'password' => null,
],
'taskType' => 'AutomationPolicy',
];

/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [];
protected $casts = [
'applianceId' => 'int',
'customerId' => 'int',
'deviceId' => 'int',
'isEnabled' => 'bool',
'isReactive' => 'bool',
'itemId' => 'int',
'parentId' => 'int',
'taskId' => 'int',
];

/**
* Path to API endpoint.
*/
protected string $path = '/scheduled-tasks';

/**
* The primary key for the model.
*/
protected string $primaryKey = 'taskId';

/**
* Accessor to get the details
*
* @throws NoClientException
*/
public function getDetailsAttribute(): DetailedScheduledTask
{
return (new Builder())->setClient($this->getClient())
->detailedScheduledTasks()
->find($this->taskId);
}

/**
* Any thing to add to the end of the path
*/
public function getExtra(): ?string
{
// N-able has create route different than get route
return $this->taskId ? null : '/direct';
}

/**
* Does the model allow updates?
*/
public function getReadonlyModel(): bool
{
// Toggle readonly for existing as you cannot update
return $this->exists;
}
}
Loading

0 comments on commit a4e1dec

Please sign in to comment.