Skip to content

Commit

Permalink
Replace callable with Endpoint factory (#237)
Browse files Browse the repository at this point in the history
* Replace endpoint callable with EndpointFactory

Signed-off-by: Kim Pepper <[email protected]>

Signed-off-by: Kim Pepper <[email protected]>

Signed-off-by: Kim Pepper <[email protected]>

* Add BC for deprecated  property

Signed-off-by: Kim Pepper <[email protected]>

* Address feedback

Signed-off-by: Kim Pepper <[email protected]>

* Remove trait and fix bc

Signed-off-by: Kim Pepper <[email protected]>

* Addressed feedback

Signed-off-by: Kim Pepper <[email protected]>

* Address feedback

Signed-off-by: Kim Pepper <[email protected]>

* Added changelog and deprecation trigger

Signed-off-by: Kim Pepper <[email protected]>

* Update changelog

Signed-off-by: Kim Pepper <[email protected]>

* Generate API

Signed-off-by: Kim Pepper <[email protected]>

* Pass  factory to closure

Signed-off-by: Kim Pepper <[email protected]>

---------

Signed-off-by: Kim Pepper <[email protected]>
  • Loading branch information
kimpepper authored Nov 15, 2024
1 parent 6b08b16 commit f110a17
Show file tree
Hide file tree
Showing 74 changed files with 1,302 additions and 1,108 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Increased min version of `ezimuel/ringphp` to `^1.2.2`
- Changed fluent setters to return static
### Deprecated
- Passing a callable to \OpenSearch\ClientBuilder::setEndpoint() is deprecated and replaced with passing an EndpointFactory to \OpenSearch\ClientBuilder::setEndpointFactory() ([#237](https://github.com/opensearch-project/opensearch-php/pull/237))
### Removed
- Removed support for PHP 7.3 and 7.4
### Fixed
- Fixed PHP 8.4 deprecations
### Updated APIs
- Updated opensearch-php APIs to reflect [opensearch-api-specification@398481e](https://github.com/opensearch-project/opensearch-api-specification/commit/398481e5bd1cc590d947c35379c47096f2114f00)
- Updated opensearch-php APIs to reflect [opensearch-api-specification@6bb1fed](https://github.com/opensearch-project/opensearch-api-specification/commit/6bb1fed0a2c7cf094a5ecfdb01f0306a4b9f8eba)
- Updated opensearch-php APIs to reflect [opensearch-api-specification@07e329e](https://github.com/opensearch-project/opensearch-api-specification/commit/07e329e8d01fd0576de6a0a3c35412fd5a9163db)
- Updated opensearch-php APIs to reflect [opensearch-api-specification@1db1840](https://github.com/opensearch-project/opensearch-api-specification/commit/1db184063a463c5180a2cc824b1efc1aeebfd5eb)
Expand Down
336 changes: 181 additions & 155 deletions src/OpenSearch/Client.php

Large diffs are not rendered by default.

52 changes: 24 additions & 28 deletions src/OpenSearch/ClientBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@
use Aws\Credentials\CredentialProvider;
use Aws\Credentials\Credentials;
use Aws\Credentials\CredentialsInterface;
use GuzzleHttp\Ring\Client\CurlHandler;
use GuzzleHttp\Ring\Client\CurlMultiHandler;
use GuzzleHttp\Ring\Client\Middleware;
use OpenSearch\Common\Exceptions\AuthenticationConfigException;
use OpenSearch\Common\Exceptions\InvalidArgumentException;
use OpenSearch\Common\Exceptions\RuntimeException;
use OpenSearch\Common\Exceptions\AuthenticationConfigException;
use OpenSearch\ConnectionPool\AbstractConnectionPool;
use OpenSearch\ConnectionPool\Selectors\RoundRobinSelector;
use OpenSearch\ConnectionPool\Selectors\SelectorInterface;
Expand All @@ -38,9 +41,6 @@
use OpenSearch\Namespaces\NamespaceBuilderInterface;
use OpenSearch\Serializers\SerializerInterface;
use OpenSearch\Serializers\SmartSerializer;
use GuzzleHttp\Ring\Client\CurlHandler;
use GuzzleHttp\Ring\Client\CurlMultiHandler;
use GuzzleHttp\Ring\Client\Middleware;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use ReflectionClass;
Expand All @@ -54,10 +54,7 @@ class ClientBuilder
*/
private $transport;

/**
* @var callable|null
*/
private $endpoint;
private ?EndpointFactoryInterface $endpointFactory = null;

/**
* @var NamespaceBuilderInterface[]
Expand Down Expand Up @@ -184,10 +181,13 @@ public function getTransport(): Transport

/**
* Can supply second param to Client::__construct() when invoking manually or with dependency injection
*
* @deprecated in 2.3.2 and will be removed in 3.0.0. Use \OpenSearch\ClientBuilder::getEndpointFactory() instead.
*/
public function getEndpoint(): callable
{
return $this->endpoint;
@trigger_error(__METHOD__ . '() is deprecated in 2.3.2 and will be removed in 3.0.0. Use \OpenSearch\ClientBuilder::getEndpointFactory() instead.', E_USER_DEPRECATED);
return fn ($c) => $this->endpointFactory->getEndpoint('OpenSearch\\Endpoints\\' . $c);
}

/**
Expand Down Expand Up @@ -329,11 +329,20 @@ public function setConnectionPool($connectionPool, array $args = []): ClientBuil
* Set the endpoint
*
* @param callable $endpoint
*
* @deprecated in 2.3.2 and will be removed in 3.0.0. Use \OpenSearch\ClientBuilder::setEndpointFactory() instead.
*/
public function setEndpoint(callable $endpoint): ClientBuilder
{
$this->endpoint = $endpoint;
@trigger_error(__METHOD__ . '() is deprecated in 2.3.2 and will be removed in 3.0.0. Use \OpenSearch\ClientBuilder::setEndpointFactory() instead.', E_USER_DEPRECATED);
$this->endpointFactory = new LegacyEndpointFactory($endpoint);

return $this;
}

public function setEndpointFactory(EndpointFactoryInterface $endpointFactory): ClientBuilder
{
$this->endpointFactory = $endpointFactory;
return $this;
}

Expand Down Expand Up @@ -671,21 +680,8 @@ public function build(): Client

$this->buildTransport();

if (is_null($this->endpoint)) {
$serializer = $this->serializer;

$this->endpoint = function ($class) use ($serializer) {
$fullPath = '\\OpenSearch\\Endpoints\\' . $class;

$reflection = new ReflectionClass($fullPath);
$constructor = $reflection->getConstructor();

if ($constructor && $constructor->getParameters()) {
return new $fullPath($serializer);
} else {
return new $fullPath();
}
};
if (is_null($this->endpointFactory)) {
$this->endpointFactory = new EndpointFactory($this->serializer);
}

$registeredNamespaces = [];
Expand All @@ -696,12 +692,12 @@ public function build(): Client
$registeredNamespaces[$builder->getName()] = $builder->getObject($this->transport, $this->serializer);
}

return $this->instantiate($this->transport, $this->endpoint, $registeredNamespaces);
return $this->instantiate($this->transport, $this->endpointFactory, $registeredNamespaces);
}

protected function instantiate(Transport $transport, callable $endpoint, array $registeredNamespaces): Client
protected function instantiate(Transport $transport, EndpointFactoryInterface $endpointFactory, array $registeredNamespaces): Client
{
return new Client($transport, $endpoint, $registeredNamespaces);
return new Client($transport, $endpointFactory, $registeredNamespaces);
}

private function buildLoggers(): void
Expand Down
55 changes: 55 additions & 0 deletions src/OpenSearch/EndpointFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace OpenSearch;

use OpenSearch\Endpoints\AbstractEndpoint;
use OpenSearch\Serializers\SerializerInterface;
use ReflectionClass;

/**
* A factory for creating endpoints.
*/
class EndpointFactory implements EndpointFactoryInterface
{
/**
* @var array<string, AbstractEndpoint>
*/
private array $endpoints = [];

public function __construct(
protected SerializerInterface $serializer,
) {
}

/**
* {@inheritdoc}
*/
public function getEndpoint(string $class): AbstractEndpoint
{
if (!isset($this->endpoints[$class])) {
$this->endpoints[$class] = $this->createEndpoint($class);
}

return $this->endpoints[$class];
}

/**
* Creates an endpoint.
*
* @phpstan-template T of AbstractEndpoint
* @phpstan-param class-string<T> $class
* @phpstan-return T
* @throws \ReflectionException
*/
private function createEndpoint(string $class): AbstractEndpoint
{
$reflection = new ReflectionClass($class);
$constructor = $reflection->getConstructor();

if ($constructor && $constructor->getParameters()) {
return new $class($this->serializer);
}
return new $class();
}

}
21 changes: 21 additions & 0 deletions src/OpenSearch/EndpointFactoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace OpenSearch;

use OpenSearch\Endpoints\AbstractEndpoint;

/**
* A factory for creating endpoints.
*/
interface EndpointFactoryInterface
{
/**
* Gets an endpoint.
*
* @phpstan-template T of AbstractEndpoint
* @phpstan-param class-string<T> $class
* @phpstan-return T
*/
public function getEndpoint(string $class): AbstractEndpoint;

}
81 changes: 81 additions & 0 deletions src/OpenSearch/EndpointInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace OpenSearch;

/**
* Provides and interface for endpoints.
*/
interface EndpointInterface
{
/**
* Get the whitelist of allowed parameters.
*
* @return string[]
*/
public function getParamWhitelist(): array;

/**
* Get the URI.
*/
public function getURI(): string;

/**
* Get the HTTP method.
*/
public function getMethod(): string;

/**
* Set the query string parameters.
*/
public function setParams(array $params): static;

/**
* Get the query string parameters.
*/
public function getParams(): array;

/**
* Get the options.
*
* @return array<string, mixed>
*/
public function getOptions(): array;

/**
* Get the index.
*/
public function getIndex(): ?string;

/**
* Set the index.
*
* @param string|string[]|null $index
*
* @return $this
*/
public function setIndex(string|array|null $index): static;

/**
* Get the document ID.
*
* @param int|string|null $docID
*
* @return $this
*/
public function setId(int|string|null $docID): static;

/**
* Get the body of the request.
*
* @return array|string
*/
public function getBody(): array|string;

/**
* Set the body of the request.
*
* @param array<string,mixed> $body
*/
public function setBody(array $body): static;

}
39 changes: 39 additions & 0 deletions src/OpenSearch/LegacyEndpointFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace OpenSearch;

use OpenSearch\Endpoints\AbstractEndpoint;

/**
* Provides a endpoint factory using a legacy callable.
*
* @internal
*/
class LegacyEndpointFactory implements EndpointFactoryInterface
{
/**
* The endpoints callable.
*
* @var callable
*/
protected $endpoints;

public function __construct(callable $endpoints)
{
$this->endpoints = $endpoints;
}

/**
* {@inheritdoc}
*/
public function getEndpoint(string $class): AbstractEndpoint
{
// We need to strip the base namespace from the class name for BC.
$class = str_replace('OpenSearch\\Endpoints\\', '', $class);
$endpointBuilder = $this->endpoints;
return $endpointBuilder($class);
}

}
19 changes: 18 additions & 1 deletion src/OpenSearch/Namespaces/AbstractNamespace.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

namespace OpenSearch\Namespaces;

use OpenSearch\EndpointFactoryInterface;
use OpenSearch\Endpoints\AbstractEndpoint;
use OpenSearch\LegacyEndpointFactory;
use OpenSearch\Transport;

abstract class AbstractNamespace
Expand All @@ -31,15 +33,30 @@ abstract class AbstractNamespace
*/
protected $transport;

protected EndpointFactoryInterface $endpointFactory;

/**
* @var callable
*
* @deprecated in 2.3.2 and will be removed in 3.0.0. Use $endpointFactory property instead.
*/
protected $endpoints;

public function __construct(Transport $transport, callable $endpoints)
public function __construct(Transport $transport, callable|EndpointFactoryInterface $endpointFactory)
{
$this->transport = $transport;
if (is_callable($endpointFactory)) {
@trigger_error('Passing a callable as $endpointFactory param to ' . __METHOD__ . '() is deprecated in 2.3.2 and will be removed in 3.0.0. Pass an instance of \OpenSearch\EndpointFactoryInterface instead.', E_USER_DEPRECATED);
$endpoints = $endpointFactory;
$endpointFactory = new LegacyEndpointFactory($endpointFactory);
} else {
$endpoints = function ($c) use ($endpointFactory) {
@trigger_error('The $endpoints property is deprecated in 2.3.2 and will be removed in 3.0.0.', E_USER_DEPRECATED);
return $endpointFactory->getEndpoint('OpenSearch\\Endpoints\\' . $c);
};
}
$this->endpoints = $endpoints;
$this->endpointFactory = $endpointFactory;
}

/**
Expand Down
Loading

0 comments on commit f110a17

Please sign in to comment.