Commit 83282366 authored by Roman Ondráček's avatar Roman Ondráček

Config: fix scheduler configuration migration

Signed-off-by: Roman Ondráček's avatarRoman Ondráček <ondracek.roman@centrum.cz>
parent 45acbaf9
Pipeline #2110 passed with stages
in 16 minutes and 3 seconds
......@@ -82,6 +82,9 @@ class SchedulerDataGridFactory {
$grid->addToolbarButton('import', 'config.actions.Import')
->setIcon('arrow-up')
->setClass('btn btn-xs btn-primary');
$grid->addToolbarButton('export', 'config.actions.Export')
->setIcon('arrow-down')
->setClass('btn btn-xs btn-default');
return $grid;
}
......
......@@ -20,10 +20,13 @@ declare(strict_types = 1);
namespace App\ConfigModule\Forms;
use App\ConfigModule\Exceptions\InvalidConfigurationFormatException;
use App\ConfigModule\Models\SchedulerManager;
use App\ConfigModule\Models\SchedulerMigrationManager;
use App\ConfigModule\Presenters\SchedulerPresenter;
use App\CoreModule\Exceptions\NonExistingJsonSchemaException;
use App\CoreModule\Forms\FormFactory;
use App\ServiceModule\Exceptions\NotSupportedInitSystemException;
use Nette\Application\UI\Form;
use Nette\Http\FileUpload;
use Nette\IOException;
......@@ -38,11 +41,6 @@ class SchedulerImportFormFactory {
use SmartObject;
/**
* @var SchedulerManager Scheduler manager
*/
private $manager;
/**
* @var FormFactory Generic form factory
*/
......@@ -53,6 +51,16 @@ class SchedulerImportFormFactory {
*/
private $presenter;
/**
* @var SchedulerManager Scheduler manager
*/
private $manager;
/**
* @var SchedulerMigrationManager Scheduler migration manager
*/
private $migrationManager;
/**
* Translator prefix
*/
......@@ -62,10 +70,12 @@ class SchedulerImportFormFactory {
* Constructor
* @param FormFactory $factory Generic form factory
* @param SchedulerManager $manager Scheduler manager
* @param SchedulerMigrationManager $migrationManager Scheduler migration manager
*/
public function __construct(FormFactory $factory, SchedulerManager $manager) {
$this->manager = $manager;
public function __construct(FormFactory $factory, SchedulerManager $manager, SchedulerMigrationManager $migrationManager) {
$this->factory = $factory;
$this->manager = $manager;
$this->migrationManager = $migrationManager;
}
/**
......@@ -78,21 +88,37 @@ class SchedulerImportFormFactory {
$form = $this->factory->create(self::TRANSLATOR_PREFIX);
$form->addUpload('file', 'file')
->setRequired('messages.file')
->setHtmlAttribute('accept', 'application/json');
->setHtmlAttribute('accept', 'application/json,application/zip');
$form->addSubmit('import', 'import');
$form->addProtection('core.errors.form-timeout');
$form->onSuccess[] = [$this, 'import'];
return $form;
}
/**
* Imports a file
* @param Form $form Scheduler configuration import form
*/
public function import(Form $form): void {
$values = $form->getValues('array');
/**
* @var FileUpload $file JSON file
*/
$file = $values['file'];
$file = $form->getValues()->file;
if ($file->getContentType() === 'application/json') {
$this->importJson($form, $file);
} elseif ($file->getContentType() === 'application/zip') {
$this->importZip($form, $file);
}
}
/**
* Imports JSON file with task configuration
* @param Form $form Scheduler configuration import form
* @param FileUpload $file JSON file with task configuration
*/
private function importJson(Form $form, FileUpload $file): void {
try {
$json = Json::decode($file->getContents(), Json::FORCE_ARRAY);
$json = Json::decode($file->getContents());
} catch (JsonException $e) {
$form['file']->addError('messages.invalidFile');
$this->presenter->flashError(self::TRANSLATOR_PREFIX . '.messages.invalidFile');
......@@ -101,6 +127,7 @@ class SchedulerImportFormFactory {
try {
$this->manager->save($json);
$this->presenter->flashSuccess(self::TRANSLATOR_PREFIX . '.messages.success');
$this->presenter->redirect('Scheduler:default');
} catch (NonExistingJsonSchemaException $e) {
$this->presenter->flashError('config.messages.writeFailures.nonExistingJsonSchema');
} catch (IOException $e) {
......@@ -108,7 +135,28 @@ class SchedulerImportFormFactory {
} catch (JsonException $e) {
$this->presenter->flashError('config.messages.writeFailures.invalidJson');
}
$this->presenter->redirect('Scheduler:default');
}
/**
* Imports ZIP archive with scheduler configuration
* @param Form $form Scheduler configuration import form
* @param FileUpload $file ZIP archive with scheduler configuration
*/
private function importZip(Form $form, FileUpload $file): void {
try {
$this->migrationManager->upload($file);
$this->presenter->flashSuccess('config.migration.messages.importedConfig');
$this->presenter->redirect('Scheduler:default');
} catch (InvalidConfigurationFormatException $e) {
$this->presenter->flashError('config.migration.errors.invalidFormat');
} catch (NonExistingJsonSchemaException $e) {
$this->presenter->flashError('config.messages.writeFailures.nonExistingJsonSchema');
} catch (NotSupportedInitSystemException $e) {
$this->presenter->flashError('service.errors.unsupportedInit');
} catch (IOException $e) {
/// TODO: Use custom error message.
$this->presenter->flashError('config.messages.writeFailures.ioError');
}
}
}
<?php
/**
* Copyright 2017 MICRORISC s.r.o.
* Copyright 2017-2019 IQRF Tech s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
declare(strict_types = 1);
namespace App\ConfigModule\Forms;
use App\ConfigModule\Exceptions\InvalidConfigurationFormatException;
use App\ConfigModule\Models\SchedulerMigrationManager;
use App\ConfigModule\Presenters\MigrationPresenter;
use App\CoreModule\Exceptions\NonExistingJsonSchemaException;
use App\CoreModule\Forms\FormFactory;
use App\ServiceModule\Exceptions\NotSupportedInitSystemException;
use Nette\Application\UI\Form;
use Nette\Forms\Controls\SubmitButton;
use Nette\IOException;
use Nette\SmartObject;
/**
* Scheduler's configuration migration form factory
*/
class SchedulerMigrationFormFactory {
use SmartObject;
/**
* @var SchedulerMigrationManager Scheduler's configuration migration manager
*/
private $manager;
/**
* @var FormFactory Generic form factory
*/
private $factory;
/**
* @var MigrationPresenter Configuration migration presenter
*/
private $presenter;
/**
* Constructor
* @param FormFactory $factory Generic form factory
* @param SchedulerMigrationManager $manager Scheduler's configuration migration manager
*/
public function __construct(FormFactory $factory, SchedulerMigrationManager $manager) {
$this->factory = $factory;
$this->manager = $manager;
}
/**
* Creates the configuration migration form
* @param MigrationPresenter $presenter Configuration migration presenter
* @return Form Configuration migration form
*/
public function create(MigrationPresenter $presenter): Form {
$this->presenter = $presenter;
$form = $this->factory->create('config.schedulerMigration');
$form->addUpload('configuration', 'configuration')
->setRequired('messages.configuration')
->setHtmlAttribute('accept', '.zip');
$form->addSubmit('import', 'import')
->onClick[] = [$this, 'import'];
$form->addSubmit('export', 'export')
->setValidationScope([])
->onClick[] = [$this, 'export'];
$form->addProtection('core.errors.form-timeout');
return $form;
}
/**
* Imports the scheduler's configuration
* @param SubmitButton $button Scheduler's configuration import button
*/
public function import(SubmitButton $button): void {
try {
$this->manager->upload($button->getForm()->getValues('array'));
$this->presenter->flashSuccess('config.migration.messages.importedConfig');
} catch (InvalidConfigurationFormatException $e) {
$this->presenter->flashError('config.migration.errors.invalidFormat');
} catch (NonExistingJsonSchemaException $e) {
$this->presenter->flashError('config.messages.writeFailures.nonExistingJsonSchema');
} catch (NotSupportedInitSystemException $e) {
$this->presenter->flashError('service.errors.unsupportedInit');
} catch (IOException $e) {
/// TODO: Use custom error message.
$this->presenter->flashError('config.messages.writeFailures.ioError');
} finally {
$this->presenter->redirect('Homepage:default');
}
}
/**
* Exports the configuration
*/
public function export(): void {
$this->presenter->redirect('Migration:schedulerExport');
}
}
......@@ -27,6 +27,7 @@ use App\ServiceModule\Models\ServiceManager;
use DateTime;
use Nette\Application\BadRequestException;
use Nette\Application\Responses\FileResponse;
use Nette\Http\FileUpload;
use Nette\IOException;
use Nette\SmartObject;
use Nette\Utils\FileSystem;
......@@ -94,12 +95,11 @@ class SchedulerMigrationManager {
/**
* Uploads a configuration
* @param mixed[] $formValues Values from form
* @param FileUpload $zip ZIP archive with scheduler configuration
* @throws InvalidConfigurationFormatException
* @throws NotSupportedInitSystemException
*/
public function upload(array $formValues): void {
$zip = $formValues['configuration'];
public function upload(FileUpload $zip): void {
if (!$zip->isOk()) {
throw new InvalidConfigurationFormatException();
}
......
......@@ -21,9 +21,7 @@ declare(strict_types = 1);
namespace App\ConfigModule\Presenters;
use App\ConfigModule\Forms\MigrationFormFactory;
use App\ConfigModule\Forms\SchedulerMigrationFormFactory;
use App\ConfigModule\Models\MigrationManager;
use App\ConfigModule\Models\SchedulerMigrationManager;
use App\CoreModule\Presenters\ProtectedPresenter;
use App\CoreModule\Traits\TPresenterFlashMessage;
use Nette\Application\BadRequestException;
......@@ -42,30 +40,17 @@ class MigrationPresenter extends ProtectedPresenter {
*/
public $formFactory;
/**
* @var SchedulerMigrationFormFactory Scheduler's configuration import form factory
* @inject
*/
public $schedulerFormFactory;
/**
* @var MigrationManager Configuration migration manager
*/
private $manager;
/**
* @var SchedulerMigrationManager Scheduler's configuration migration manager
*/
private $schedulerManager;
/**
* Constructor
* @param MigrationManager $manager Configuration migration manager
* @param SchedulerMigrationManager $schedulerManager Scheduler's configuration migration manager
*/
public function __construct(MigrationManager $manager, SchedulerMigrationManager $schedulerManager) {
public function __construct(MigrationManager $manager) {
$this->manager = $manager;
$this->schedulerManager = $schedulerManager;
parent::__construct();
}
......@@ -81,18 +66,6 @@ class MigrationPresenter extends ProtectedPresenter {
}
}
/**
* Exports a scheduler's configuration action
*/
public function actionSchedulerExport(): void {
try {
$this->sendResponse($this->schedulerManager->download());
} catch (BadRequestException $e) {
$this->flashError('config.schedulerMigration.errors.readConfig');
$this->redirect('Migration:default');
}
}
/**
* Creates the configuration import form
* @return Form Configuration import form
......@@ -101,12 +74,4 @@ class MigrationPresenter extends ProtectedPresenter {
return $this->formFactory->create($this);
}
/**
* Creates the scheduler's configuration import form
* @return Form Scheduler's configuration import form
*/
protected function createComponentConfigSchedulerImportForm(): Form {
return $this->schedulerFormFactory->create($this);
}
}
......@@ -24,8 +24,10 @@ use App\ConfigModule\Datagrids\SchedulerDataGridFactory;
use App\ConfigModule\Forms\SchedulerFormFactory;
use App\ConfigModule\Forms\SchedulerImportFormFactory;
use App\ConfigModule\Models\SchedulerManager;
use App\ConfigModule\Models\SchedulerMigrationManager;
use App\CoreModule\Presenters\ProtectedPresenter;
use App\CoreModule\Traits\TPresenterFlashMessage;
use Nette\Application\BadRequestException;
use Nette\Application\UI\Form;
use Nette\IOException;
use Nette\Utils\JsonException;
......@@ -58,16 +60,23 @@ class SchedulerPresenter extends ProtectedPresenter {
public $importFormFactory;
/**
* @var SchedulerManager Scheduler's task manager
* @var SchedulerManager Scheduler's configuration manager
*/
private $configManager;
private $manager;
/**
* @var SchedulerMigrationManager Scheduler's migration manager
*/
private $migrationManager;
/**
* Constructor
* @param SchedulerManager $configManager Scheduler's task manager
* @param SchedulerManager $manager Scheduler's configuration manager
* @param SchedulerMigrationManager $migrationManager Scheduler's migration manager
*/
public function __construct(SchedulerManager $configManager) {
$this->configManager = $configManager;
public function __construct(SchedulerManager $manager, SchedulerMigrationManager $migrationManager) {
$this->manager = $manager;
$this->migrationManager = $migrationManager;
parent::__construct();
}
......@@ -76,7 +85,7 @@ class SchedulerPresenter extends ProtectedPresenter {
*/
public function renderDefault(): void {
try {
$this->template->tasks = $this->configManager->list();
$this->template->tasks = $this->manager->list();
} catch (IOException $e) {
$this->flashError('config.messages.readFailures.ioError');
$this->redirect('Homepage:default');
......@@ -100,7 +109,7 @@ class SchedulerPresenter extends ProtectedPresenter {
*/
public function actionDelete(int $id): void {
try {
$this->configManager->delete($id);
$this->manager->delete($id);
$this->flashSuccess('config.messages.successes.delete');
} catch (IOException $e) {
$this->flashError('config.messages.writeFailures.ioError');
......@@ -110,6 +119,18 @@ class SchedulerPresenter extends ProtectedPresenter {
$this->redirect('Scheduler:default');
}
/**
* Exports a scheduler's configuration action
*/
public function actionExport(): void {
try {
$this->sendResponse($this->migrationManager->download());
} catch (BadRequestException $e) {
$this->flashError('config.schedulerMigration.errors.readConfig');
$this->redirect('Scheduler:default');
}
}
/**
* Creates the scheduler's tasks data grid
* @param string $name Data grid's component name
......
......@@ -17,7 +17,6 @@ services:
- App\ConfigModule\Forms\OtaUploadFormFactory
- App\ConfigModule\Forms\SchedulerFormFactory
- App\ConfigModule\Forms\SchedulerImportFormFactory
- App\ConfigModule\Forms\SchedulerMigrationFormFactory
- App\ConfigModule\Forms\TraceFileFormFactory
- App\ConfigModule\Forms\UdpFormFactory
- App\ConfigModule\Forms\WebSocketFormFactory
......
......@@ -22,8 +22,3 @@
{control configImportForm}
</div>
</div>
<div class='panel panel-default'>
<div class='panel-body'>
{control configSchedulerImportForm}
</div>
</div>
......@@ -4,6 +4,7 @@ description: Edit configuration.
actions:
Add: Add
Edit: Edit
Export: Export
Import: Import
Remove: Remove
......@@ -268,10 +269,10 @@ scheduler:
file: JSON Task file
import: Import
messages:
invalidFormat: The uploaded file is not JSON file.
invalidFormat: The uploaded file is not JSON file or ZIP archive.
invalidFile: The uploaded file is invalid.
file: Please select the file to import.
success: The task has been imported successfully.
success: The tasks has been imported successfully.
edit: Edit task
form:
id: ID
......@@ -291,6 +292,7 @@ scheduler:
remove: Remove task
messaging: Messaging
message: Message
mType: Message types
msgId: Message ID
returnVerbose: Enable verbose response
messages:
......
......@@ -111,10 +111,9 @@ class SchedulerMigrationManagerTest extends TestCase {
/**
* Mock an uploaded configuration
* @return FileUpload[] Mocked form values
* @return FileUpload Mocked file upload
*/
private function mockUploadedArchive(): array {
$values = [];
private function mockUploadedArchive(): FileUpload {
$file = [
'name' => 'iqrf-gateway-scheduler.zip',
'type' => 'application/zip',
......@@ -122,8 +121,7 @@ class SchedulerMigrationManagerTest extends TestCase {
'error' => UPLOAD_ERR_OK,
'size' => filesize($this->tempPath),
];
$values['configuration'] = new FileUpload($file);
return $values;
return new FileUpload($file);
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment