From f50069add6c43fcb101ac22a0575a21b3241dc6d Mon Sep 17 00:00:00 2001 From: David Jardin Date: Sat, 16 Nov 2024 11:24:27 +0100 Subject: [PATCH 1/9] Added site health check job --- .../Commands/PerformSiteHealthCheck.php | 34 +++ app/{Http => }/Controllers/Controller.php | 2 +- app/Enum/HttpMethod.php | 13 ++ .../Middleware/HorizonBasicAuthMiddleware.php | 36 +++ app/Jobs/CheckSiteHealth.php | 48 ++++ app/Jobs/UpdateSite.php | 27 +++ app/Models/Site.php | 84 ++++++- app/Models/User.php | 32 --- app/Providers/HorizonServiceProvider.php | 22 ++ bootstrap/app.php | 4 +- bootstrap/providers.php | 2 + config/auth.php | 9 - config/horizon.php | 218 ++++++++++++++++++ .../0001_01_01_000000_create_users_table.php | 49 ---- routes/console.php | 6 +- 15 files changed, 491 insertions(+), 95 deletions(-) create mode 100644 app/Console/Commands/PerformSiteHealthCheck.php rename app/{Http => }/Controllers/Controller.php (58%) create mode 100644 app/Enum/HttpMethod.php create mode 100644 app/Http/Middleware/HorizonBasicAuthMiddleware.php create mode 100644 app/Jobs/CheckSiteHealth.php create mode 100644 app/Jobs/UpdateSite.php delete mode 100644 app/Models/User.php create mode 100644 app/Providers/HorizonServiceProvider.php create mode 100644 config/horizon.php delete mode 100644 database/migrations/0001_01_01_000000_create_users_table.php diff --git a/app/Console/Commands/PerformSiteHealthCheck.php b/app/Console/Commands/PerformSiteHealthCheck.php new file mode 100644 index 0000000..f8c63ad --- /dev/null +++ b/app/Console/Commands/PerformSiteHealthCheck.php @@ -0,0 +1,34 @@ +input->getArgument('siteId')) + ); + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Controllers/Controller.php similarity index 58% rename from app/Http/Controllers/Controller.php rename to app/Controllers/Controller.php index 8677cd5..fd9e93d 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Controllers/Controller.php @@ -1,6 +1,6 @@ header('PHP_AUTH_USER', null) && $request->header('PHP_AUTH_PW', null)) { + $username = $request->header('PHP_AUTH_USER'); + $password = $request->header('PHP_AUTH_PW'); + + if ($username === config('horizon.basic_auth.username') + && $password === config('horizon.basic_auth.password')) { + $authenticationHasPassed = true; + } + } + + if ($authenticationHasPassed === false) { + return response()->make('Invalid credentials.', 401, ['WWW-Authenticate' => 'Basic']); + } + + return $next($request); + } +} diff --git a/app/Jobs/CheckSiteHealth.php b/app/Jobs/CheckSiteHealth.php new file mode 100644 index 0000000..ffe46f8 --- /dev/null +++ b/app/Jobs/CheckSiteHealth.php @@ -0,0 +1,48 @@ +site->performWebserviceRequest( + HttpMethod::GET, + 'health.json' + ); + + $healthData = collect($response); + + // Perform a sanity check + if (!$healthData->has('cms_version')) { + throw new \Exception("Invalid health response content"); + } + + // Write updated data to DB + $this->site->update($healthData->only([ + 'php_version', + 'db_type', + 'db_version', + 'cms_version', + 'server_os' + ])->toArray()); + } +} diff --git a/app/Jobs/UpdateSite.php b/app/Jobs/UpdateSite.php new file mode 100644 index 0000000..78a5790 --- /dev/null +++ b/app/Jobs/UpdateSite.php @@ -0,0 +1,27 @@ + 'bool' ]; } + + public function getUrlAttribute(string $value): string + { + return rtrim($value, "/") . "/"; + } + + + protected function performRequest( + RequestInterface $request, + array $options = [] + ): array { + /** @var Client $httpClient */ + $httpClient = App::make(Client::class); + + /** @var Response $response */ + $response = $httpClient->send( + $request, + $options + ); + + // Validate response + if (!json_validate((string) $response->getBody())) { + throw new RequestException( + "Invalid JSON body", + $request, + $response + ); + } + + // Return decoded body + return json_decode( + (string) $response->getBody(), + true, + 512, + JSON_THROW_ON_ERROR + ); + } + + public function performExtractionRequest(array $data, string $password): array + { + $request = new Request( + 'POST', + $this->url . 'extract.php' + ); + + $data['password'] = $password; + + return $this->performRequest( + $request, + [ + 'form_params' => $data, + 'timeout' => 300.0 + ] + ); + } + + public function performWebserviceRequest(HttpMethod $method, string $endpoint, array $data = []): array + { + $request = new Request( + $method->name, + $this->url . $endpoint, + [ + 'Authorization' => 'JUpdate-Token ' . $this->key + ] + ); + + return $this->performRequest( + $request, + [ + "json" => $data + ] + ); + } } diff --git a/app/Models/User.php b/app/Models/User.php deleted file mode 100644 index 802d005..0000000 --- a/app/Models/User.php +++ /dev/null @@ -1,32 +0,0 @@ - 'datetime', - 'password' => 'hashed', - ]; - } -} diff --git a/app/Providers/HorizonServiceProvider.php b/app/Providers/HorizonServiceProvider.php new file mode 100644 index 0000000..d98d242 --- /dev/null +++ b/app/Providers/HorizonServiceProvider.php @@ -0,0 +1,22 @@ +withMiddleware(function (Middleware $middleware) { - // + $middleware->alias([ + 'horizonBasicAuth' => \App\Http\Middleware\HorizonBasicAuthMiddleware::class + ]); }) ->withExceptions(function (Exceptions $exceptions) { // diff --git a/bootstrap/providers.php b/bootstrap/providers.php index 38b258d..0a3ca7b 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -2,4 +2,6 @@ return [ App\Providers\AppServiceProvider::class, + App\Providers\HorizonServiceProvider::class, + App\Providers\HttpclientServiceProvider::class, ]; diff --git a/config/auth.php b/config/auth.php index 0ba5d5d..353567c 100644 --- a/config/auth.php +++ b/config/auth.php @@ -60,15 +60,6 @@ */ 'providers' => [ - 'users' => [ - 'driver' => 'eloquent', - 'model' => env('AUTH_MODEL', App\Models\User::class), - ], - - // 'users' => [ - // 'driver' => 'database', - // 'table' => 'users', - // ], ], /* diff --git a/config/horizon.php b/config/horizon.php new file mode 100644 index 0000000..dfac10b --- /dev/null +++ b/config/horizon.php @@ -0,0 +1,218 @@ + null, + + /* + |-------------------------------------------------------------------------- + | Horizon Path + |-------------------------------------------------------------------------- + | + | This is the URI path where Horizon will be accessible from. Feel free + | to change this path to anything you like. Note that the URI will not + | affect the paths of its internal API that aren't exposed to users. + | + */ + + 'path' => env('HORIZON_PATH', 'horizon'), + + /* + |-------------------------------------------------------------------------- + | Horizon Redis Connection + |-------------------------------------------------------------------------- + | + | This is the name of the Redis connection where Horizon will store the + | meta information required for it to function. It includes the list + | of supervisors, failed jobs, job metrics, and other information. + | + */ + + 'use' => 'default', + + /* + |-------------------------------------------------------------------------- + | Horizon Redis Prefix + |-------------------------------------------------------------------------- + | + | This prefix will be used when storing all Horizon data in Redis. You + | may modify the prefix when you are running multiple installations + | of Horizon on the same server so that they don't have problems. + | + */ + + 'prefix' => env( + 'HORIZON_PREFIX', + Str::slug(env('APP_NAME', 'laravel'), '_').'_horizon:' + ), + + /* + |-------------------------------------------------------------------------- + | Horizon Route Middleware + |-------------------------------------------------------------------------- + | + | These middleware will get attached onto each Horizon route, giving you + | the chance to add your own middleware to this list or change any of + | the existing middleware. Or, you can simply stick with this list. + | + */ + + 'middleware' => ['web', 'horizonBasicAuth'], + + /* + |-------------------------------------------------------------------------- + | Queue Wait Time Thresholds + |-------------------------------------------------------------------------- + | + | This option allows you to configure when the LongWaitDetected event + | will be fired. Every connection / queue combination may have its + | own, unique threshold (in seconds) before this event is fired. + | + */ + + 'waits' => [ + 'redis:default' => 60, + ], + + /* + |-------------------------------------------------------------------------- + | Job Trimming Times + |-------------------------------------------------------------------------- + | + | Here you can configure for how long (in minutes) you desire Horizon to + | persist the recent and failed jobs. Typically, recent jobs are kept + | for one hour while all failed jobs are stored for an entire week. + | + */ + + 'trim' => [ + 'recent' => 60, + 'pending' => 60, + 'completed' => 60, + 'recent_failed' => 10080, + 'failed' => 10080, + 'monitored' => 10080, + ], + + /* + |-------------------------------------------------------------------------- + | Silenced Jobs + |-------------------------------------------------------------------------- + | + | Silencing a job will instruct Horizon to not place the job in the list + | of completed jobs within the Horizon dashboard. This setting may be + | used to fully remove any noisy jobs from the completed jobs list. + | + */ + + 'silenced' => [ + // App\Jobs\ExampleJob::class, + ], + + /* + |-------------------------------------------------------------------------- + | Metrics + |-------------------------------------------------------------------------- + | + | Here you can configure how many snapshots should be kept to display in + | the metrics graph. This will get used in combination with Horizon's + | `horizon:snapshot` schedule to define how long to retain metrics. + | + */ + + 'metrics' => [ + 'trim_snapshots' => [ + 'job' => 24, + 'queue' => 24, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Fast Termination + |-------------------------------------------------------------------------- + | + | When this option is enabled, Horizon's "terminate" command will not + | wait on all of the workers to terminate unless the --wait option + | is provided. Fast termination can shorten deployment delay by + | allowing a new instance of Horizon to start while the last + | instance will continue to terminate each of its workers. + | + */ + + 'fast_termination' => false, + + /* + |-------------------------------------------------------------------------- + | Memory Limit (MB) + |-------------------------------------------------------------------------- + | + | This value describes the maximum amount of memory the Horizon master + | supervisor may consume before it is terminated and restarted. For + | configuring these limits on your workers, see the next section. + | + */ + + 'memory_limit' => 64, + + /* + |-------------------------------------------------------------------------- + | Queue Worker Configuration + |-------------------------------------------------------------------------- + | + | Here you may define the queue worker settings used by your application + | in all environments. These supervisors and settings handle all your + | queued jobs and will be provisioned by Horizon during deployment. + | + */ + + 'defaults' => [ + 'supervisor-1' => [ + 'connection' => 'redis', + 'queue' => ['default'], + 'balance' => 'auto', + 'autoScalingStrategy' => 'time', + 'maxProcesses' => 1, + 'maxTime' => 0, + 'maxJobs' => 0, + 'memory' => 128, + 'tries' => 1, + 'timeout' => 60, + 'nice' => 0, + ], + ], + + 'environments' => [ + 'production' => [ + 'supervisor-1' => [ + 'maxProcesses' => 10, + 'balanceMaxShift' => 1, + 'balanceCooldown' => 3, + ], + ], + + 'local' => [ + 'supervisor-1' => [ + 'maxProcesses' => 3, + ], + ], + ], + + 'basic_auth' => [ + 'username' => env('HORIZON_BASIC_AUTH_USERNAME', 'joomla'), + 'password' => env('HORIZON_BASIC_AUTH_PASSWORD', 'updates') + ], +]; diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php deleted file mode 100644 index 05fb5d9..0000000 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ /dev/null @@ -1,49 +0,0 @@ -id(); - $table->string('name'); - $table->string('email')->unique(); - $table->timestamp('email_verified_at')->nullable(); - $table->string('password'); - $table->rememberToken(); - $table->timestamps(); - }); - - Schema::create('password_reset_tokens', function (Blueprint $table) { - $table->string('email')->primary(); - $table->string('token'); - $table->timestamp('created_at')->nullable(); - }); - - Schema::create('sessions', function (Blueprint $table) { - $table->string('id')->primary(); - $table->foreignId('user_id')->nullable()->index(); - $table->string('ip_address', 45)->nullable(); - $table->text('user_agent')->nullable(); - $table->longText('payload'); - $table->integer('last_activity')->index(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('users'); - Schema::dropIfExists('password_reset_tokens'); - Schema::dropIfExists('sessions'); - } -}; diff --git a/routes/console.php b/routes/console.php index 1612c78..ec6db2f 100644 --- a/routes/console.php +++ b/routes/console.php @@ -1,4 +1,6 @@ daily(); From acb0ba1b2b752883dfa92fef058322f651adcef4 Mon Sep 17 00:00:00 2001 From: David Jardin Date: Sat, 16 Nov 2024 11:27:09 +0100 Subject: [PATCH 2/9] Fix namespace --- app/Controllers/Controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Controllers/Controller.php b/app/Controllers/Controller.php index fd9e93d..8677cd5 100644 --- a/app/Controllers/Controller.php +++ b/app/Controllers/Controller.php @@ -1,6 +1,6 @@ Date: Sat, 16 Nov 2024 11:36:33 +0100 Subject: [PATCH 3/9] refactor service to separate class --- app/Jobs/CheckSiteHealth.php | 6 +- app/Models/Site.php | 83 ++----------------------- app/Services/SiteConnectionService.php | 85 ++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 79 deletions(-) create mode 100644 app/Services/SiteConnectionService.php diff --git a/app/Jobs/CheckSiteHealth.php b/app/Jobs/CheckSiteHealth.php index ffe46f8..bd31e2a 100644 --- a/app/Jobs/CheckSiteHealth.php +++ b/app/Jobs/CheckSiteHealth.php @@ -4,6 +4,7 @@ use App\Enum\HttpMethod; use App\Models\Site; +use App\Services\SiteConnectionService; use GuzzleHttp\Exception\RequestException; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; @@ -24,7 +25,10 @@ public function __construct(protected readonly Site $site) */ public function handle(): void { - $response = $this->site->performWebserviceRequest( + /** @var SiteConnectionService $connection */ + $connection = $this->site->connection; + + $response = $connection->performWebserviceRequest( HttpMethod::GET, 'health.json' ); diff --git a/app/Models/Site.php b/app/Models/Site.php index 398b611..5bc73ad 100644 --- a/app/Models/Site.php +++ b/app/Models/Site.php @@ -2,20 +2,10 @@ namespace App\Models; -use App\Enum\HttpMethod; -use App\Exceptions\RemotesiteCommunicationException; -use GuzzleHttp\Client; -use GuzzleHttp\Exception\RequestException; -use GuzzleHttp\Psr7\Request; -use GuzzleHttp\Psr7\Response; -use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Foundation\Auth\User as Authenticatable; -use Illuminate\Notifications\Notifiable; -use Illuminate\Support\Facades\App; -use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\ResponseInterface; +use App\Services\SiteConnectionService; +use Illuminate\Database\Eloquent\Model; -class Site extends Authenticatable +class Site extends Model { protected $fillable = [ 'url', @@ -49,71 +39,8 @@ public function getUrlAttribute(string $value): string return rtrim($value, "/") . "/"; } - - protected function performRequest( - RequestInterface $request, - array $options = [] - ): array { - /** @var Client $httpClient */ - $httpClient = App::make(Client::class); - - /** @var Response $response */ - $response = $httpClient->send( - $request, - $options - ); - - // Validate response - if (!json_validate((string) $response->getBody())) { - throw new RequestException( - "Invalid JSON body", - $request, - $response - ); - } - - // Return decoded body - return json_decode( - (string) $response->getBody(), - true, - 512, - JSON_THROW_ON_ERROR - ); - } - - public function performExtractionRequest(array $data, string $password): array + public function getConnectionAttribute(): SiteConnectionService { - $request = new Request( - 'POST', - $this->url . 'extract.php' - ); - - $data['password'] = $password; - - return $this->performRequest( - $request, - [ - 'form_params' => $data, - 'timeout' => 300.0 - ] - ); - } - - public function performWebserviceRequest(HttpMethod $method, string $endpoint, array $data = []): array - { - $request = new Request( - $method->name, - $this->url . $endpoint, - [ - 'Authorization' => 'JUpdate-Token ' . $this->key - ] - ); - - return $this->performRequest( - $request, - [ - "json" => $data - ] - ); + return new SiteConnectionService($this->url, $this->key); } } diff --git a/app/Services/SiteConnectionService.php b/app/Services/SiteConnectionService.php new file mode 100644 index 0000000..0ace319 --- /dev/null +++ b/app/Services/SiteConnectionService.php @@ -0,0 +1,85 @@ +send( + $request, + $options + ); + + // Validate response + if (!json_validate((string) $response->getBody())) { + throw new RequestException( + "Invalid JSON body", + $request, + $response + ); + } + + // Return decoded body + return json_decode( + (string) $response->getBody(), + true, + 512, + JSON_THROW_ON_ERROR + ); + } + + public function performExtractionRequest(array $data): array + { + $request = new Request( + 'POST', + $this->baseUrl . 'extract.php' + ); + + $data['password'] = $this->key; + + return $this->performRequest( + $request, + [ + 'form_params' => $data, + 'timeout' => 300.0 + ] + ); + } + + public function performWebserviceRequest(HttpMethod $method, string $endpoint, array $data = []): array + { + $request = new Request( + $method->name, + $this->baseUrl . $endpoint, + [ + 'Authorization' => 'JUpdate-Token ' . $this->key + ] + ); + + return $this->performRequest( + $request, + [ + "json" => $data + ] + ); + } +} From 3261de71bc2c3cb909ff712d5d9af1775d19de12 Mon Sep 17 00:00:00 2001 From: David Jardin Date: Sat, 16 Nov 2024 11:38:21 +0100 Subject: [PATCH 4/9] reformat code for clarity --- app/Jobs/CheckSiteHealth.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/Jobs/CheckSiteHealth.php b/app/Jobs/CheckSiteHealth.php index bd31e2a..fd13159 100644 --- a/app/Jobs/CheckSiteHealth.php +++ b/app/Jobs/CheckSiteHealth.php @@ -41,12 +41,14 @@ public function handle(): void } // Write updated data to DB - $this->site->update($healthData->only([ - 'php_version', - 'db_type', - 'db_version', - 'cms_version', - 'server_os' - ])->toArray()); + $this->site->update( + $healthData->only([ + 'php_version', + 'db_type', + 'db_version', + 'cms_version', + 'server_os' + ])->toArray() + ); } } From c73aea75384d0327a991f986d272e87be1372ab2 Mon Sep 17 00:00:00 2001 From: David Jardin Date: Sat, 16 Nov 2024 11:41:41 +0100 Subject: [PATCH 5/9] move endpoints --- app/Enum/WebserviceEndpoints.php | 8 ++++++++ app/{ => Http}/Controllers/Controller.php | 0 app/Jobs/CheckSiteHealth.php | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 app/Enum/WebserviceEndpoints.php rename app/{ => Http}/Controllers/Controller.php (100%) diff --git a/app/Enum/WebserviceEndpoints.php b/app/Enum/WebserviceEndpoints.php new file mode 100644 index 0000000..012611c --- /dev/null +++ b/app/Enum/WebserviceEndpoints.php @@ -0,0 +1,8 @@ +performWebserviceRequest( HttpMethod::GET, - 'health.json' + WebserviceEndpoints::HEALTH_CHECK->value ); $healthData = collect($response); From 2dec37a525cae8cc8788fc8c9743017ec45d4ae6 Mon Sep 17 00:00:00 2001 From: David Jardin Date: Sat, 16 Nov 2024 11:50:38 +0100 Subject: [PATCH 6/9] expose endpoint-specific connectoinhelper method --- ...ceEndpoints.php => WebserviceEndpoint.php} | 2 +- app/Jobs/CheckSiteHealth.php | 10 +-- app/Services/SiteConnectionService.php | 79 ++++++++++++------- 3 files changed, 51 insertions(+), 40 deletions(-) rename app/Enum/{WebserviceEndpoints.php => WebserviceEndpoint.php} (68%) diff --git a/app/Enum/WebserviceEndpoints.php b/app/Enum/WebserviceEndpoint.php similarity index 68% rename from app/Enum/WebserviceEndpoints.php rename to app/Enum/WebserviceEndpoint.php index 012611c..5939a7e 100644 --- a/app/Enum/WebserviceEndpoints.php +++ b/app/Enum/WebserviceEndpoint.php @@ -2,7 +2,7 @@ namespace App\Enum; -enum WebserviceEndpoints: string +enum WebserviceEndpoint: string { case HEALTH_CHECK = "health.json"; } diff --git a/app/Jobs/CheckSiteHealth.php b/app/Jobs/CheckSiteHealth.php index 65fd08d..2f3e15f 100644 --- a/app/Jobs/CheckSiteHealth.php +++ b/app/Jobs/CheckSiteHealth.php @@ -29,18 +29,10 @@ public function handle(): void /** @var SiteConnectionService $connection */ $connection = $this->site->connection; - $response = $connection->performWebserviceRequest( - HttpMethod::GET, - WebserviceEndpoints::HEALTH_CHECK->value - ); + $response = $connection->checkHealth(); $healthData = collect($response); - // Perform a sanity check - if (!$healthData->has('cms_version')) { - throw new \Exception("Invalid health response content"); - } - // Write updated data to DB $this->site->update( $healthData->only([ diff --git a/app/Services/SiteConnectionService.php b/app/Services/SiteConnectionService.php index 0ace319..5f38a89 100644 --- a/app/Services/SiteConnectionService.php +++ b/app/Services/SiteConnectionService.php @@ -3,6 +3,7 @@ namespace App\Services; use App\Enum\HttpMethod; +use App\Enum\WebserviceEndpoint; use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Psr7\Request; @@ -16,35 +17,19 @@ public function __construct(protected readonly string $baseUrl, protected readon { } - protected function performRequest( - RequestInterface $request, - array $options = [] - ): array { - /** @var Client $httpClient */ - $httpClient = App::make(Client::class); - - /** @var Response $response */ - $response = $httpClient->send( - $request, - $options + public function checkHealth(): array + { + $healthData = $this->performWebserviceRequest( + HttpMethod::GET, + WebserviceEndpoint::HEALTH_CHECK ); - // Validate response - if (!json_validate((string) $response->getBody())) { - throw new RequestException( - "Invalid JSON body", - $request, - $response - ); + // Perform a sanity check + if (empty($healthData['cms_version'])) { + throw new \Exception("Invalid health response content"); } - // Return decoded body - return json_decode( - (string) $response->getBody(), - true, - 512, - JSON_THROW_ON_ERROR - ); + return $healthData; } public function performExtractionRequest(array $data): array @@ -56,7 +41,7 @@ public function performExtractionRequest(array $data): array $data['password'] = $this->key; - return $this->performRequest( + return $this->performHttpRequest( $request, [ 'form_params' => $data, @@ -65,21 +50,55 @@ public function performExtractionRequest(array $data): array ); } - public function performWebserviceRequest(HttpMethod $method, string $endpoint, array $data = []): array - { + protected function performWebserviceRequest( + HttpMethod $method, + WebserviceEndpoint $endpoint, + array $data = [] + ): array { $request = new Request( $method->name, - $this->baseUrl . $endpoint, + $this->baseUrl . $endpoint->value, [ 'Authorization' => 'JUpdate-Token ' . $this->key ] ); - return $this->performRequest( + return $this->performHttpRequest( $request, [ "json" => $data ] ); } + + protected function performHttpRequest( + RequestInterface $request, + array $options = [] + ): array { + /** @var Client $httpClient */ + $httpClient = App::make(Client::class); + + /** @var Response $response */ + $response = $httpClient->send( + $request, + $options + ); + + // Validate response + if (!json_validate((string) $response->getBody())) { + throw new RequestException( + "Invalid JSON body", + $request, + $response + ); + } + + // Return decoded body + return json_decode( + (string) $response->getBody(), + true, + 512, + JSON_THROW_ON_ERROR + ); + } } From 2ecdb9a8e939972469a54341c8562e56e59750fa Mon Sep 17 00:00:00 2001 From: David Jardin Date: Sat, 16 Nov 2024 11:54:21 +0100 Subject: [PATCH 7/9] remove import --- app/Jobs/CheckSiteHealth.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/Jobs/CheckSiteHealth.php b/app/Jobs/CheckSiteHealth.php index 2f3e15f..1d514ab 100644 --- a/app/Jobs/CheckSiteHealth.php +++ b/app/Jobs/CheckSiteHealth.php @@ -2,11 +2,8 @@ namespace App\Jobs; -use App\Enum\HttpMethod; -use App\Enum\WebserviceEndpoints; use App\Models\Site; use App\Services\SiteConnectionService; -use GuzzleHttp\Exception\RequestException; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; From d8f1f5cdbdbe0bad32391ce5c471ccff92b877e9 Mon Sep 17 00:00:00 2001 From: David Jardin Date: Sat, 16 Nov 2024 11:55:53 +0100 Subject: [PATCH 8/9] cs fix --- app/Jobs/CheckSiteHealth.php | 4 +++- app/Jobs/UpdateSite.php | 4 +++- app/Models/Site.php | 4 +++- app/Services/SiteConnectionService.php | 4 +++- database/migrations/0001_01_01_000002_create_jobs_table.php | 3 +-- database/migrations/2024_11_15_191942_create_sites_table.php | 3 +-- pint.json | 3 +++ 7 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 pint.json diff --git a/app/Jobs/CheckSiteHealth.php b/app/Jobs/CheckSiteHealth.php index 1d514ab..3e0ab36 100644 --- a/app/Jobs/CheckSiteHealth.php +++ b/app/Jobs/CheckSiteHealth.php @@ -1,4 +1,6 @@ - Date: Sat, 16 Nov 2024 11:56:22 +0100 Subject: [PATCH 9/9] run pint in test mode --- .github/workflows/pint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pint.yaml b/.github/workflows/pint.yaml index 1fa5752..1577081 100644 --- a/.github/workflows/pint.yaml +++ b/.github/workflows/pint.yaml @@ -20,4 +20,4 @@ jobs: run: composer global require laravel/pint - name: Run Pint - run: pint + run: pint --test