Skip to content
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

Index and Alias feature #15

Merged
merged 2 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions src/Alias/Alias.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

namespace Olekjs\Elasticsearch\Alias;

use Illuminate\Http\Client\Response;
use Olekjs\Elasticsearch\Client;
use Olekjs\Elasticsearch\Contracts\AliasInterface;
use Olekjs\Elasticsearch\Contracts\ClientInterface;
use Olekjs\Elasticsearch\Exceptions\SearchResponseException;

class Alias implements AliasInterface
{
public function __construct(private readonly ClientInterface $client = new Client())
{
}

/**
* @throws SearchResponseException
*/
public function getIndicesForAlias(string $alias): array
{
$response = $this->client->getBaseClient()->get("$alias/_alias");

if ($response->clientError()) {
$this->client->throwSearchResponseException(
data_get($response, 'error.reason'),
$response->status(),
);
}

$indices = [];
foreach ($response->json() as $index => $aliases) {
$indices[] = $index;
}

return $indices;
}

public function add(string $index, string $alias): bool
{
$response = $this->runActions([
[
'add' => [
'index' => $index,
'alias' => $alias,
]
]
]);

return $response->successful();
}

public function remove(string $index, string $alias): bool
{
$response = $this->runActions([
[
'remove' => [
'index' => $index,
'alias' => $alias,
]
]
]);

return $response->successful();
}

public function runActions(array $actions): Response
{
$response = $this->client->getBaseClient()->post('_aliases', ['actions' => $actions]);

if ($response->clientError()) {
$this->client->throwUpdateResponseException(
json_encode($response->json(), JSON_THROW_ON_ERROR),
$response->status()
);
}

return $response;
}

public function replace(string $alias, string $newIndex, ?string $oldIndex = null): bool
{
if (null === $oldIndex) {
$indices = $this->getIndicesForAlias($alias);

$oldIndex = $indices[0] ?? null;
}

if (null === $oldIndex) {
throw new \LogicException('Old index is not defined.');
}

$response = $this->runActions([
[
'add' => [
'index' => $newIndex,
'alias' => $alias,
]
],
[
'remove' => [
'index' => $oldIndex,
'alias' => $alias,
]
]
]);

return $response->successful();
}
}
14 changes: 7 additions & 7 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public function create(string $index, string|int $id, array $data): IndexRespons

if ($response->clientError()) {
$this->throwIndexResponseException(
json_encode($response->json()),
json_encode($response->json(), JSON_THROW_ON_ERROR),
$response->status()
);
}
Expand Down Expand Up @@ -132,7 +132,7 @@ public function update(
'if_seq_no' => $sequenceNumber,
]);

$baseUrl = $baseUrl . '?' . $strictUrl;
$baseUrl .= '?' . $strictUrl;
}

$body = match (true) {
Expand All @@ -145,7 +145,7 @@ public function update(

if ($response->notFound() && data_get($response, 'status') === SymfonyResponse::HTTP_NOT_FOUND) {
$this->throwNotFoundException(
json_encode($response->json())
json_encode($response->json(), JSON_THROW_ON_ERROR)
);
}

Expand All @@ -156,13 +156,13 @@ public function update(
&& data_get($response, 'status') === SymfonyResponse::HTTP_CONFLICT
) {
$this->throwConflictResponseException(
json_encode($response->json())
json_encode($response->json(), JSON_THROW_ON_ERROR)
);
}

if ($response->clientError()) {
$this->throwUpdateResponseException(
json_encode($response->json()),
json_encode($response->json(), JSON_THROW_ON_ERROR),
$response->status()
);
}
Expand All @@ -181,13 +181,13 @@ public function delete(string $index, string|int $id): IndexResponseDto

if ($response->notFound() && data_get($response, 'result') === 'not_found') {
$this->throwNotFoundException(
json_encode($response->json())
json_encode($response->json(), JSON_THROW_ON_ERROR)
);
}

if ($response->clientError()) {
$this->throwDeleteResponseException(
json_encode($response->json()),
json_encode($response->json(), JSON_THROW_ON_ERROR),
$response->status()
);
}
Expand Down
16 changes: 8 additions & 8 deletions src/Contracts/AbstractClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

abstract class AbstractClient
{
protected function getBaseClient(): PendingRequest
public function getBaseClient(): PendingRequest
{
$apiKey = config('services.elasticsearch.api_key');
$port = config('services.elasticsearch.port');
Expand All @@ -39,7 +39,7 @@ protected function getBaseClient(): PendingRequest
/**
* @throws NotFoundResponseException
*/
protected function throwNotFoundException(string $message, int $code = Response::HTTP_NOT_FOUND): void
public function throwNotFoundException(string $message, int $code = Response::HTTP_NOT_FOUND): void
{
throw new NotFoundResponseException(
$message,
Expand All @@ -50,7 +50,7 @@ protected function throwNotFoundException(string $message, int $code = Response:
/**
* @throws IndexNotFoundResponseException
*/
protected function throwIndexNotFoundException(string $message, int $code = Response::HTTP_NOT_FOUND): void
public function throwIndexNotFoundException(string $message, int $code = Response::HTTP_NOT_FOUND): void
{
throw new IndexNotFoundResponseException(
$message,
Expand All @@ -61,7 +61,7 @@ protected function throwIndexNotFoundException(string $message, int $code = Resp
/**
* @throws SearchResponseException
*/
protected function throwSearchResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void
public function throwSearchResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void
{
throw new SearchResponseException(
$message,
Expand All @@ -72,7 +72,7 @@ protected function throwSearchResponseException(string $message, int $code = Res
/**
* @throws IndexResponseException
*/
protected function throwIndexResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void
public function throwIndexResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void
{
throw new IndexResponseException(
$message,
Expand All @@ -83,7 +83,7 @@ protected function throwIndexResponseException(string $message, int $code = Resp
/**
* @throws DeleteResponseException
*/
protected function throwDeleteResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void
public function throwDeleteResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void
{
throw new DeleteResponseException(
$message,
Expand All @@ -94,7 +94,7 @@ protected function throwDeleteResponseException(string $message, int $code = Res
/**
* @throws UpdateResponseException
*/
protected function throwUpdateResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void
public function throwUpdateResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void
{
throw new UpdateResponseException(
$message,
Expand All @@ -105,7 +105,7 @@ protected function throwUpdateResponseException(string $message, int $code = Res
/**
* @throws ConflictResponseException
*/
protected function throwConflictResponseException(string $message, int $code = Response::HTTP_CONFLICT): void
public function throwConflictResponseException(string $message, int $code = Response::HTTP_CONFLICT): void
{
throw new ConflictResponseException(
$message,
Expand Down
21 changes: 21 additions & 0 deletions src/Contracts/AliasInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Olekjs\Elasticsearch\Contracts;

use Illuminate\Http\Client\Response;

interface AliasInterface
{
/**
* @return array<int, string>
*/
public function getIndicesForAlias(string $alias): array;

public function add(string $index, string $alias): bool;

public function remove(string $index, string $alias): bool;

public function runActions(array $actions): Response;

public function replace(string $alias, string $newIndex, ?string $oldIndex = null): bool;
}
39 changes: 39 additions & 0 deletions src/Contracts/ClientInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Olekjs\Elasticsearch\Contracts;

use Illuminate\Http\Client\PendingRequest;
use Olekjs\Elasticsearch\Dto\BulkResponseDto;
use Olekjs\Elasticsearch\Dto\FindResponseDto;
use Olekjs\Elasticsearch\Dto\IndexResponseDto;
Expand All @@ -16,6 +17,7 @@
use Olekjs\Elasticsearch\Exceptions\NotFoundResponseException;
use Olekjs\Elasticsearch\Exceptions\SearchResponseException;
use Olekjs\Elasticsearch\Exceptions\UpdateResponseException;
use Symfony\Component\HttpFoundation\Response;

interface ClientInterface
{
Expand Down Expand Up @@ -108,4 +110,41 @@ public function paginate(string $index, array $data = [], int $page = 1, int $pe
* @throws CoreException
*/
public function bulk(BulkOperationInterface $bulk): BulkResponseDto;

public function getBaseClient(): PendingRequest;

/**
* @throws NotFoundResponseException
*/
public function throwNotFoundException(string $message, int $code = Response::HTTP_NOT_FOUND): void;

/**
* @throws IndexNotFoundResponseException
*/
public function throwIndexNotFoundException(string $message, int $code = Response::HTTP_NOT_FOUND): void;

/**
* @throws SearchResponseException
*/
public function throwSearchResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void;

/**
* @throws IndexResponseException
*/
public function throwIndexResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void;

/**
* @throws DeleteResponseException
*/
public function throwDeleteResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void;

/**
* @throws UpdateResponseException
*/
public function throwUpdateResponseException(string $message, int $code = Response::HTTP_BAD_REQUEST): void;

/**
* @throws ConflictResponseException
*/
public function throwConflictResponseException(string $message, int $code = Response::HTTP_CONFLICT): void;
}
10 changes: 10 additions & 0 deletions src/Contracts/IndexInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Olekjs\Elasticsearch\Contracts;

interface IndexInterface
{
public function create(string $name): bool;

public function delete(string $name): bool;
}
47 changes: 47 additions & 0 deletions src/Index/Index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Olekjs\Elasticsearch\Index;

use Olekjs\Elasticsearch\Client;
use Olekjs\Elasticsearch\Contracts\ClientInterface;
use Olekjs\Elasticsearch\Contracts\IndexInterface;
use Olekjs\Elasticsearch\Exceptions\UpdateResponseException;

class Index implements IndexInterface
{
public function __construct(private readonly ClientInterface $client = new Client())
{
}

/**
* @throws UpdateResponseException
* @throws \JsonException
*/
public function create(string $name, array $settings = []): bool
{
$response = $this->client->getBaseClient()->put($name, (object) $settings);

if ($response->clientError()) {
$this->client->throwUpdateResponseException(
json_encode($response->json(), JSON_THROW_ON_ERROR),
$response->status()
);
}

return $response->successful();
}

public function delete(string $name): bool
{
$response = $this->client->getBaseClient()->delete($name);

if ($response->clientError()) {
$this->client->throwDeleteResponseException(
json_encode($response->json(), JSON_THROW_ON_ERROR),
$response->status()
);
}

return $response->successful();
}
}
Loading
Loading