Lines
90.24%
37 / 41
Methods
33.33%
1 / 3
Classes
0.00%
0 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| waitForHealthy | 88.23% | 15 / 17 | 0.00% | 0 / 1 | 8.10 | ||
| configureElasticsearch | 85.71% | 12 / 14 | 0.00% | 0 / 1 | 4.05 | ||
| configureOpenSearch | 100.00% | 10 / 10 | 100.00% | 1 / 1 | 1 | ||
| 33 | class SearchClientFactory | |
| 34 | { | |
| 35 | /** | |
| 36 | * Polls the search engine health endpoint until it responds with a 2xx–4xx status. | |
| 37 | */ | |
| 38 | public static function waitForHealthy( | |
| 39 | string $baseUri, | |
| 40 | int $timeoutSeconds = 15, | |
| 41 | ?HttpClientInterface $httpClient = null, | |
| 42 | ?callable $httpClientFactory = null, | |
| 43 | ): void { | |
| 44 | try { | |
| 45 | $http = $httpClient; | |
| 46 | if ($http === null && $httpClientFactory !== null) { | |
| 47 | $createdHttpClient = $httpClientFactory(); | |
| 48 | if ($createdHttpClient instanceof HttpClientInterface) { | |
| 49 | $http = $createdHttpClient; | |
| 50 | } | |
| 51 | } | |
| 52 | ||
| 53 | $http ??= HttpClient::create(['verify_peer' => false]); | |
| 54 | $deadline = time() + $timeoutSeconds; | |
| 55 | do { | |
| 56 | try { | |
| 57 | $res = $http->request('GET', rtrim($baseUri, characters: '/') . '/_cluster/health'); | |
| 58 | $code = $res->getStatusCode(); | |
| 59 | if ($code >= 200 && $code < 500) { | |
| 60 | break; | |
| 61 | } | |
| 62 | } catch (Throwable $exception) { | |
| 63 | unset($exception); | |
| 64 | } | |
| 65 | usleep(500_000); | |
| 66 | } while (time() < $deadline); | |
| 67 | } catch (Throwable $exception) { | |
| 68 | unset($exception); | |
| 69 | } | |
| 70 | } | |
| 71 | ||
| 72 | /** | |
| 73 | * Configures the Elasticsearch client and attaches it to the Configuration. | |
| 74 | */ | |
| 75 | public static function configureElasticsearch( | |
| 76 | Configuration $faqConfig, | |
| 77 | string $configDir, | |
| 78 | ?HttpClientInterface $httpClient = null, | |
| 79 | ?callable $clientFactory = null, | |
| 80 | ): void { | |
| 81 | require $configDir . '/constants_elasticsearch.php'; | |
| 82 | $esConfig = new ElasticsearchConfiguration($configDir . '/elasticsearch.php'); | |
| 83 | ||
| 84 | $esBaseUri = $_ENV['ELASTICSEARCH_BASE_URI'] ?? $esConfig->getHosts()[0]; | |
| 85 | ||
| 86 | self::waitForHealthy($esBaseUri, (int) ($_ENV['SEARCH_WAIT_TIMEOUT'] ?? 15), $httpClient); | |
| 87 | ||
| 88 | try { | |
| 89 | $esClient = null; | |
| 90 | if ($clientFactory !== null) { | |
| 91 | $createdClient = $clientFactory($esBaseUri); | |
| 92 | if ($createdClient instanceof Client) { | |
| 93 | $esClient = $createdClient; | |
| 94 | } | |
| 95 | } | |
| 96 | ||
| 97 | $esClient ??= ClientBuilder::create()->setHosts([$esBaseUri])->build(); | |
| 98 | $faqConfig->setElasticsearch($esClient); | |
| 99 | $faqConfig->setElasticsearchConfig($esConfig); | |
| 100 | } catch (AuthenticationException $exception) { | |
| 101 | unset($exception); | |
| 102 | } | |
| 103 | } | |
| 104 | ||
| 105 | /** | |
| 106 | * Configures the OpenSearch client and attaches it to the Configuration. | |
| 107 | */ | |
| 108 | public static function configureOpenSearch( | |
| 109 | Configuration $faqConfig, | |
| 110 | string $configDir, | |
| 111 | ?HttpClientInterface $httpClient = null, | |
| 112 | ): void { | |
| 113 | require $configDir . '/constants_opensearch.php'; | |
| 114 | $openSearchConfig = new OpenSearchConfiguration($configDir . '/opensearch.php'); | |
| 115 | ||
| 116 | $baseUri = $_ENV['OPENSEARCH_BASE_URI'] ?? $openSearchConfig->getHosts()[0]; | |
| 117 | ||
| 118 | self::waitForHealthy($baseUri, (int) ($_ENV['SEARCH_WAIT_TIMEOUT'] ?? 15), $httpClient); | |
| 119 | ||
| 120 | $client = new SymfonyClientFactory()->create([ | |
| 121 | 'base_uri' => $baseUri, | |
| 122 | 'verify_peer' => false, | |
| 123 | ]); | |
| 124 | $faqConfig->setOpenSearch($client); | |
| 125 | $faqConfig->setOpenSearchConfig($openSearchConfig); | |
| 126 | } | |
| 127 | } |