Skip to content

Commit 8f25277

Browse files
tarrowoutdooracorn
andauthored
Add EnsureElasticSearchAliases command (#1053)
Created new command using `artisan:make command` Adds a single basic test that is also somewhat resilient to straggling Wikis left hanging around from other tests cases or seeding. Adjusts the ElasticSearchAliasInitJob to be dispatchable Adds types to the fields of ElasticSearchAliasInitJob Bug: T416158 Co-authored-by: Ollie <oliver.hyde@wikimedia.de>
1 parent 12df621 commit 8f25277

3 files changed

Lines changed: 106 additions & 6 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace App\Console\Commands;
4+
5+
use App\Jobs\ElasticSearchAliasInit;
6+
use App\Wiki;
7+
use Illuminate\Console\Command;
8+
use Illuminate\Support\Facades\Config;
9+
10+
class EnsureElasticSearchAliases extends Command {
11+
/**
12+
* The name and signature of the console command.
13+
*
14+
* @var string
15+
*/
16+
protected $signature = 'wbs-search:ensure-elasticsearch-aliases';
17+
18+
/**
19+
* The console command description.
20+
*
21+
* @var string
22+
*/
23+
protected $description = 'Command description';
24+
25+
/**
26+
* Execute the console command.
27+
*/
28+
public function handle() {
29+
$this->info('Dispatching Elasticsearch alias initialization jobs for all wikis...');
30+
31+
$allUndeletedWikis = Wiki::all();
32+
$esHosts = Config::get('wbstack.elasticsearch_hosts');
33+
foreach ($allUndeletedWikis as $wiki) {
34+
$this->info("Dispatching job for wiki: {$wiki->domain} (ID: {$wiki->id})");
35+
foreach ($esHosts as $host) {
36+
ElasticSearchAliasInit::dispatch($wiki->id, $host);
37+
}
38+
}
39+
40+
// TODO: check that this is actually the case?
41+
$this->info('All jobs dispatched successfully');
42+
43+
return 0;
44+
}
45+
}

app/Jobs/ElasticSearchAliasInit.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@
44

55
use App\Http\Curl\HttpRequest;
66
use App\WikiDb;
7+
use Illuminate\Foundation\Bus\Dispatchable;
78
use Illuminate\Support\Facades\Log;
89

910
class ElasticSearchAliasInit extends Job {
10-
private $wikiId;
11+
use Dispatchable;
1112

12-
private $esHost;
13+
public readonly int $wikiId;
14+
15+
public readonly string $esHost;
1316

1417
private $dbName;
1518

16-
private $sharedPrefix;
19+
public readonly string $sharedPrefix;
1720

18-
/**
19-
* @param string $dbName
20-
*/
2121
public function __construct(int $wikiId, string $esHost, ?string $sharedPrefix = null) {
2222
$this->wikiId = $wikiId;
2323
$this->esHost = $esHost;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Tests\Commands;
4+
5+
use App\Jobs\ElasticSearchAliasInit;
6+
use App\Wiki;
7+
use Illuminate\Foundation\Testing\DatabaseTransactions;
8+
use Illuminate\Support\Facades\Bus;
9+
use Illuminate\Support\Facades\Config;
10+
use Tests\TestCase;
11+
12+
class EnsureElasticsearchAliasesTest extends TestCase {
13+
use DatabaseTransactions;
14+
15+
public function testDispatchesElasticsearchAliasInitForAllWikis() {
16+
// setup
17+
Bus::fake();
18+
19+
// create some wikis
20+
$wiki1 = Wiki::factory()->create(['domain' => 'wiki1.wikibase.cloud']);
21+
$wiki2 = Wiki::factory()->create(['domain' => 'wiki2.wikibase.cloud']);
22+
23+
// configure elasticsearch hosts
24+
$esHost1 = 'es1.example.com:9200';
25+
$esHost2 = 'es2.example.com:9200';
26+
Config::set('wbstack.elasticsearch_hosts', [$esHost1, $esHost2]);
27+
28+
// run the command
29+
$this->artisan('wbs-search:ensure-elasticsearch-aliases')->assertExitCode(0);
30+
31+
// build a list of expected jobs based on the wikis and elasticsearch hosts configured
32+
$allUndeletedWikis = Wiki::all();
33+
$expectedJobs = [];
34+
foreach ($allUndeletedWikis as $wiki) {
35+
// null is just a random value; it's easier to unset the host if it's an array key
36+
$expectedJobs[$wiki->id] = [$esHost1 => null, $esHost2 => null];
37+
}
38+
39+
// each wiki should have 2 jobs dispatched (one for each elasticsearch host)
40+
Bus::assertDispatchedTimes(ElasticSearchAliasInit::class, Wiki::all()->count() * 2);
41+
Bus::assertDispatched(ElasticSearchAliasInit::class, function ($job) use (&$expectedJobs) {
42+
$this->assertArrayHasKey($job->wikiId, $expectedJobs);
43+
$this->assertArrayHasKey($job->esHost, $expectedJobs[$job->wikiId]);
44+
// delete the host from the expected jobs to ensure we don't have duplicate jobs for the same wiki and host
45+
unset($expectedJobs[$job->wikiId][$job->esHost]);
46+
if (empty($expectedJobs[$job->wikiId])) {
47+
unset($expectedJobs[$job->wikiId]);
48+
}
49+
50+
return true;
51+
});
52+
// assert that there are dispatched jobs for each wiki and for each ES host
53+
$this->assertEmpty($expectedJobs, 'Not all expected jobs were dispatched');
54+
}
55+
}

0 commit comments

Comments
 (0)