Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit efe1e4e

Browse files
committed
Merge branch 'MAGETWO-89973' into 2.3-develop-pr9
2 parents c804fc0 + ea92f4c commit efe1e4e

File tree

7 files changed

+490
-59
lines changed

7 files changed

+490
-59
lines changed

app/code/Magento/Amqp/Setup/ConfigOptionsList.php

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class ConfigOptionsList implements ConfigOptionsListInterface
2525
const INPUT_KEY_QUEUE_AMQP_PASSWORD = 'amqp-password';
2626
const INPUT_KEY_QUEUE_AMQP_VIRTUAL_HOST = 'amqp-virtualhost';
2727
const INPUT_KEY_QUEUE_AMQP_SSL = 'amqp-ssl';
28+
const INPUT_KEY_QUEUE_AMQP_SSL_OPTIONS = 'amqp-ssl-options';
2829

2930
/**
3031
* Path to the values in the deployment config
@@ -35,6 +36,7 @@ class ConfigOptionsList implements ConfigOptionsListInterface
3536
const CONFIG_PATH_QUEUE_AMQP_PASSWORD = 'queue/amqp/password';
3637
const CONFIG_PATH_QUEUE_AMQP_VIRTUAL_HOST = 'queue/amqp/virtualhost';
3738
const CONFIG_PATH_QUEUE_AMQP_SSL = 'queue/amqp/ssl';
39+
const CONFIG_PATH_QUEUE_AMQP_SSL_OPTIONS = 'queue/amqp/ssl_options';
3840

3941
/**
4042
* Default values
@@ -109,6 +111,13 @@ public function getOptions()
109111
'Amqp SSL',
110112
self::DEFAULT_AMQP_SSL
111113
),
114+
new TextConfigOption(
115+
self::INPUT_KEY_QUEUE_AMQP_SSL_OPTIONS,
116+
TextConfigOption::FRONTEND_WIZARD_TEXTAREA,
117+
self::CONFIG_PATH_QUEUE_AMQP_SSL_OPTIONS,
118+
'Amqp SSL Options (JSON)',
119+
self::DEFAULT_AMQP_SSL
120+
),
112121
];
113122
}
114123

@@ -140,6 +149,21 @@ public function createConfig(array $data, DeploymentConfig $deploymentConfig)
140149
if (!$this->isDataEmpty($data, self::INPUT_KEY_QUEUE_AMQP_SSL)) {
141150
$configData->set(self::CONFIG_PATH_QUEUE_AMQP_SSL, $data[self::INPUT_KEY_QUEUE_AMQP_SSL]);
142151
}
152+
if (!$this->isDataEmpty(
153+
$data,
154+
self::INPUT_KEY_QUEUE_AMQP_SSL_OPTIONS
155+
)) {
156+
$options = json_decode(
157+
$data[self::INPUT_KEY_QUEUE_AMQP_SSL_OPTIONS],
158+
true
159+
);
160+
if ($options !== null) {
161+
$configData->set(
162+
self::CONFIG_PATH_QUEUE_AMQP_SSL_OPTIONS,
163+
$options
164+
);
165+
}
166+
}
143167
}
144168

145169
return [$configData];
@@ -154,12 +178,28 @@ public function validate(array $options, DeploymentConfig $deploymentConfig)
154178

155179
if (isset($options[self::INPUT_KEY_QUEUE_AMQP_HOST])
156180
&& $options[self::INPUT_KEY_QUEUE_AMQP_HOST] !== '') {
181+
if (!$this->isDataEmpty(
182+
$options,
183+
self::INPUT_KEY_QUEUE_AMQP_SSL_OPTIONS
184+
)) {
185+
$sslOptions = json_decode(
186+
$options[self::INPUT_KEY_QUEUE_AMQP_SSL_OPTIONS],
187+
true
188+
);
189+
} else {
190+
$sslOptions = null;
191+
}
192+
$isSslEnabled = !empty($options[self::INPUT_KEY_QUEUE_AMQP_SSL])
193+
&& $options[self::INPUT_KEY_QUEUE_AMQP_SSL] !== 'false';
194+
157195
$result = $this->connectionValidator->isConnectionValid(
158196
$options[self::INPUT_KEY_QUEUE_AMQP_HOST],
159197
$options[self::INPUT_KEY_QUEUE_AMQP_PORT],
160198
$options[self::INPUT_KEY_QUEUE_AMQP_USER],
161199
$options[self::INPUT_KEY_QUEUE_AMQP_PASSWORD],
162-
$options[self::INPUT_KEY_QUEUE_AMQP_VIRTUAL_HOST]
200+
$options[self::INPUT_KEY_QUEUE_AMQP_VIRTUAL_HOST],
201+
$isSslEnabled,
202+
$sslOptions
163203
);
164204

165205
if (!$result) {

app/code/Magento/Amqp/Setup/ConnectionValidator.php

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,27 @@
55
*/
66
namespace Magento\Amqp\Setup;
77

8-
use PhpAmqpLib\Connection\AMQPStreamConnection;
8+
use Magento\Framework\Amqp\Connection\Factory as ConnectionFactory;
9+
use Magento\Framework\Amqp\Connection\FactoryOptions;
910

1011
/**
1112
* Class ConnectionValidator - validates Amqp related settings
1213
*/
1314
class ConnectionValidator
1415
{
16+
/**
17+
* @var ConnectionFactory
18+
*/
19+
private $connectionFactory;
20+
21+
/**
22+
* @param ConnectionFactory $connectionFactory
23+
*/
24+
public function __construct(ConnectionFactory $connectionFactory)
25+
{
26+
$this->connectionFactory = $connectionFactory;
27+
}
28+
1529
/**
1630
* Checks Amqp Connection
1731
*
@@ -20,18 +34,33 @@ class ConnectionValidator
2034
* @param string $user
2135
* @param string $password
2236
* @param string $virtualHost
37+
* @param bool $ssl
38+
* @param string[]|null $sslOptions
2339
* @return bool true if the connection succeeded, false otherwise
2440
*/
25-
public function isConnectionValid($host, $port, $user, $password = '', $virtualHost = '')
26-
{
41+
public function isConnectionValid(
42+
$host,
43+
$port,
44+
$user,
45+
$password = '',
46+
$virtualHost = '',
47+
bool $ssl = false,
48+
array $sslOptions = null
49+
) {
2750
try {
28-
$connection = new AMQPStreamConnection(
29-
$host,
30-
$port,
31-
$user,
32-
$password,
33-
$virtualHost
34-
);
51+
$options = new FactoryOptions();
52+
$options->setHost($host);
53+
$options->setPort($port);
54+
$options->setUsername($user);
55+
$options->setPassword($password);
56+
$options->setVirtualHost($virtualHost);
57+
$options->setSslEnabled($ssl);
58+
59+
if ($sslOptions) {
60+
$options->setSslOptions($sslOptions);
61+
}
62+
63+
$connection = $this->connectionFactory->create($options);
3564

3665
$connection->close();
3766
} catch (\Exception $e) {

app/code/Magento/Amqp/Test/Unit/Setup/ConfigOptionsListTest.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ protected function setUp()
4747
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_PASSWORD => 'password',
4848
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_VIRTUAL_HOST => 'virtual host',
4949
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_SSL => 'ssl',
50-
50+
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_SSL_OPTIONS => '{"ssl_option":"test"}',
5151
];
5252

5353
$this->objectManager = new ObjectManager($this);
@@ -113,7 +113,14 @@ public function testGetOptions()
113113
ConfigOptionsList::CONFIG_PATH_QUEUE_AMQP_SSL,
114114
'Amqp SSL',
115115
ConfigOptionsList::DEFAULT_AMQP_SSL
116-
)
116+
),
117+
new TextConfigOption(
118+
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_SSL_OPTIONS,
119+
TextConfigOption::FRONTEND_WIZARD_TEXTAREA,
120+
ConfigOptionsList::CONFIG_PATH_QUEUE_AMQP_SSL_OPTIONS,
121+
'Amqp SSL Options (JSON)',
122+
ConfigOptionsList::DEFAULT_AMQP_SSL
123+
),
117124
];
118125
$this->assertEquals($expectedOptions, $this->model->getOptions());
119126
}
@@ -167,6 +174,7 @@ public function getCreateConfigDataProvider()
167174
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_PASSWORD => 'password',
168175
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_VIRTUAL_HOST => 'virtual host',
169176
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_SSL => 'ssl',
177+
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_SSL_OPTIONS => '{"ssl_option":"test"}',
170178
],
171179
['queue' =>
172180
['amqp' =>
@@ -177,6 +185,7 @@ public function getCreateConfigDataProvider()
177185
'password' => 'password',
178186
'virtualhost' => 'virtual host',
179187
'ssl' => 'ssl',
188+
'ssl_options' => ['ssl_option' => 'test'],
180189
]
181190
]
182191
],
@@ -189,6 +198,7 @@ public function getCreateConfigDataProvider()
189198
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_PASSWORD => 'password',
190199
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_VIRTUAL_HOST => 'virtual host',
191200
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_SSL => 'ssl',
201+
ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_SSL_OPTIONS => '{"ssl_option":"test"}',
192202
],
193203
['queue' =>
194204
['amqp' =>
@@ -199,6 +209,7 @@ public function getCreateConfigDataProvider()
199209
'password' => 'password',
200210
'virtualhost' => 'virtual host',
201211
'ssl' => 'ssl',
212+
'ssl_options' => ['ssl_option' => 'test'],
202213
]
203214
]
204215
],

lib/internal/Magento/Framework/Amqp/Config.php

Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
*/
66
namespace Magento\Framework\Amqp;
77

8+
use Magento\Framework\Amqp\Connection\FactoryOptions;
89
use Magento\Framework\App\DeploymentConfig;
9-
use PhpAmqpLib\Connection\AMQPStreamConnection;
10+
use Magento\Framework\App\ObjectManager;
11+
use PhpAmqpLib\Connection\AbstractConnection;
1012
use PhpAmqpLib\Channel\AMQPChannel;
11-
use PhpAmqpLib\Connection\AMQPSSLConnection;
13+
use Magento\Framework\Amqp\Connection\Factory as ConnectionFactory;
1214

1315
/**
1416
* Reads the Amqp config in the deployed environment configuration
@@ -44,7 +46,7 @@ class Config
4446
private $deploymentConfig;
4547

4648
/**
47-
* @var AMQPStreamConnection
49+
* @var AbstractConnection
4850
*/
4951
private $connection;
5052

@@ -67,6 +69,11 @@ class Config
6769
*/
6870
private $connectionName;
6971

72+
/**
73+
* @var ConnectionFactory
74+
*/
75+
private $connectionFactory;
76+
7077
/**
7178
* Initialize dependencies.
7279
*
@@ -88,12 +95,18 @@ class Config
8895
*
8996
* @param DeploymentConfig $config
9097
* @param string $connectionName
98+
* @param ConnectionFactory|null $connectionFactory
9199
* @since 100.0.0
92100
*/
93-
public function __construct(DeploymentConfig $config, $connectionName = 'amqp')
94-
{
101+
public function __construct(
102+
DeploymentConfig $config,
103+
$connectionName = 'amqp',
104+
ConnectionFactory $connectionFactory = null
105+
) {
95106
$this->deploymentConfig = $config;
96107
$this->connectionName = $connectionName;
108+
$this->connectionFactory = $connectionFactory
109+
?: ObjectManager::getInstance()->get(ConnectionFactory::class);
97110
}
98111

99112
/**
@@ -121,6 +134,27 @@ public function getValue($key)
121134
return isset($this->data[$key]) ? $this->data[$key] : null;
122135
}
123136

137+
/**
138+
* @return AbstractConnection
139+
*/
140+
private function createConnection(): AbstractConnection
141+
{
142+
$sslEnabled = trim($this->getValue(self::SSL)) === 'true';
143+
$options = new FactoryOptions();
144+
$options->setHost($this->getValue(self::HOST));
145+
$options->setPort($this->getValue(self::PORT));
146+
$options->setUsername($this->getValue(self::USERNAME));
147+
$options->setPassword($this->getValue(self::PASSWORD));
148+
$options->setVirtualHost($this->getValue(self::VIRTUALHOST));
149+
$options->setSslEnabled($sslEnabled);
150+
/** @var array $sslOptions */
151+
if ($sslOptions = $this->getValue(self::SSL_OPTIONS)) {
152+
$options->setSslOptions($sslOptions);
153+
}
154+
155+
return $this->connectionFactory->create($options);
156+
}
157+
124158
/**
125159
* Return Amqp channel
126160
*
@@ -131,8 +165,7 @@ public function getValue($key)
131165
public function getChannel()
132166
{
133167
if (!isset($this->connection) || !isset($this->channel)) {
134-
$this->connection = $this->getValue(self::SSL) ? $this->createSecureConnection() :
135-
$this->createUnsecureConnection();
168+
$this->connection = $this->createConnection();
136169

137170
$this->channel = $this->connection->channel();
138171
}
@@ -179,43 +212,4 @@ private function closeConnection()
179212
unset($this->connection);
180213
}
181214
}
182-
183-
/**
184-
* @return AMQPStreamConnection
185-
*/
186-
private function createUnsecureConnection()
187-
{
188-
return new AMQPStreamConnection(
189-
$this->getValue(self::HOST),
190-
$this->getValue(self::PORT),
191-
$this->getValue(self::USERNAME),
192-
$this->getValue(self::PASSWORD),
193-
$this->getValue(self::VIRTUALHOST)
194-
);
195-
}
196-
197-
/**
198-
* Create secure connection to AMQP server.
199-
*
200-
* Note: when you are passing empty array of SSL options PHP-AMQPLIB will actually create unsecure connection.
201-
*
202-
* @return AMQPSSLConnection
203-
*/
204-
private function createSecureConnection()
205-
{
206-
$sslOptions = $this->getValue(self::SSL_OPTIONS);
207-
208-
if (empty($sslOptions)) {
209-
$sslOptions = ['verify_peer' => true];
210-
}
211-
212-
return new AMQPSSLConnection(
213-
$this->getValue(self::HOST),
214-
$this->getValue(self::PORT),
215-
$this->getValue(self::USERNAME),
216-
$this->getValue(self::PASSWORD),
217-
$this->getValue(self::VIRTUALHOST),
218-
$sslOptions
219-
);
220-
}
221215
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Framework\Amqp\Connection;
9+
10+
use Magento\Framework\App\ObjectManager;
11+
use PhpAmqpLib\Connection\AbstractConnection;
12+
use PhpAmqpLib\Connection\AMQPSSLConnection;
13+
use PhpAmqpLib\Connection\AMQPStreamConnection;
14+
15+
/**
16+
* Create connection based on options.
17+
*/
18+
class Factory
19+
{
20+
/**
21+
* Create connection according to given options.
22+
*
23+
* @param FactoryOptions $options
24+
* @return AbstractConnection
25+
*/
26+
public function create(FactoryOptions $options): AbstractConnection
27+
{
28+
$connectionType = $options->isSslEnabled() ? AMQPSSLConnection::class : AMQPStreamConnection::class;
29+
$parameters = [
30+
'host' => $options->getHost(),
31+
'port' => $options->getPort(),
32+
'user' => $options->getUsername(),
33+
'password' => $options->getPassword(),
34+
'vhost' => $options->getVirtualHost() !== null ? $options->getVirtualHost() : '/',
35+
];
36+
37+
if ($options->isSslEnabled()) {
38+
$parameters['ssl_options'] = $options->getSslOptions() !== null
39+
? $options->getSslOptions()
40+
: ['verify_peer' => true];
41+
}
42+
43+
return ObjectManager::getInstance()->create($connectionType, $parameters);
44+
}
45+
}

0 commit comments

Comments
 (0)