Skip to content

Commit 97e415c

Browse files
author
Bohdan Korablov
committed
MAGETWO-65208: Store checksum for every section of configuration file & change behavior on read-only FS & add sorting of importers
1 parent 6c1938f commit 97e415c

File tree

11 files changed

+236
-134
lines changed

11 files changed

+236
-134
lines changed

app/code/Magento/Deploy/Console/Command/App/ConfigImport/Importer.php

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77

88
use Magento\Framework\App\DeploymentConfig\ImporterInterface;
99
use Magento\Framework\App\DeploymentConfig;
10-
use Magento\Framework\Exception\LocalizedException;
10+
use Magento\Deploy\Model\DeploymentConfig\ImportFailedException;
1111
use Psr\Log\LoggerInterface as Logger;
1212
use Magento\Deploy\Model\DeploymentConfig\Validator;
1313
use Magento\Deploy\Model\DeploymentConfig\ImporterPool;
1414
use Magento\Deploy\Model\DeploymentConfig\Hash;
1515
use Symfony\Component\Console\Output\OutputInterface;
16+
use Magento\Deploy\Model\DeploymentConfig\ImporterFactory;
1617

1718
/**
1819
* Runs importing of config data from deployment configuration files.
@@ -47,6 +48,13 @@ class Importer
4748
*/
4849
private $configHash;
4950

51+
/**
52+
* Factory for creation of importer instance.
53+
*
54+
* @var ImporterFactory
55+
*/
56+
private $importerFactory;
57+
5058
/**
5159
* Logger.
5260
*
@@ -57,19 +65,22 @@ class Importer
5765
/**
5866
* @param Validator $configValidator the manager of deployment configuration hash
5967
* @param ImporterPool $configImporterPool the pool of all deployment configuration importers
68+
* @param ImporterFactory $importerFactory the factory for creation of importer instance
6069
* @param DeploymentConfig $deploymentConfig the application deployment configuration
6170
* @param Hash $configHash the hash updater of config data
6271
* @param Logger $logger the logger
6372
*/
6473
public function __construct(
6574
Validator $configValidator,
6675
ImporterPool $configImporterPool,
76+
ImporterFactory $importerFactory,
6777
DeploymentConfig $deploymentConfig,
6878
Hash $configHash,
6979
Logger $logger
7080
) {
7181
$this->configValidator = $configValidator;
7282
$this->configImporterPool = $configImporterPool;
83+
$this->importerFactory = $importerFactory;
7384
$this->deploymentConfig = $deploymentConfig;
7485
$this->configHash = $configHash;
7586
$this->logger = $logger;
@@ -80,7 +91,7 @@ public function __construct(
8091
*
8192
* @param OutputInterface $output the CLI output
8293
* @return void
83-
* @throws LocalizedException is thrown when import has failed
94+
* @throws ImportFailedException is thrown when import has failed
8495
*/
8596
public function import(OutputInterface $output)
8697
{
@@ -95,18 +106,20 @@ public function import(OutputInterface $output)
95106

96107
/**
97108
* @var string $section
98-
* @var ImporterInterface $importer
109+
* @var string $importer
99110
*/
100-
foreach ($importers as $section => $importer) {
111+
foreach ($importers as $section => $importerClassName) {
101112
if (!$this->configValidator->isValid($section)) {
113+
/** @var ImporterInterface $importer */
114+
$importer = $this->importerFactory->create($importerClassName);
102115
$messages = $importer->import($this->deploymentConfig->getConfigData($section));
103116
$output->writeln($messages);
104117
$this->configHash->regenerate($section);
105118
}
106119
}
107-
} catch (LocalizedException $exception) {
120+
} catch (\Exception $exception) {
108121
$this->logger->error($exception);
109-
throw new LocalizedException(__('Import is failed.'), $exception);
122+
throw new ImportFailedException(__('Import is failed. Please, see the log report.'), $exception);
110123
}
111124
}
112125
}

app/code/Magento/Deploy/Console/Command/App/ConfigImportCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
namespace Magento\Deploy\Console\Command\App;
77

8-
use Magento\Framework\Exception\LocalizedException;
8+
use Magento\Deploy\Model\DeploymentConfig\ImportFailedException;
99
use Symfony\Component\Console\Command\Command;
1010
use Symfony\Component\Console\Input\InputInterface;
1111
use Symfony\Component\Console\Output\OutputInterface;
@@ -76,7 +76,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
7676

7777
try {
7878
$this->importer->import($output);
79-
} catch (LocalizedException $e) {
79+
} catch (ImportFailedException $e) {
8080
$output->writeln('<error>' . $e->getMessage() . '</error>');
8181

8282
return Cli::RETURN_FAILURE;

app/code/Magento/Deploy/Model/DeploymentConfig/Hash.php

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
*/
66
namespace Magento\Deploy\Model\DeploymentConfig;
77

8-
use Magento\Framework\Config\File\ConfigFilePool;
9-
use Magento\Framework\App\DeploymentConfig\Writer;
10-
use Magento\Framework\App\DeploymentConfig;
118
use Magento\Framework\Exception\LocalizedException;
12-
use Magento\Framework\Exception\FileSystemException;
9+
use Magento\Framework\Flag\FlagResource;
10+
use Magento\Framework\Flag;
11+
use Magento\Framework\FlagFactory;
1312

1413
/**
1514
* Saves and Retrieves deployment configuration hash.
@@ -22,49 +21,49 @@ class Hash
2221
const CONFIG_KEY = 'config_hash';
2322

2423
/**
25-
* Application deployment configuration.
24+
* Hash generator.
2625
*
27-
* @var DeploymentConfig
26+
* @var Hash\Generator
2827
*/
29-
private $deploymentConfig;
28+
private $configHashGenerator;
3029

3130
/**
32-
* Deployment configuration writer to files.
31+
* Config data collector.
3332
*
34-
* @var Writer
33+
* @var DataCollector
3534
*/
36-
private $writer;
35+
private $dataConfigCollector;
3736

3837
/**
39-
* Hash generator.
38+
* Flag Resource model.
4039
*
41-
* @var Hash\Generator
40+
* @var FlagResource
4241
*/
43-
private $configHashGenerator;
42+
private $flagResource;
4443

4544
/**
46-
* Config data collector.
45+
* Factory class for \Magento\Framework\Flag
4746
*
48-
* @var DataCollector
47+
* @var FlagFactory
4948
*/
50-
private $dataConfigCollector;
49+
private $flagFactory;
5150

5251
/**
53-
* @param DeploymentConfig $deploymentConfig the application deployment configuration
54-
* @param Writer $writer the configuration writer that writes to files
5552
* @param Hash\Generator $configHashGenerator the hash generator
5653
* @param DataCollector $dataConfigCollector the config data collector
54+
* @param FlagResource $flagResource
55+
* @param FlagFactory $flagFactory
5756
*/
5857
public function __construct(
59-
DeploymentConfig $deploymentConfig,
60-
Writer $writer,
6158
Hash\Generator $configHashGenerator,
62-
DataCollector $dataConfigCollector
59+
DataCollector $dataConfigCollector,
60+
FlagResource $flagResource,
61+
FlagFactory $flagFactory
6362
) {
64-
$this->deploymentConfig = $deploymentConfig;
65-
$this->writer = $writer;
6663
$this->configHashGenerator = $configHashGenerator;
6764
$this->dataConfigCollector = $dataConfigCollector;
65+
$this->flagResource = $flagResource;
66+
$this->flagFactory = $flagFactory;
6867
}
6968

7069
/**
@@ -81,14 +80,17 @@ public function regenerate($sectionName = null)
8180
{
8281
try {
8382
$hashes = $this->get();
84-
$configs = $this->dataConfigCollector->getConfig($sectionName ?: null);
83+
$configs = $this->dataConfigCollector->getConfig($sectionName);
8584

8685
foreach ($configs as $section => $config) {
8786
$hashes[$section] = $this->configHashGenerator->generate($config);
8887
}
8988

90-
$this->writer->saveConfig([ConfigFilePool::APP_ENV => [self::CONFIG_KEY => $hashes]]);
91-
} catch (FileSystemException $exception) {
89+
/** @var Flag $flag */
90+
$flag = $this->getFlagObject();
91+
$flag->setFlagData($hashes);
92+
$this->flagResource->save($flag);
93+
} catch (\Exception $exception) {
9294
throw new LocalizedException(__('Hash has not been saved.'), $exception);
9395
}
9496
}
@@ -100,6 +102,24 @@ public function regenerate($sectionName = null)
100102
*/
101103
public function get()
102104
{
103-
return (array) ($this->deploymentConfig->getConfigData(self::CONFIG_KEY) ?: []);
105+
/** @var Flag $flag */
106+
$flag = $this->getFlagObject();
107+
return (array) ($flag->getFlagData() ?: []);
108+
}
109+
110+
/**
111+
* Returns flag object.
112+
*
113+
* We use it for saving hashes of sections in the DB.
114+
*
115+
* @return Flag
116+
*/
117+
private function getFlagObject()
118+
{
119+
/** @var Flag $flag */
120+
$flag = $this->flagFactory
121+
->create(['data' => ['flag_code' => self::CONFIG_KEY]]);
122+
$this->flagResource->load($flag, self::CONFIG_KEY, 'flag_code');
123+
return $flag;
104124
}
105125
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Deploy\Model\DeploymentConfig;
7+
8+
use Magento\Framework\Exception\LocalizedException;
9+
10+
/**
11+
* This exception is thrown when import data from configuration files was failed.
12+
*/
13+
class ImportFailedException extends LocalizedException
14+
{
15+
16+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Deploy\Model\DeploymentConfig;
7+
8+
use Magento\Framework\ObjectManagerInterface;
9+
use Magento\Framework\App\DeploymentConfig\ImporterInterface;
10+
11+
/**
12+
* Factory for importers.
13+
*
14+
* Creates object instance that implements Magento\Framework\App\DeploymentConfig\ImporterInterface interface.
15+
*/
16+
class ImporterFactory
17+
{
18+
/**
19+
* Magento object manager.
20+
*
21+
* @var ObjectManagerInterface
22+
*/
23+
private $objectManager;
24+
25+
/**
26+
* @param ObjectManagerInterface $objectManager the magento object manager
27+
*/
28+
public function __construct(ObjectManagerInterface $objectManager)
29+
{
30+
$this->objectManager = $objectManager;
31+
}
32+
33+
/**
34+
* Creates object instance by class name.
35+
*
36+
* @param string $className the name of class for creation of its object instance
37+
* @param array $data the array with some additional configuration data for creation of object instance
38+
* @return ImporterInterface the created object instance
39+
* @throws \InvalidArgumentException is thrown when object instance does not implement ImporterInterface
40+
*/
41+
public function create($className, array $data = [])
42+
{
43+
$importer = $this->objectManager->create($className, $data);
44+
45+
if (!$importer instanceof ImporterInterface) {
46+
throw new \InvalidArgumentException(
47+
'Type "' . $className . '" is not instance on ' . ImporterInterface::class
48+
);
49+
}
50+
51+
return $importer;
52+
}
53+
}

app/code/Magento/Deploy/Model/DeploymentConfig/ImporterPool.php

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
use Magento\Framework\Exception\ConfigurationMismatchException;
99
use Magento\Framework\ObjectManagerInterface;
10-
use Magento\Framework\App\DeploymentConfig\ImporterInterface;
1110

1211
/**
1312
* Pool of all deployment configuration importers.
@@ -59,11 +58,11 @@ class ImporterPool
5958
private $importers = [];
6059

6160
/**
62-
* The same as $importers, sorted by sortOrder.
61+
*
6362
*
6463
* @var array
6564
*/
66-
private $sortedImporters;
65+
private $sortedImporters = [];
6766

6867
/**
6968
* Magento object manager.
@@ -101,45 +100,37 @@ public function getSections()
101100
}
102101

103102
/**
104-
* Retrieves list of all sections with their importer instances, sorted by sortOrder.
103+
* Retrieves list of all sections with their importer class names, sorted by sortOrder.
105104
*
106105
* E.g.
107106
* ```php
108107
* [
109-
* 'scopes' => SomeScopeImporter(),
108+
* 'scopes' => Magento\Store\Model\StoreImporter,
110109
* ...
111110
* ]
112111
* ```
113112
*
114-
* @return array the list of all sections with their importer instances
115-
* @throws ConfigurationMismatchException is thrown when instance of importer implements a wrong interface
113+
* @return array the list of all sections with their importer class names
114+
* @throws ConfigurationMismatchException is thrown when parameter class is empty
116115
*/
117116
public function getImporters()
118117
{
119-
$result = [];
118+
if (!$this->sortedImporters) {
119+
$sortedImporters = [];
120+
$importers = $this->sort($this->importers);
120121

121-
if (null == $this->sortedImporters) {
122-
$this->sortedImporters = $this->sort($this->importers);
123-
}
122+
foreach ($importers as $section => $importer) {
123+
if (empty($importer['class'])) {
124+
throw new ConfigurationMismatchException(__('Parameter "class" must be present.'));
125+
}
124126

125-
foreach ($this->sortedImporters as $section => $importer) {
126-
if (empty($importer['class'])) {
127-
throw new ConfigurationMismatchException(__('Parameter "class" must be present.'));
127+
$sortedImporters[$section] = $importer['class'];
128128
}
129129

130-
$importerObj = $this->objectManager->get($importer['class']);
131-
if (!$importerObj instanceof ImporterInterface) {
132-
throw new ConfigurationMismatchException(__(
133-
'%1: Instance of %2 is expected, got %3 instead',
134-
$section,
135-
ImporterInterface::class,
136-
get_class($importerObj)
137-
));
138-
}
139-
$result[$section] = $importerObj;
130+
$this->sortedImporters = $sortedImporters;
140131
}
141132

142-
return $result;
133+
return $this->sortedImporters;
143134
}
144135

145136
/**

app/code/Magento/Deploy/Model/DeploymentConfig/Validator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function __construct(
5959
*/
6060
public function isValid($sectionName = null)
6161
{
62-
$configs = $this->dataConfigCollector->getConfig($sectionName ?: null);
62+
$configs = $this->dataConfigCollector->getConfig($sectionName);
6363
$hashes = $this->configHash->get();
6464

6565
foreach ($configs as $section => $config) {

0 commit comments

Comments
 (0)