Skip to content

Commit f110a17

Browse files
authored
Replace callable with Endpoint factory (#237)
* 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]>
1 parent 6b08b16 commit f110a17

File tree

74 files changed

+1302
-1108
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1302
-1108
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
1212
- Increased min version of `ezimuel/ringphp` to `^1.2.2`
1313
- Changed fluent setters to return static
1414
### Deprecated
15+
- 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))
1516
### Removed
1617
- Removed support for PHP 7.3 and 7.4
1718
### Fixed
1819
- Fixed PHP 8.4 deprecations
1920
### Updated APIs
21+
- Updated opensearch-php APIs to reflect [opensearch-api-specification@398481e](https://github.com/opensearch-project/opensearch-api-specification/commit/398481e5bd1cc590d947c35379c47096f2114f00)
2022
- Updated opensearch-php APIs to reflect [opensearch-api-specification@6bb1fed](https://github.com/opensearch-project/opensearch-api-specification/commit/6bb1fed0a2c7cf094a5ecfdb01f0306a4b9f8eba)
2123
- Updated opensearch-php APIs to reflect [opensearch-api-specification@07e329e](https://github.com/opensearch-project/opensearch-api-specification/commit/07e329e8d01fd0576de6a0a3c35412fd5a9163db)
2224
- Updated opensearch-php APIs to reflect [opensearch-api-specification@1db1840](https://github.com/opensearch-project/opensearch-api-specification/commit/1db184063a463c5180a2cc824b1efc1aeebfd5eb)

src/OpenSearch/Client.php

+181-155
Large diffs are not rendered by default.

src/OpenSearch/ClientBuilder.php

+24-28
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@
2424
use Aws\Credentials\CredentialProvider;
2525
use Aws\Credentials\Credentials;
2626
use Aws\Credentials\CredentialsInterface;
27+
use GuzzleHttp\Ring\Client\CurlHandler;
28+
use GuzzleHttp\Ring\Client\CurlMultiHandler;
29+
use GuzzleHttp\Ring\Client\Middleware;
30+
use OpenSearch\Common\Exceptions\AuthenticationConfigException;
2731
use OpenSearch\Common\Exceptions\InvalidArgumentException;
2832
use OpenSearch\Common\Exceptions\RuntimeException;
29-
use OpenSearch\Common\Exceptions\AuthenticationConfigException;
3033
use OpenSearch\ConnectionPool\AbstractConnectionPool;
3134
use OpenSearch\ConnectionPool\Selectors\RoundRobinSelector;
3235
use OpenSearch\ConnectionPool\Selectors\SelectorInterface;
@@ -38,9 +41,6 @@
3841
use OpenSearch\Namespaces\NamespaceBuilderInterface;
3942
use OpenSearch\Serializers\SerializerInterface;
4043
use OpenSearch\Serializers\SmartSerializer;
41-
use GuzzleHttp\Ring\Client\CurlHandler;
42-
use GuzzleHttp\Ring\Client\CurlMultiHandler;
43-
use GuzzleHttp\Ring\Client\Middleware;
4444
use Psr\Log\LoggerInterface;
4545
use Psr\Log\NullLogger;
4646
use ReflectionClass;
@@ -54,10 +54,7 @@ class ClientBuilder
5454
*/
5555
private $transport;
5656

57-
/**
58-
* @var callable|null
59-
*/
60-
private $endpoint;
57+
private ?EndpointFactoryInterface $endpointFactory = null;
6158

6259
/**
6360
* @var NamespaceBuilderInterface[]
@@ -184,10 +181,13 @@ public function getTransport(): Transport
184181

185182
/**
186183
* Can supply second param to Client::__construct() when invoking manually or with dependency injection
184+
*
185+
* @deprecated in 2.3.2 and will be removed in 3.0.0. Use \OpenSearch\ClientBuilder::getEndpointFactory() instead.
187186
*/
188187
public function getEndpoint(): callable
189188
{
190-
return $this->endpoint;
189+
@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);
190+
return fn ($c) => $this->endpointFactory->getEndpoint('OpenSearch\\Endpoints\\' . $c);
191191
}
192192

193193
/**
@@ -329,11 +329,20 @@ public function setConnectionPool($connectionPool, array $args = []): ClientBuil
329329
* Set the endpoint
330330
*
331331
* @param callable $endpoint
332+
*
333+
* @deprecated in 2.3.2 and will be removed in 3.0.0. Use \OpenSearch\ClientBuilder::setEndpointFactory() instead.
332334
*/
333335
public function setEndpoint(callable $endpoint): ClientBuilder
334336
{
335-
$this->endpoint = $endpoint;
337+
@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);
338+
$this->endpointFactory = new LegacyEndpointFactory($endpoint);
339+
340+
return $this;
341+
}
336342

343+
public function setEndpointFactory(EndpointFactoryInterface $endpointFactory): ClientBuilder
344+
{
345+
$this->endpointFactory = $endpointFactory;
337346
return $this;
338347
}
339348

@@ -671,21 +680,8 @@ public function build(): Client
671680

672681
$this->buildTransport();
673682

674-
if (is_null($this->endpoint)) {
675-
$serializer = $this->serializer;
676-
677-
$this->endpoint = function ($class) use ($serializer) {
678-
$fullPath = '\\OpenSearch\\Endpoints\\' . $class;
679-
680-
$reflection = new ReflectionClass($fullPath);
681-
$constructor = $reflection->getConstructor();
682-
683-
if ($constructor && $constructor->getParameters()) {
684-
return new $fullPath($serializer);
685-
} else {
686-
return new $fullPath();
687-
}
688-
};
683+
if (is_null($this->endpointFactory)) {
684+
$this->endpointFactory = new EndpointFactory($this->serializer);
689685
}
690686

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

699-
return $this->instantiate($this->transport, $this->endpoint, $registeredNamespaces);
695+
return $this->instantiate($this->transport, $this->endpointFactory, $registeredNamespaces);
700696
}
701697

702-
protected function instantiate(Transport $transport, callable $endpoint, array $registeredNamespaces): Client
698+
protected function instantiate(Transport $transport, EndpointFactoryInterface $endpointFactory, array $registeredNamespaces): Client
703699
{
704-
return new Client($transport, $endpoint, $registeredNamespaces);
700+
return new Client($transport, $endpointFactory, $registeredNamespaces);
705701
}
706702

707703
private function buildLoggers(): void

src/OpenSearch/EndpointFactory.php

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace OpenSearch;
4+
5+
use OpenSearch\Endpoints\AbstractEndpoint;
6+
use OpenSearch\Serializers\SerializerInterface;
7+
use ReflectionClass;
8+
9+
/**
10+
* A factory for creating endpoints.
11+
*/
12+
class EndpointFactory implements EndpointFactoryInterface
13+
{
14+
/**
15+
* @var array<string, AbstractEndpoint>
16+
*/
17+
private array $endpoints = [];
18+
19+
public function __construct(
20+
protected SerializerInterface $serializer,
21+
) {
22+
}
23+
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
public function getEndpoint(string $class): AbstractEndpoint
28+
{
29+
if (!isset($this->endpoints[$class])) {
30+
$this->endpoints[$class] = $this->createEndpoint($class);
31+
}
32+
33+
return $this->endpoints[$class];
34+
}
35+
36+
/**
37+
* Creates an endpoint.
38+
*
39+
* @phpstan-template T of AbstractEndpoint
40+
* @phpstan-param class-string<T> $class
41+
* @phpstan-return T
42+
* @throws \ReflectionException
43+
*/
44+
private function createEndpoint(string $class): AbstractEndpoint
45+
{
46+
$reflection = new ReflectionClass($class);
47+
$constructor = $reflection->getConstructor();
48+
49+
if ($constructor && $constructor->getParameters()) {
50+
return new $class($this->serializer);
51+
}
52+
return new $class();
53+
}
54+
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace OpenSearch;
4+
5+
use OpenSearch\Endpoints\AbstractEndpoint;
6+
7+
/**
8+
* A factory for creating endpoints.
9+
*/
10+
interface EndpointFactoryInterface
11+
{
12+
/**
13+
* Gets an endpoint.
14+
*
15+
* @phpstan-template T of AbstractEndpoint
16+
* @phpstan-param class-string<T> $class
17+
* @phpstan-return T
18+
*/
19+
public function getEndpoint(string $class): AbstractEndpoint;
20+
21+
}

src/OpenSearch/EndpointInterface.php

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
namespace OpenSearch;
4+
5+
/**
6+
* Provides and interface for endpoints.
7+
*/
8+
interface EndpointInterface
9+
{
10+
/**
11+
* Get the whitelist of allowed parameters.
12+
*
13+
* @return string[]
14+
*/
15+
public function getParamWhitelist(): array;
16+
17+
/**
18+
* Get the URI.
19+
*/
20+
public function getURI(): string;
21+
22+
/**
23+
* Get the HTTP method.
24+
*/
25+
public function getMethod(): string;
26+
27+
/**
28+
* Set the query string parameters.
29+
*/
30+
public function setParams(array $params): static;
31+
32+
/**
33+
* Get the query string parameters.
34+
*/
35+
public function getParams(): array;
36+
37+
/**
38+
* Get the options.
39+
*
40+
* @return array<string, mixed>
41+
*/
42+
public function getOptions(): array;
43+
44+
/**
45+
* Get the index.
46+
*/
47+
public function getIndex(): ?string;
48+
49+
/**
50+
* Set the index.
51+
*
52+
* @param string|string[]|null $index
53+
*
54+
* @return $this
55+
*/
56+
public function setIndex(string|array|null $index): static;
57+
58+
/**
59+
* Get the document ID.
60+
*
61+
* @param int|string|null $docID
62+
*
63+
* @return $this
64+
*/
65+
public function setId(int|string|null $docID): static;
66+
67+
/**
68+
* Get the body of the request.
69+
*
70+
* @return array|string
71+
*/
72+
public function getBody(): array|string;
73+
74+
/**
75+
* Set the body of the request.
76+
*
77+
* @param array<string,mixed> $body
78+
*/
79+
public function setBody(array $body): static;
80+
81+
}
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenSearch;
6+
7+
use OpenSearch\Endpoints\AbstractEndpoint;
8+
9+
/**
10+
* Provides a endpoint factory using a legacy callable.
11+
*
12+
* @internal
13+
*/
14+
class LegacyEndpointFactory implements EndpointFactoryInterface
15+
{
16+
/**
17+
* The endpoints callable.
18+
*
19+
* @var callable
20+
*/
21+
protected $endpoints;
22+
23+
public function __construct(callable $endpoints)
24+
{
25+
$this->endpoints = $endpoints;
26+
}
27+
28+
/**
29+
* {@inheritdoc}
30+
*/
31+
public function getEndpoint(string $class): AbstractEndpoint
32+
{
33+
// We need to strip the base namespace from the class name for BC.
34+
$class = str_replace('OpenSearch\\Endpoints\\', '', $class);
35+
$endpointBuilder = $this->endpoints;
36+
return $endpointBuilder($class);
37+
}
38+
39+
}

src/OpenSearch/Namespaces/AbstractNamespace.php

+18-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121

2222
namespace OpenSearch\Namespaces;
2323

24+
use OpenSearch\EndpointFactoryInterface;
2425
use OpenSearch\Endpoints\AbstractEndpoint;
26+
use OpenSearch\LegacyEndpointFactory;
2527
use OpenSearch\Transport;
2628

2729
abstract class AbstractNamespace
@@ -31,15 +33,30 @@ abstract class AbstractNamespace
3133
*/
3234
protected $transport;
3335

36+
protected EndpointFactoryInterface $endpointFactory;
37+
3438
/**
3539
* @var callable
40+
*
41+
* @deprecated in 2.3.2 and will be removed in 3.0.0. Use $endpointFactory property instead.
3642
*/
3743
protected $endpoints;
3844

39-
public function __construct(Transport $transport, callable $endpoints)
45+
public function __construct(Transport $transport, callable|EndpointFactoryInterface $endpointFactory)
4046
{
4147
$this->transport = $transport;
48+
if (is_callable($endpointFactory)) {
49+
@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);
50+
$endpoints = $endpointFactory;
51+
$endpointFactory = new LegacyEndpointFactory($endpointFactory);
52+
} else {
53+
$endpoints = function ($c) use ($endpointFactory) {
54+
@trigger_error('The $endpoints property is deprecated in 2.3.2 and will be removed in 3.0.0.', E_USER_DEPRECATED);
55+
return $endpointFactory->getEndpoint('OpenSearch\\Endpoints\\' . $c);
56+
};
57+
}
4258
$this->endpoints = $endpoints;
59+
$this->endpointFactory = $endpointFactory;
4360
}
4461

4562
/**

0 commit comments

Comments
 (0)