-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Redirect healthcheck #156
Redirect healthcheck #156
Changes from 9 commits
521bc8d
361ab79
55ef3ed
69ec5aa
8431159
07ecef1
9feee09
2d8090d
cb9648b
5f7d217
71dc75b
94571f3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
use Illuminate\Support\Facades\Schema; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Database\Migrations\Migration; | ||
|
||
class AddUrlStatusToRedirectsTable extends Migration | ||
{ | ||
/** | ||
* Run the migrations. | ||
* | ||
* @return void | ||
*/ | ||
public function up() | ||
{ | ||
Schema::table('redirects', function (Blueprint $table) { | ||
$table->boolean('status')->default(0); | ||
}); | ||
} | ||
|
||
/** | ||
* Reverse the migrations. | ||
* | ||
* @return void | ||
*/ | ||
public function down() | ||
{ | ||
Schema::table('redirects', function (Blueprint $table) { | ||
$table->dropColumn('status'); | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<?php | ||
|
||
namespace Arbory\Base\Console\Commands; | ||
|
||
use Illuminate\Console\Command; | ||
use Illuminate\Support\Facades\DB; | ||
use Arbory\Base\Jobs\UpdateRedirectUrlStatus; | ||
use Illuminate\Foundation\Bus\DispatchesJobs; | ||
|
||
class RedirectHealthCommand extends Command | ||
{ | ||
use DispatchesJobs; | ||
/** | ||
* The name and signature of the console command. | ||
* | ||
* @var string | ||
*/ | ||
protected $signature = 'arbory.redirect-health | ||
{ids=[] : The array of IDs from redirects table to check (if not provided then would be selected all redirects table entries)} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do we pass "array" via CLI? Please specify that command expects comma separated values. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this really necessary? Who would ever know ID for specific redirect entry. |
||
{--errors : Show curl request errors}'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -v --verbose are standart flags to increase console output. Could we use those? |
||
|
||
/** | ||
* The console command description. | ||
* | ||
* @var string | ||
*/ | ||
protected $description = 'Runs an URL healthcheck to verify the redirects table `to_url` is available and update `status` field in table'; | ||
|
||
/** | ||
* Execute the console command. | ||
* | ||
* @return mixed | ||
*/ | ||
public function handle() | ||
{ | ||
try { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't put all your code in Try block, this is bad error suppression |
||
$ids = $this->getIDs(); | ||
$job = new UpdateRedirectUrlStatus($ids); | ||
|
||
$this->info('Start to check '.count($ids).' entries...'); | ||
|
||
$this->dispatchNow($job); | ||
$result = $job->getResult(); | ||
|
||
if (! empty($result) && count($result->getInvalidUrlList())) { | ||
$this->warn("\nInvalid URLs list:"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use PHP_EOL for new line |
||
foreach ($result->getInvalidUrlList() as $url) { | ||
$this->warn($url); | ||
} | ||
} | ||
|
||
if ($this->option('errors') && ! empty($result) && count($result->getErrors())) { | ||
foreach ($result->getErrors() as $url => $err) { | ||
$this->error("Request to $url - $err"); | ||
} | ||
} | ||
|
||
$this->warn("\nInvalid entries: {$result->getInvalidCount()}"); | ||
$this->info("Valid entries: {$result->getValidCount()}"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use sprintf or concat for string concatination |
||
} catch (\Exception $e) { | ||
$this->error('Redirects healthcheck failed with an exception'); | ||
$this->error($e->getMessage()); | ||
|
||
return 2; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why 2? Magic nu,ber |
||
} | ||
|
||
return 0; | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
public function selectAllRedirectIds() | ||
{ | ||
$results = DB::table('redirects')->where('id', '>', 0)->pluck('id')->toArray(); | ||
|
||
return $results; | ||
} | ||
|
||
/** | ||
* @param array $entryIds | ||
* @param int $status | ||
*/ | ||
public function setStatus(array $entryIds, int $status) | ||
{ | ||
DB::table('redirects')->whereIn('id', $entryIds)->update(['status' => $status]); | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
private function getIDs() | ||
{ | ||
$param = $this->argument('ids'); | ||
|
||
$final_ids = []; | ||
foreach (explode(',', $param) as $id) { | ||
if (is_numeric($id)) { | ||
$final_ids[] = $id; | ||
} | ||
} | ||
|
||
if (count($final_ids)) { | ||
return $final_ids; | ||
} | ||
|
||
return $this->selectAllRedirectIds(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?php | ||
|
||
namespace Arbory\Base\Jobs; | ||
|
||
use Illuminate\Log\Logger; | ||
use Illuminate\Support\Facades\DB; | ||
use Arbory\Base\RedirectHealthChecker; | ||
use Illuminate\Contracts\Queue\ShouldQueue; | ||
|
||
class UpdateRedirectUrlStatus implements ShouldQueue | ||
{ | ||
/** | ||
* @var Logger | ||
*/ | ||
protected $logger; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
protected $redirectIds; | ||
|
||
/** @var RedirectHealthChecker */ | ||
private $redirectHealthChecker; | ||
|
||
/** | ||
* UpdateRedirectUrlStatus constructor. | ||
* @param array $redirectIds | ||
*/ | ||
public function __construct(array $redirectIds) | ||
{ | ||
$this->redirectIds = $redirectIds; | ||
} | ||
|
||
/** | ||
* Execute the job. | ||
* | ||
* @param Logger $logger | ||
* @return void | ||
*/ | ||
public function handle(Logger $logger) | ||
{ | ||
$this->logger = $logger; | ||
|
||
$this->checkAndUpdateRedirectStatus(); | ||
} | ||
|
||
/** | ||
* @return void | ||
*/ | ||
private function checkAndUpdateRedirectStatus() | ||
{ | ||
try { | ||
$redirects = $this->selectRedirects($this->redirectIds); | ||
|
||
$redirectHealthChecker = new RedirectHealthChecker($redirects); | ||
$redirectHealthChecker->check(); | ||
|
||
$this->updateStatusBulk($redirectHealthChecker->getValidIds(), true); | ||
$this->updateStatusBulk($redirectHealthChecker->getInvalidIds(), false); | ||
|
||
$this->redirectHealthChecker = $redirectHealthChecker; | ||
} catch (\Exception $e) { | ||
$this->logger->warning($e->getMessage()); | ||
} | ||
} | ||
|
||
/** | ||
* @param array $ids | ||
* @return \Illuminate\Support\Collection | ||
*/ | ||
public function selectRedirects(array $ids) | ||
{ | ||
$results = DB::table('redirects')->whereIn('id', $ids)->get(['id', 'to_url']); | ||
|
||
return $results; | ||
} | ||
|
||
/* | ||
* @return void | ||
*/ | ||
public function updateStatusBulk(array $entryIds, int $status) | ||
{ | ||
DB::table('redirects')->whereIn('id', $entryIds)->update(['status' => $status]); | ||
} | ||
|
||
/** | ||
* @return RedirectHealthChecker|null | ||
*/ | ||
public function getResult() | ||
{ | ||
return $this->redirectHealthChecker ?? null; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
namespace Arbory\Base\Observers; | ||
|
||
use Arbory\Base\Pages\Redirect; | ||
use Arbory\Base\Jobs\UpdateRedirectUrlStatus; | ||
use Illuminate\Foundation\Bus\DispatchesJobs; | ||
|
||
class RedirectObserver | ||
{ | ||
use DispatchesJobs; | ||
|
||
/** | ||
* Handle the redirect "saved" event. | ||
* | ||
* @param Redirect $redirect | ||
* @return void | ||
*/ | ||
public function saved(Redirect $redirect) | ||
{ | ||
$job = new UpdateRedirectUrlStatus([$redirect->id]); | ||
$this->dispatchNow($job); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ class Redirect extends Model | |
protected $fillable = [ | ||
'from_url', | ||
'to_url', | ||
'status', | ||
]; | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this up, group with other extensions