Skip to content

Commit 7aa305d

Browse files
committed
Merge branch 'philkra-add-opaque-id-mutator'
2 parents 3334f67 + efb6290 commit 7aa305d

File tree

7 files changed

+176
-18
lines changed

7 files changed

+176
-18
lines changed

docs/per-request-configuration.asciidoc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,32 @@
44
There are several configurations that can be set on a per-request basis, rather than at a connection- or client-level.
55
These are specified as part of the request associative array.
66

7+
8+
=== Request Identification
9+
10+
You can enrich your requests against Elasticsearch with an identifier string, that allows you to discover this identifier
11+
in https://www.elastic.co/guide/en/elasticsearch/reference/7.4/logging.html#deprecation-logging[deprecation logs], to support you with
12+
https://www.elastic.co/guide/en/elasticsearch/reference/7.4/index-modules-slowlog.html#_identifying_search_slow_log_origin[identifying search slow log origin]
13+
or to help with https://www.elastic.co/guide/en/elasticsearch/reference/current/tasks.html#_identifying_running_tasks[identifying running tasks].
14+
15+
16+
[source,php]
17+
----
18+
$client = ClientBuilder::create()->build();
19+
20+
$params = [
21+
'index' => 'test',
22+
'id' => 1,
23+
'client' => [
24+
'opaqueId' => '[email protected]_user1234', <1>
25+
]
26+
];
27+
$response = $client->get($params);
28+
29+
----
30+
<1> This will populate the `X-Opaque-Id` header with the value `[email protected]_user1234`
31+
32+
733
=== Ignoring exceptions
834
The library attempts to throw exceptions for common problems. These exceptions match the HTTP response code provided
935
by Elasticsearch. For example, attempting to GET a nonexistent document will throw a `MissingDocument404Exception`.

src/Elasticsearch/Connections/Connection.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ public function logRequestSuccess(array $request, array $response): void
374374
array(
375375
'method' => $request['http_method'],
376376
'uri' => $response['effective_url'],
377+
'port' => $response['transfer_stats']['primary_port'],
377378
'headers' => $request['headers'],
378379
'HTTP code' => $response['status'],
379380
'duration' => $response['transfer_stats']['total_time'],
@@ -408,11 +409,13 @@ public function logRequestSuccess(array $request, array $response): void
408409
public function logRequestFail(array $request, array $response, \Exception $exception): void
409410
{
410411
$this->log->debug('Request Body', array($request['body']));
412+
411413
$this->log->warning(
412414
'Request Failure:',
413415
array(
414416
'method' => $request['http_method'],
415417
'uri' => $response['effective_url'],
418+
'port' => $response['transfer_stats']['primary_port'],
416419
'headers' => $request['headers'],
417420
'HTTP code' => $response['status'],
418421
'duration' => $response['transfer_stats']['total_time'],

src/Elasticsearch/Endpoints/AbstractEndpoint.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ private function checkUserParams(array $params)
225225

226226
$whitelist = array_merge(
227227
$this->getParamWhitelist(),
228-
[ 'pretty', 'human', 'error_trace', 'source', 'filter_path' ]
228+
[ 'pretty', 'human', 'error_trace', 'source', 'filter_path', 'opaqueId' ]
229229
);
230230

231231
$invalid = array_diff(array_keys($params), $whitelist);
@@ -249,6 +249,15 @@ private function extractOptions(&$params)
249249
{
250250
// Extract out client options, then start transforming
251251
if (isset($params['client']) === true) {
252+
// Check if the opaqueId is populated and add the header
253+
if (isset($params['client']['opaqueId']) === true) {
254+
if (isset($params['client']['headers']) === false) {
255+
$params['client']['headers'] = [];
256+
}
257+
$params['client']['headers']['x-opaque-id'] = [trim($params['client']['opaqueId'])];
258+
unset($params['client']['opaqueId']);
259+
}
260+
252261
$this->options['client'] = $params['client'];
253262
unset($params['client']);
254263
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace Elasticsearch\Tests\ClientBuilder;
5+
6+
use Psr\Log\LoggerInterface;
7+
use Psr\Log\LogLevel;
8+
9+
class ArrayLogger implements LoggerInterface
10+
{
11+
public $output = [];
12+
13+
public function emergency($message, array $context = array())
14+
{
15+
$this->log(LogLevel::EMERGENCY, $message, $context);
16+
}
17+
18+
public function alert($message, array $context = array())
19+
{
20+
$this->log(LogLevel::ALERT, $message, $context);
21+
}
22+
23+
public function critical($message, array $context = array())
24+
{
25+
$this->log(LogLevel::CRITICAL, $message, $context);
26+
}
27+
28+
public function error($message, array $context = array())
29+
{
30+
$this->log(LogLevel::ERROR, $message, $context);
31+
}
32+
33+
public function warning($message, array $context = array())
34+
{
35+
$this->log(LogLevel::WARNING, $message, $context);
36+
}
37+
38+
public function notice($message, array $context = array())
39+
{
40+
$this->log(LogLevel::NOTICE, $message, $context);
41+
}
42+
43+
public function info($message, array $context = array())
44+
{
45+
$this->log(LogLevel::INFO, $message, $context);
46+
}
47+
48+
public function debug($message, array $context = array())
49+
{
50+
$this->log(LogLevel::DEBUG, $message, $context);
51+
}
52+
53+
public function log($level, $message, array $context = array())
54+
{
55+
$this->output[] = sprintf("%s: %s %s", $level, $message, json_encode($context));
56+
}
57+
}

tests/Elasticsearch/Tests/ClientBuilder/DummyLogger.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55

66
class DummyLogger
77
{
8-
8+
99
}

tests/Elasticsearch/Tests/ClientIntegrationTests.php

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
namespace Elasticsearch\Tests;
66

7-
use Elasticsearch;
7+
use Elasticsearch\ClientBuilder;
8+
use Elasticsearch\Common\Exceptions\Missing404Exception;
9+
use Elasticsearch\Tests\ClientBuilder\ArrayLogger;
10+
use Psr\Log\LogLevel;
811

912
/**
1013
* Class ClientTest
@@ -18,22 +21,62 @@
1821
*/
1922
class ClientIntegrationTests extends \PHPUnit\Framework\TestCase
2023
{
21-
public function testCustomQueryParams()
24+
public function setUp()
2225
{
23-
$client = Elasticsearch\ClientBuilder::create()
26+
if (empty(getenv('ES_TEST_HOST'))) {
27+
$this->markTestSkipped('I cannot execute integration test without ES_TEST_HOST env');
28+
}
29+
$this->logger = new ArrayLogger();
30+
}
31+
32+
public function testLogRequestSuccessHasInfoNotEmpty()
33+
{
34+
$client = ClientBuilder::create()
35+
->setHosts([getenv('ES_TEST_HOST')])
36+
->setLogger($this->logger)
37+
->build();
38+
39+
$result = $client->info();
40+
41+
$this->assertNotEmpty($this->getLevelOutput(LogLevel::INFO, $this->logger->output));
42+
}
43+
44+
public function testLogRequestSuccessHasPortInInfo()
45+
{
46+
$client = ClientBuilder::create()
2447
->setHosts([getenv('ES_TEST_HOST')])
48+
->setLogger($this->logger)
2549
->build();
2650

27-
$getParams = [
28-
'index' => 'test',
29-
'type' => 'test',
30-
'id' => 1,
31-
'parent' => 'abc',
32-
'custom' => ['customToken' => 'abc', 'otherToken' => 123],
33-
'client' => ['ignore' => 400]
34-
];
35-
$exists = $client->exists($getParams);
36-
37-
$this->assertFalse((bool) $exists);
51+
$result = $client->info();
52+
53+
$this->assertContains('"port"', $this->getLevelOutput(LogLevel::INFO, $this->logger->output));
54+
}
55+
56+
public function testLogRequestFailHasWarning()
57+
{
58+
$client = ClientBuilder::create()
59+
->setHosts([getenv('ES_TEST_HOST')])
60+
->setLogger($this->logger)
61+
->build();
62+
63+
try {
64+
$result = $client->get([
65+
'index' => 'foo',
66+
'id' => 'bar'
67+
]);
68+
} catch (Missing404Exception $e) {
69+
$this->assertNotEmpty($this->getLevelOutput(LogLevel::WARNING, $this->logger->output));
70+
}
71+
}
72+
73+
private function getLevelOutput(string $level, array $output): string
74+
{
75+
foreach ($output as $out) {
76+
if (false !== strpos($out, $level)) {
77+
return $out;
78+
}
79+
}
80+
return '';
3881
}
3982
}

tests/Elasticsearch/Tests/Endpoints/AbstractEndpointTest.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ class AbstractEndpointTest extends \PHPUnit\Framework\TestCase
1010
{
1111
private $endpoint;
1212

13+
protected function setUp()
14+
{
15+
$this->endpoint = $this->getMockForAbstractClass(AbstractEndpoint::class);
16+
}
17+
1318
public static function invalidParameters(): array
1419
{
1520
return [
@@ -20,6 +25,8 @@ public static function invalidParameters(): array
2025

2126
/**
2227
* @dataProvider invalidParameters
28+
*
29+
* @covers AbstractEndpoint::setParams
2330
*/
2431
public function testInvalidParamsCauseErrorsWhenProvidedToSetParams(array $params)
2532
{
@@ -32,8 +39,21 @@ public function testInvalidParamsCauseErrorsWhenProvidedToSetParams(array $param
3239
$this->endpoint->setParams($params);
3340
}
3441

35-
protected function setUp()
42+
/**
43+
* @covers AbstractEndpoint::setParams
44+
* @covers AbstractEndpoint::extractOptions
45+
* @covers AbstractEndpoint::getOptions
46+
*/
47+
public function testOpaqueIdInHeaders()
3648
{
37-
$this->endpoint = $this->getMockForAbstractClass(AbstractEndpoint::class);
49+
$params = ['client' => ['opaqueId' => 'test_id_' . rand(1000, 9999)]];
50+
$this->endpoint->setParams($params);
51+
52+
$options = $this->endpoint->getOptions();
53+
$this->assertArrayHasKey('client', $options);
54+
$this->assertArrayHasKey('headers', $options['client']);
55+
$this->assertArrayHasKey('x-opaque-id', $options['client']['headers']);
56+
$this->assertNotEmpty($options['client']['headers']['x-opaque-id']);
57+
$this->assertEquals($params['client']['opaqueId'], $options['client']['headers']['x-opaque-id'][0]);
3858
}
3959
}

0 commit comments

Comments
 (0)