-
Notifications
You must be signed in to change notification settings - Fork 440
/
Copy pathDriverFactory.php
124 lines (101 loc) · 4.08 KB
/
DriverFactory.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php
namespace Enqueue\Client;
use Enqueue\Client\Driver\RabbitMqDriver;
use Enqueue\Client\Driver\RabbitMqStompDriver;
use Enqueue\Client\Driver\StompManagementClient;
use Enqueue\Dsn\Dsn;
use Enqueue\Stomp\StompConnectionFactory;
use Interop\Amqp\AmqpConnectionFactory;
use Interop\Queue\ConnectionFactory;
final class DriverFactory implements DriverFactoryInterface
{
/**
* @var Config
*/
private $config;
/**
* @var RouteCollection
*/
private $routeCollection;
public function __construct(Config $config, RouteCollection $routeCollection)
{
$this->config = $config;
$this->routeCollection = $routeCollection;
}
public function create(ConnectionFactory $factory, string $dsn, array $config): DriverInterface
{
$dsn = new Dsn($dsn);
if ($driverInfo = $this->findDriverInfo($dsn, Resources::getAvailableDrivers())) {
$driverClass = $driverInfo['driverClass'];
if (RabbitMqDriver::class === $driverClass) {
if (false == $factory instanceof AmqpConnectionFactory) {
throw new \LogicException(sprintf(
'The factory must be instance of "%s", got "%s"',
AmqpConnectionFactory::class,
get_class($factory)
));
}
return new RabbitMqDriver($factory->createContext(), $this->config, $this->routeCollection);
}
if (RabbitMqStompDriver::class === $driverClass) {
if (false == $factory instanceof StompConnectionFactory) {
throw new \LogicException(sprintf(
'The factory must be instance of "%s", got "%s"',
StompConnectionFactory::class,
get_class($factory)
));
}
$managementClient = StompManagementClient::create(
ltrim($dsn->getPath(), '/'),
$dsn->getHost() ?: 'localhost',
$config['management_plugin_port'] ?? 15672,
(string) $dsn->getUser(),
(string) $dsn->getPassword()
);
return new RabbitMqStompDriver($factory->createContext(), $this->config, $this->routeCollection, $managementClient);
}
return new $driverClass($factory->createContext(), $this->config, $this->routeCollection);
}
$knownDrivers = Resources::getKnownDrivers();
if ($driverInfo = $this->findDriverInfo($dsn, $knownDrivers)) {
throw new \LogicException(sprintf(
'To use given scheme "%s" a package has to be installed. Run "composer req %s" to add it.',
$dsn->getScheme(),
implode(' ', $driverInfo['packages'])
));
}
throw new \LogicException(sprintf(
'A given scheme "%s" is not supported. Maybe it is a custom driver, make sure you registered it with "%s::addDriver".',
$dsn->getScheme(),
Resources::class
));
}
private function findDriverInfo(Dsn $dsn, array $factories): ?array
{
$protocol = $dsn->getSchemeProtocol();
if ($dsn->getSchemeExtensions()) {
foreach ($factories as $info) {
if (empty($info['requiredSchemeExtensions'])) {
continue;
}
if (false == in_array($protocol, $info['schemes'], true)) {
continue;
}
$diff = array_diff($dsn->getSchemeExtensions(), $info['requiredSchemeExtensions']);
if (empty($diff)) {
return $info;
}
}
}
foreach ($factories as $driverClass => $info) {
if (false == empty($info['requiredSchemeExtensions'])) {
continue;
}
if (false == in_array($protocol, $info['schemes'], true)) {
continue;
}
return $info;
}
return null;
}
}