Skip to content

Commit 1a2fdd9

Browse files
committed
MAGETWO-70573: Impossible to configure Redis through the CLI
- Additional classes to handle config options for session, cache, and page cache - Associated refactoring. Adding and updating tests
1 parent e8976ad commit 1a2fdd9

File tree

9 files changed

+1515
-53
lines changed

9 files changed

+1515
-53
lines changed

setup/src/Magento/Setup/Model/ConfigOptionsList.php

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,15 @@ class ConfigOptionsList implements ConfigOptionsListInterface
3636
/**
3737
* @var array
3838
*/
39-
private $validSaveHandlers = [
40-
ConfigOptionsListConstants::SESSION_SAVE_FILES,
41-
ConfigOptionsListConstants::SESSION_SAVE_DB,
39+
private $configOptionsCollection = [];
40+
41+
/**
42+
* @var array
43+
*/
44+
private $configOptionsListClasses = [
45+
\Magento\Setup\Model\ConfigOptionsList\Session::class,
46+
\Magento\Setup\Model\ConfigOptionsList\Cache::class,
47+
\Magento\Setup\Model\ConfigOptionsList\PageCache::class
4248
];
4349

4450
/**
@@ -51,6 +57,9 @@ public function __construct(ConfigGenerator $configGenerator, DbValidator $dbVal
5157
{
5258
$this->configGenerator = $configGenerator;
5359
$this->dbValidator = $dbValidator;
60+
foreach ($this->configOptionsListClasses as $className) {
61+
$this->configOptionsCollection[] = \Magento\Framework\App\ObjectManager::getInstance()->get($className);
62+
}
5463
}
5564

5665
/**
@@ -59,21 +68,13 @@ public function __construct(ConfigGenerator $configGenerator, DbValidator $dbVal
5968
*/
6069
public function getOptions()
6170
{
62-
return [
71+
$options = [
6372
new TextConfigOption(
6473
ConfigOptionsListConstants::INPUT_KEY_ENCRYPTION_KEY,
6574
TextConfigOption::FRONTEND_WIZARD_TEXT,
6675
ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY,
6776
'Encryption key'
6877
),
69-
new SelectConfigOption(
70-
ConfigOptionsListConstants::INPUT_KEY_SESSION_SAVE,
71-
SelectConfigOption::FRONTEND_WIZARD_SELECT,
72-
$this->validSaveHandlers,
73-
ConfigOptionsListConstants::CONFIG_PATH_SESSION_SAVE,
74-
'Session save handler',
75-
ConfigOptionsListConstants::SESSION_SAVE_FILES
76-
),
7778
new TextConfigOption(
7879
ConfigOptionsListConstants::INPUT_KEY_DB_HOST,
7980
TextConfigOption::FRONTEND_WIZARD_TEXT,
@@ -150,6 +151,12 @@ public function getOptions()
150151
'http Cache hosts'
151152
),
152153
];
154+
155+
foreach ($this->configOptionsCollection as $configOptionsList) {
156+
$options = array_merge($options, $configOptionsList->getOptions());
157+
}
158+
159+
return $options;
153160
}
154161

155162
/**
@@ -159,7 +166,6 @@ public function createConfig(array $data, DeploymentConfig $deploymentConfig)
159166
{
160167
$configData = [];
161168
$configData[] = $this->configGenerator->createCryptConfig($data, $deploymentConfig);
162-
$configData[] = $this->configGenerator->createSessionConfig($data);
163169
$definitionConfig = $this->configGenerator->createDefinitionsConfig($data);
164170
if (isset($definitionConfig)) {
165171
$configData[] = $definitionConfig;
@@ -169,6 +175,11 @@ public function createConfig(array $data, DeploymentConfig $deploymentConfig)
169175
$configData[] = $this->configGenerator->createXFrameConfig();
170176
$configData[] = $this->configGenerator->createModeConfig();
171177
$configData[] = $this->configGenerator->createCacheHostsConfig($data);
178+
179+
foreach ($this->configOptionsCollection as $configOptionsList) {
180+
$configData[] = $configOptionsList->createConfig($data, $deploymentConfig);
181+
}
182+
172183
return $configData;
173184
}
174185

@@ -197,9 +208,12 @@ public function validate(array $options, DeploymentConfig $deploymentConfig)
197208
$errors = array_merge($errors, $this->validateDbSettings($options, $deploymentConfig));
198209
}
199210

211+
foreach ($this->configOptionsCollection as $configOptionsList) {
212+
$errors = array_merge($errors, $configOptionsList->validate($options, $deploymentConfig));
213+
}
214+
200215
$errors = array_merge(
201216
$errors,
202-
$this->validateSessionSave($options),
203217
$this->validateEncryptionKey($options)
204218
);
205219

@@ -251,24 +265,6 @@ private function getDbSettings(array $options, DeploymentConfig $deploymentConfi
251265
return $options;
252266
}
253267

254-
/**
255-
* Validates session save param
256-
*
257-
* @param array $options
258-
* @return string[]
259-
*/
260-
private function validateSessionSave(array $options)
261-
{
262-
$errors = [];
263-
if (isset($options[ConfigOptionsListConstants::INPUT_KEY_SESSION_SAVE])
264-
&& !in_array($options[ConfigOptionsListConstants::INPUT_KEY_SESSION_SAVE], $this->validSaveHandlers)
265-
) {
266-
$errors[] = "Invalid session handler '{$options[ConfigOptionsListConstants::INPUT_KEY_SESSION_SAVE]}'";
267-
}
268-
269-
return $errors;
270-
}
271-
272268
/**
273269
* Validates encryption key param
274270
*
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Setup\Model\ConfigOptionsList;
8+
9+
use Magento\Framework\Setup\ConfigOptionsListInterface;
10+
use Magento\Framework\App\DeploymentConfig;
11+
use Magento\Framework\Config\Data\ConfigData;
12+
use Magento\Framework\Config\File\ConfigFilePool;
13+
use Magento\Framework\Setup\Option\SelectConfigOption;
14+
use Magento\Framework\Setup\Option\TextConfigOption;
15+
use Magento\Setup\Validator\RedisConnectionValidator;
16+
17+
/**
18+
* Deployment configuration options for the default cache
19+
*/
20+
class Cache implements ConfigOptionsListInterface
21+
{
22+
const INPUT_VALUE_CACHE_REDIS = 'redis';
23+
const CONFIG_VALUE_CACHE_REDIS = 'Cm_Cache_Backend_Redis';
24+
25+
const INPUT_KEY_CACHE_BACKEND = 'cache-backend';
26+
const INPUT_KEY_CACHE_BACKEND_REDIS_SERVER = 'cache-backend-redis-server';
27+
const INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE = 'cache-backend-redis-db';
28+
const INPUT_KEY_CACHE_BACKEND_REDIS_PORT = 'cache-backend-redis-port';
29+
30+
const CONFIG_PATH_CACHE_BACKEND = 'cache/frontend/default/backend';
31+
const CONFIG_PATH_CACHE_BACKEND_SERVER = 'cache/frontend/default/backend_options/server';
32+
const CONFIG_PATH_CACHE_BACKEND_DATABASE = 'cache/frontend/default/backend_options/database';
33+
const CONFIG_PATH_CACHE_BACKEND_PORT = 'cache/frontend/default/backend_options/port';
34+
35+
/**
36+
* @var array
37+
*/
38+
private $defaultConfigValues = [
39+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SERVER => '127.0.0.1',
40+
self::INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE => '0',
41+
self::INPUT_KEY_CACHE_BACKEND_REDIS_PORT => '6379'
42+
];
43+
44+
/**
45+
* @var array
46+
*/
47+
private $validBackendCacheOptions = [
48+
self::INPUT_VALUE_CACHE_REDIS
49+
];
50+
51+
/**
52+
* @var array
53+
*/
54+
private $inputKeyToConfigPathMap = [
55+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SERVER => self::CONFIG_PATH_CACHE_BACKEND_SERVER,
56+
self::INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE => self::CONFIG_PATH_CACHE_BACKEND_DATABASE,
57+
self::INPUT_KEY_CACHE_BACKEND_REDIS_PORT => self::CONFIG_PATH_CACHE_BACKEND_PORT,
58+
];
59+
60+
/**
61+
* @var RedisConnectionValidator
62+
*/
63+
private $redisValidator;
64+
65+
/**
66+
* Construct the Cache ConfigOptionsList
67+
*
68+
* @param RedisConnectionValidator $redisValidator
69+
*/
70+
public function __construct(RedisConnectionValidator $redisValidator)
71+
{
72+
$this->redisValidator = $redisValidator;
73+
}
74+
75+
/**
76+
* {@inheritdoc}
77+
*/
78+
public function getOptions()
79+
{
80+
return [
81+
new SelectConfigOption(
82+
self::INPUT_KEY_CACHE_BACKEND,
83+
SelectConfigOption::FRONTEND_WIZARD_SELECT,
84+
$this->validBackendCacheOptions,
85+
self::CONFIG_PATH_CACHE_BACKEND,
86+
'Default cache handler'
87+
),
88+
new TextConfigOption(
89+
self::INPUT_KEY_CACHE_BACKEND_REDIS_SERVER,
90+
TextConfigOption::FRONTEND_WIZARD_TEXT,
91+
self::CONFIG_PATH_CACHE_BACKEND_SERVER,
92+
'Redis server'
93+
),
94+
new TextConfigOption(
95+
self::INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE,
96+
TextConfigOption::FRONTEND_WIZARD_TEXT,
97+
self::CONFIG_PATH_CACHE_BACKEND_DATABASE,
98+
'Database number for the cache'
99+
),
100+
new TextConfigOption(
101+
self::INPUT_KEY_CACHE_BACKEND_REDIS_PORT,
102+
TextConfigOption::FRONTEND_WIZARD_TEXT,
103+
self::CONFIG_PATH_CACHE_BACKEND_PORT,
104+
'Redis server listen port'
105+
)
106+
];
107+
}
108+
109+
/**
110+
* {@inheritdoc}
111+
*/
112+
public function createConfig(array $options, DeploymentConfig $deploymentConfig)
113+
{
114+
$configData = new ConfigData(ConfigFilePool::APP_ENV);
115+
116+
if (isset($options[self::INPUT_KEY_CACHE_BACKEND])) {
117+
if ($options[self::INPUT_KEY_CACHE_BACKEND] == self::INPUT_VALUE_CACHE_REDIS) {
118+
$configData->set(self::CONFIG_PATH_CACHE_BACKEND, self::CONFIG_VALUE_CACHE_REDIS);
119+
$this->setDefaultRedisConfig($deploymentConfig, $configData);
120+
} else {
121+
$configData->set(self::CONFIG_PATH_CACHE_BACKEND, $options[self::INPUT_KEY_CACHE_BACKEND]);
122+
}
123+
}
124+
125+
foreach ($this->inputKeyToConfigPathMap as $inputKey => $configPath) {
126+
if (isset($options[$inputKey])) {
127+
$configData->set($configPath, $options[$inputKey]);
128+
}
129+
}
130+
return $configData;
131+
}
132+
133+
/**
134+
* {@inheritdoc}
135+
*/
136+
public function validate(array $options, DeploymentConfig $deploymentConfig)
137+
{
138+
$errors = [];
139+
140+
$currentCacheBackend = $deploymentConfig->get(Cache::CONFIG_PATH_CACHE_BACKEND);
141+
if (isset($options[self::INPUT_KEY_CACHE_BACKEND])) {
142+
if ($options[self::INPUT_KEY_CACHE_BACKEND] == self::INPUT_VALUE_CACHE_REDIS) {
143+
if (!$this->validateRedisConfig($options, $deploymentConfig)) {
144+
$errors[] = 'Invalid Redis configuration. Could not connect to Redis server.';
145+
}
146+
}
147+
} elseif ($currentCacheBackend == self::CONFIG_VALUE_CACHE_REDIS) {
148+
if (!$this->validateRedisConfig($options, $deploymentConfig)) {
149+
$errors[] = 'Invalid Redis configuration. Could not connect to Redis server.';
150+
}
151+
}
152+
153+
if (isset($options[self::INPUT_KEY_CACHE_BACKEND])
154+
&& !in_array($options[self::INPUT_KEY_CACHE_BACKEND], $this->validBackendCacheOptions)
155+
) {
156+
$errors[] = "Invalid cache handler '{$options[self::INPUT_KEY_CACHE_BACKEND]}'";
157+
}
158+
159+
return $errors;
160+
}
161+
162+
/**
163+
* Validate that Redis connection succeeds for given configuration
164+
*
165+
* @param array $options
166+
* @param DeploymentConfig $deploymentConfig
167+
* @return bool
168+
*/
169+
private function validateRedisConfig(array $options, DeploymentConfig $deploymentConfig)
170+
{
171+
$config = [];
172+
173+
$config['host'] = isset($options[self::INPUT_KEY_CACHE_BACKEND_REDIS_SERVER])
174+
? $options[self::INPUT_KEY_CACHE_BACKEND_REDIS_SERVER]
175+
: $deploymentConfig->get(
176+
self::CONFIG_PATH_CACHE_BACKEND_SERVER,
177+
$this->getDefaultConfigValue(self::INPUT_KEY_CACHE_BACKEND_REDIS_SERVER)
178+
);
179+
180+
$config['port'] = isset($options[self::INPUT_KEY_CACHE_BACKEND_REDIS_PORT])
181+
? $options[self::INPUT_KEY_CACHE_BACKEND_REDIS_PORT]
182+
: $deploymentConfig->get(
183+
self::CONFIG_PATH_CACHE_BACKEND_PORT,
184+
$this->getDefaultConfigValue(self::INPUT_KEY_CACHE_BACKEND_REDIS_PORT)
185+
);
186+
187+
$config['db'] = isset($options[self::INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE])
188+
? $options[self::INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE]
189+
: $deploymentConfig->get(
190+
self::CONFIG_PATH_CACHE_BACKEND_DATABASE,
191+
$this->getDefaultConfigValue(self::INPUT_KEY_CACHE_BACKEND_REDIS_DATABASE)
192+
);
193+
194+
return $this->redisValidator->isValidConnection($config);
195+
}
196+
197+
/**
198+
* Set default values for the Redis configuration.
199+
*
200+
* @param DeploymentConfig $deploymentConfig
201+
* @param ConfigData $configData
202+
* @return ConfigData
203+
*/
204+
private function setDefaultRedisConfig(DeploymentConfig $deploymentConfig, ConfigData $configData)
205+
{
206+
foreach ($this->inputKeyToConfigPathMap as $inputKey => $configPath) {
207+
$configData->set($configPath, $deploymentConfig->get($configPath, $this->getDefaultConfigValue($inputKey)));
208+
}
209+
210+
return $configData;
211+
}
212+
213+
/**
214+
* Get default value for input key
215+
*
216+
* @param string $inputKey
217+
* @return string
218+
*/
219+
private function getDefaultConfigValue($inputKey)
220+
{
221+
if (isset($this->defaultConfigValues[$inputKey])) {
222+
return $this->defaultConfigValues[$inputKey];
223+
} else {
224+
return '';
225+
}
226+
}
227+
}

0 commit comments

Comments
 (0)