Skip to content

Commit 2635b29

Browse files
Striftnorkunas
andauthored
Add remote federated search (#738)
* Add network features * Add remote federation option * Run PHP CS fixer * Fix PHP doc * Add doc blocks * Run linter * Revert docker-compose.yml changes * Update src/Contracts/FederationOptions.php Co-authored-by: Tomas Norkūnas <[email protected]> * Update src/Contracts/NetworkResults.php Co-authored-by: Tomas Norkūnas <[email protected]> * Add doc about remote being non empty string * Update all node identifiers to non-empty strings --------- Co-authored-by: Tomas Norkūnas <[email protected]>
1 parent 860c6f8 commit 2635b29

File tree

7 files changed

+193
-0
lines changed

7 files changed

+193
-0
lines changed

src/Client.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
use Meilisearch\Endpoints\Delegates\HandlesIndex;
1111
use Meilisearch\Endpoints\Delegates\HandlesKeys;
1212
use Meilisearch\Endpoints\Delegates\HandlesMultiSearch;
13+
use Meilisearch\Endpoints\Delegates\HandlesNetwork;
1314
use Meilisearch\Endpoints\Delegates\HandlesSnapshots;
1415
use Meilisearch\Endpoints\Delegates\HandlesSystem;
1516
use Meilisearch\Endpoints\Delegates\HandlesTasks;
1617
use Meilisearch\Endpoints\Dumps;
1718
use Meilisearch\Endpoints\Health;
1819
use Meilisearch\Endpoints\Indexes;
1920
use Meilisearch\Endpoints\Keys;
21+
use Meilisearch\Endpoints\Network;
2022
use Meilisearch\Endpoints\Snapshots;
2123
use Meilisearch\Endpoints\Stats;
2224
use Meilisearch\Endpoints\Tasks;
@@ -37,6 +39,7 @@ class Client
3739
use HandlesSystem;
3840
use HandlesMultiSearch;
3941
use HandlesBatches;
42+
use HandlesNetwork;
4043

4144
/**
4245
* @param array<int, string> $clientAgents
@@ -60,5 +63,6 @@ public function __construct(
6063
$this->dumps = new Dumps($this->http);
6164
$this->snapshots = new Snapshots($this->http);
6265
$this->tenantToken = new TenantToken($this->http, $apiKey);
66+
$this->network = new Network($this->http);
6367
}
6468
}

src/Contracts/FederationOptions.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
class FederationOptions
88
{
99
private ?float $weight = null;
10+
/**
11+
* @var non-empty-string|null
12+
*/
13+
private ?string $remote = null;
1014

1115
/**
1216
* @return $this
@@ -18,15 +22,29 @@ public function setWeight(float $weight): self
1822
return $this;
1923
}
2024

25+
/**
26+
* @param non-empty-string $remote
27+
*
28+
* @return $this
29+
*/
30+
public function setRemote(string $remote): self
31+
{
32+
$this->remote = $remote;
33+
34+
return $this;
35+
}
36+
2137
/**
2238
* @return array{
2339
* weight?: float,
40+
* remote?: non-empty-string,
2441
* }
2542
*/
2643
public function toArray(): array
2744
{
2845
return array_filter([
2946
'weight' => $this->weight,
47+
'remote' => $this->remote,
3048
], static function ($item) { return null !== $item; });
3149
}
3250
}

src/Contracts/NetworkResults.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Meilisearch\Contracts;
6+
7+
class NetworkResults extends Data
8+
{
9+
/**
10+
* @var non-empty-string the identifier for the local node
11+
*/
12+
private string $self;
13+
14+
/**
15+
* @var array<non-empty-string, array{url: non-empty-string, searchApiKey: string}> a mapping of remote node IDs to their connection details
16+
*/
17+
private array $remotes;
18+
19+
/**
20+
* @param array{
21+
* self?: non-empty-string,
22+
* remotes?: array<non-empty-string, array{url: non-empty-string, searchApiKey: string}>
23+
* } $params
24+
*/
25+
public function __construct(array $params)
26+
{
27+
parent::__construct($params);
28+
29+
$this->self = $params['self'] ?? '';
30+
$this->remotes = $params['remotes'] ?? [];
31+
}
32+
33+
/**
34+
* @return non-empty-string the identifier for the local node
35+
*/
36+
public function getSelf(): string
37+
{
38+
return $this->self;
39+
}
40+
41+
/**
42+
* @return array<non-empty-string, array{url: non-empty-string, searchApiKey: string}>
43+
*/
44+
public function getRemotes(): array
45+
{
46+
return $this->remotes;
47+
}
48+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Meilisearch\Endpoints\Delegates;
6+
7+
use Meilisearch\Contracts\NetworkResults;
8+
use Meilisearch\Endpoints\Network;
9+
10+
trait HandlesNetwork
11+
{
12+
protected Network $network;
13+
14+
public function getNetwork(): NetworkResults
15+
{
16+
$response = $this->network->get();
17+
18+
return new NetworkResults($response);
19+
}
20+
21+
/**
22+
* @param array{
23+
* self?: non-empty-string,
24+
* remotes?: array<non-empty-string, array{url: non-empty-string, searchApiKey: string}>
25+
* } $network
26+
*/
27+
public function updateNetwork(array $network): NetworkResults
28+
{
29+
$response = $this->network->update($network);
30+
31+
return new NetworkResults($response);
32+
}
33+
}

src/Endpoints/Network.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Meilisearch\Endpoints;
6+
7+
use Meilisearch\Contracts\Endpoint;
8+
9+
class Network extends Endpoint
10+
{
11+
protected const PATH = '/network';
12+
13+
/**
14+
* @return array{
15+
* self: non-empty-string,
16+
* remotes: array<non-empty-string, array{url: non-empty-string, searchApiKey: string}>
17+
* }
18+
*/
19+
public function get(): array
20+
{
21+
return $this->http->get(self::PATH);
22+
}
23+
24+
/**
25+
* @param array{
26+
* self?: non-empty-string,
27+
* remotes?: array<non-empty-string, array{url: non-empty-string, searchApiKey: string}>
28+
* } $body
29+
*
30+
* @return array{
31+
* self: non-empty-string,
32+
* remotes: array<non-empty-string, array{url: non-empty-string, searchApiKey: string}>
33+
* }
34+
*/
35+
public function update(array $body): array
36+
{
37+
return $this->http->patch(self::PATH, $body);
38+
}
39+
}

tests/Contracts/FederationOptionsTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,11 @@ public function testSetWeight(): void
2222

2323
self::assertSame(['weight' => 2.369], $data->toArray());
2424
}
25+
26+
public function testSetRemote(): void
27+
{
28+
$data = (new FederationOptions())->setRemote('ms-00');
29+
30+
self::assertSame(['remote' => 'ms-00'], $data->toArray());
31+
}
2532
}

tests/Endpoints/NetworksTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Endpoints;
6+
7+
use Meilisearch\Http\Client;
8+
use Tests\TestCase;
9+
10+
final class NetworksTest extends TestCase
11+
{
12+
protected function setUp(): void
13+
{
14+
parent::setUp();
15+
16+
$http = new Client($this->host, getenv('MEILISEARCH_API_KEY'));
17+
$http->patch('/experimental-features', ['network' => true]);
18+
}
19+
20+
public function testUpdateNetworks(): void
21+
{
22+
$networks = [
23+
'self' => 'ms-00',
24+
'remotes' => [
25+
'ms-00' => [
26+
'url' => 'http://INSTANCE_URL',
27+
'searchApiKey' => 'INSTANCE_API_KEY',
28+
],
29+
'ms-01' => [
30+
'url' => 'http://ANOTHER_INSTANCE_URL',
31+
'searchApiKey' => 'ANOTHER_INSTANCE_API_KEY',
32+
],
33+
],
34+
];
35+
36+
$response = $this->client->updateNetwork($networks);
37+
self::assertSame($networks['self'], $response->getSelf());
38+
self::assertSame($networks['remotes'], $response->getRemotes());
39+
40+
$response = $this->client->getNetwork();
41+
self::assertSame($networks['self'], $response->getSelf());
42+
self::assertSame($networks['remotes'], $response->getRemotes());
43+
}
44+
}

0 commit comments

Comments
 (0)