Skip to content

Commit 1035b15

Browse files
committed
readd server info testkit support
1 parent 8a02508 commit 1035b15

File tree

6 files changed

+511
-0
lines changed

6 files changed

+511
-0
lines changed
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Neo4j PHP Client and Driver package.
7+
*
8+
* (c) Nagels <https://nagels.tech>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Laudis\Neo4j\TestkitBackend\Handlers;
15+
16+
use Exception;
17+
use Laudis\Neo4j\Databags\Neo4jError;
18+
use Laudis\Neo4j\Databags\SessionConfiguration;
19+
use Laudis\Neo4j\Enum\AccessMode;
20+
use Laudis\Neo4j\Exception\Neo4jException;
21+
use Laudis\Neo4j\Exception\TransactionException;
22+
use Laudis\Neo4j\TestkitBackend\Contracts\RequestHandlerInterface;
23+
use Laudis\Neo4j\TestkitBackend\Contracts\TestkitResponseInterface;
24+
use Laudis\Neo4j\TestkitBackend\MainRepository;
25+
use Laudis\Neo4j\TestkitBackend\Requests\ExecuteQueryRequest;
26+
use Laudis\Neo4j\TestkitBackend\Responses\DriverErrorResponse;
27+
use Laudis\Neo4j\TestkitBackend\Responses\EagerResultResponse;
28+
use Symfony\Component\Uid\Uuid;
29+
30+
/**
31+
* @implements RequestHandlerInterface<ExecuteQueryRequest>
32+
*/
33+
final class ExecuteQuery implements RequestHandlerInterface
34+
{
35+
public function __construct(
36+
private MainRepository $repository,
37+
) {
38+
}
39+
40+
/**
41+
* @param ExecuteQueryRequest $request
42+
*/
43+
public function handle($request): TestkitResponseInterface
44+
{
45+
try {
46+
$driver = $this->repository->getDriver($request->getDriverId());
47+
48+
if (method_exists($driver, 'executeQuery')) {
49+
return $this->handleWithExecuteQuery($driver, $request);
50+
}
51+
52+
return $this->handleWithSession($driver, $request);
53+
} catch (Exception $e) {
54+
$uuid = Uuid::v4();
55+
56+
if ($e instanceof Neo4jException || $e instanceof TransactionException) {
57+
return new DriverErrorResponse($uuid, $e);
58+
}
59+
60+
$neo4jError = new Neo4jError(
61+
$e->getMessage(),
62+
(string) $e->getCode(),
63+
'DatabaseError',
64+
'Service',
65+
'Service Unavailable'
66+
);
67+
68+
return new DriverErrorResponse($uuid, new Neo4jException([$neo4jError], $e));
69+
}
70+
}
71+
72+
private function handleWithExecuteQuery($driver, ExecuteQueryRequest $request): TestkitResponseInterface
73+
{
74+
$config = $this->buildExecutionConfig($request->getConfig());
75+
$params = $request->getParams() ?? [];
76+
77+
$eagerResult = $driver->executeQuery(
78+
$request->getCypher(),
79+
$params,
80+
$config
81+
);
82+
83+
$resultId = Uuid::v4();
84+
$this->repository->addEagerResult($resultId, $eagerResult);
85+
86+
return new EagerResultResponse($resultId, $eagerResult);
87+
}
88+
89+
private function handleWithSession($driver, ExecuteQueryRequest $request): TestkitResponseInterface
90+
{
91+
$config = $request->getConfig();
92+
93+
$sessionConfig = SessionConfiguration::default();
94+
95+
if (array_key_exists('database', $config)) {
96+
$sessionConfig = $sessionConfig->withDatabase($config['database']);
97+
}
98+
99+
$accessMode = AccessMode::READ();
100+
if (array_key_exists('routing', $config) && $config['routing'] === 'w') {
101+
$accessMode = AccessMode::WRITE();
102+
}
103+
$sessionConfig = $sessionConfig->withAccessMode($accessMode);
104+
105+
$session = $driver->createSession($sessionConfig);
106+
107+
try {
108+
$result = $session->run(
109+
$request->getCypher(),
110+
$request->getParams() ?? []
111+
);
112+
113+
$resultId = Uuid::v4();
114+
$this->repository->addEagerResult($resultId, $result);
115+
116+
return new EagerResultResponse($resultId, $result);
117+
} finally {
118+
$session->close();
119+
}
120+
}
121+
122+
private function buildExecutionConfig(?array $config): array
123+
{
124+
if ($config === null) {
125+
return [];
126+
}
127+
128+
$executionConfig = [];
129+
130+
if (array_key_exists('database', $config) && $config['database'] !== null) {
131+
$executionConfig['database'] = $config['database'];
132+
}
133+
134+
if (array_key_exists('routing', $config) && $config['routing'] !== null) {
135+
$executionConfig['routing'] = $config['routing'];
136+
}
137+
138+
if (array_key_exists('impersonatedUser', $config) && $config['impersonatedUser'] !== null) {
139+
$executionConfig['impersonatedUser'] = $config['impersonatedUser'];
140+
}
141+
142+
if (array_key_exists('txMeta', $config) && $config['txMeta'] !== null) {
143+
$executionConfig['txMeta'] = $config['txMeta'];
144+
}
145+
146+
if (array_key_exists('timeout', $config) && $config['timeout'] !== null) {
147+
$executionConfig['timeout'] = $config['timeout'] / 1000;
148+
}
149+
150+
if (array_key_exists('authorizationToken', $config) && $config['authorizationToken'] !== null) {
151+
$authToken = $config['authorizationToken'];
152+
if (array_key_exists('data', $authToken)) {
153+
$executionConfig['auth'] = $this->convertAuthToken($authToken['data']);
154+
}
155+
}
156+
157+
return $executionConfig;
158+
}
159+
160+
private function convertAuthToken(array $tokenData): array
161+
{
162+
$auth = [];
163+
164+
if (array_key_exists('scheme', $tokenData)) {
165+
$auth['scheme'] = $tokenData['scheme'];
166+
}
167+
168+
if (array_key_exists('principal', $tokenData)) {
169+
$auth['principal'] = $tokenData['principal'];
170+
}
171+
172+
if (array_key_exists('credentials', $tokenData)) {
173+
$auth['credentials'] = $tokenData['credentials'];
174+
}
175+
176+
if (array_key_exists('realm', $tokenData)) {
177+
$auth['realm'] = $tokenData['realm'];
178+
}
179+
180+
if (array_key_exists('parameters', $tokenData)) {
181+
$auth['parameters'] = $tokenData['parameters'];
182+
}
183+
184+
return $auth;
185+
}
186+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Neo4j PHP Client and Driver package.
7+
*
8+
* (c) Nagels <https://nagels.tech>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Laudis\Neo4j\TestkitBackend\Handlers;
15+
16+
use Exception;
17+
use Laudis\Neo4j\Databags\Neo4jError;
18+
use Laudis\Neo4j\Exception\Neo4jException;
19+
use Laudis\Neo4j\Exception\TransactionException;
20+
use Laudis\Neo4j\TestkitBackend\Contracts\RequestHandlerInterface;
21+
use Laudis\Neo4j\TestkitBackend\Contracts\TestkitResponseInterface;
22+
use Laudis\Neo4j\TestkitBackend\MainRepository;
23+
use Laudis\Neo4j\TestkitBackend\Requests\GetServerInfoRequest;
24+
use Laudis\Neo4j\TestkitBackend\Responses\DriverErrorResponse;
25+
use Laudis\Neo4j\TestkitBackend\Responses\ServerInfoResponse;
26+
use Symfony\Component\Uid\Uuid;
27+
28+
/**
29+
* @implements RequestHandlerInterface<GetServerInfoRequest>
30+
*/
31+
final class GetServerInfo implements RequestHandlerInterface
32+
{
33+
public function __construct(
34+
private MainRepository $repository,
35+
) {
36+
}
37+
38+
/**
39+
* @param GetServerInfoRequest $request
40+
*/
41+
public function handle($request): TestkitResponseInterface
42+
{
43+
try {
44+
$driver = $this->repository->getDriver($request->getDriverId());
45+
46+
$serverInfo = $driver->getServerInfo();
47+
48+
return new ServerInfoResponse($serverInfo);
49+
} catch (Neo4jException|TransactionException $e) {
50+
return new DriverErrorResponse(Uuid::v4(), $e);
51+
} catch (Exception $e) {
52+
$neo4jError = new Neo4jError(
53+
$e->getMessage(),
54+
(string) $e->getCode(),
55+
'DatabaseError',
56+
'Service',
57+
'Service Unavailable'
58+
);
59+
60+
return new DriverErrorResponse(Uuid::v4(), new Neo4jException([$neo4jError], $e));
61+
}
62+
}
63+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Neo4j PHP Client and Driver package.
7+
*
8+
* (c) Nagels <https://nagels.tech>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Laudis\Neo4j\TestkitBackend\Requests;
15+
16+
use Symfony\Component\Uid\Uuid;
17+
18+
final class ExecuteQueryRequest
19+
{
20+
private Uuid $driverId;
21+
private string $cypher;
22+
private ?array $params;
23+
private ?array $config;
24+
25+
public function __construct(
26+
Uuid $driverId,
27+
string $cypher,
28+
?array $params = null,
29+
?array $config = null,
30+
) {
31+
$this->driverId = $driverId;
32+
$this->cypher = $cypher;
33+
$this->params = $params;
34+
$this->config = $config;
35+
}
36+
37+
public function getDriverId(): Uuid
38+
{
39+
return $this->driverId;
40+
}
41+
42+
public function getCypher(): string
43+
{
44+
return $this->cypher;
45+
}
46+
47+
public function getParams(): ?array
48+
{
49+
return $this->params;
50+
}
51+
52+
public function getConfig(): ?array
53+
{
54+
return $this->config;
55+
}
56+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Neo4j PHP Client and Driver package.
7+
*
8+
* (c) Nagels <https://nagels.tech>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Laudis\Neo4j\TestkitBackend\Requests;
15+
16+
use Symfony\Component\Uid\Uuid;
17+
18+
final class GetServerInfoRequest
19+
{
20+
private Uuid $driverId;
21+
22+
public function __construct(Uuid $driverId)
23+
{
24+
$this->driverId = $driverId;
25+
}
26+
27+
public function getDriverId(): Uuid
28+
{
29+
return $this->driverId;
30+
}
31+
}

0 commit comments

Comments
 (0)