1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Copyright 2017 SURFnet B.V. |
5
|
|
|
* |
6
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
7
|
|
|
* you may not use this file except in compliance with the License. |
8
|
|
|
* You may obtain a copy of the License at |
9
|
|
|
* |
10
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0 |
11
|
|
|
* |
12
|
|
|
* Unless required by applicable law or agreed to in writing, software |
13
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, |
14
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15
|
|
|
* See the License for the specific language governing permissions and |
16
|
|
|
* limitations under the License. |
17
|
|
|
*/ |
18
|
|
|
|
19
|
|
|
namespace Surfnet\StepupMiddleware\MiddlewareBundle\Console\Command; |
20
|
|
|
|
21
|
|
|
use Surfnet\StepupMiddleware\MiddlewareBundle\EventSourcing\EventCollection; |
22
|
|
|
use Surfnet\StepupMiddleware\MiddlewareBundle\EventSourcing\ProjectorCollection; |
23
|
|
|
use Surfnet\StepupMiddleware\MiddlewareBundle\Service\PastEventsService; |
24
|
|
|
use Surfnet\StepupMiddleware\MiddlewareBundle\Service\TransactionAwareEventDispatcher; |
25
|
|
|
use Symfony\Component\Console\Command\Command; |
26
|
|
|
use Symfony\Component\Console\Helper\QuestionHelper; |
27
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
28
|
|
|
use Symfony\Component\Console\Input\InputOption; |
29
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
30
|
|
|
use Symfony\Component\Console\Question\ChoiceQuestion; |
31
|
|
|
|
32
|
|
|
class ReplaySpecificEventsCommand extends Command |
33
|
|
|
{ |
34
|
|
|
const OPTION_LIST_EVENTS = 'list-events'; |
35
|
|
|
const OPTION_LIST_PROJECTORS = 'list-projectors'; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @var EventCollection |
39
|
|
|
*/ |
40
|
|
|
private $collection; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @var PastEventsService |
44
|
|
|
*/ |
45
|
|
|
private $pastEventsService; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @var TransactionAwareEventDispatcher |
49
|
|
|
*/ |
50
|
|
|
private $eventDispatcher; |
51
|
|
|
/** |
52
|
|
|
* @var ProjectorCollection |
53
|
|
|
*/ |
54
|
|
|
private $projectorCollection; |
55
|
|
|
|
56
|
|
|
protected function configure() |
57
|
|
|
{ |
58
|
|
|
$this |
59
|
|
|
->setName('stepup:event:replay') |
60
|
|
|
->setDescription('replay specified events for specified projectors') |
61
|
|
|
->addOption( |
62
|
|
|
self::OPTION_LIST_EVENTS, |
63
|
|
|
null, |
64
|
|
|
InputOption::VALUE_NONE, |
65
|
|
|
'List all events available to replay' |
66
|
|
|
) |
67
|
|
|
->addOption( |
68
|
|
|
self::OPTION_LIST_PROJECTORS, |
69
|
|
|
null, |
70
|
|
|
InputOption::VALUE_NONE, |
71
|
|
|
'List all projectors available for which events can be replayed' |
72
|
|
|
); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
public function __construct( |
76
|
|
|
EventCollection $collection, |
77
|
|
|
ProjectorCollection $projectorCollection, |
78
|
|
|
PastEventsService $pastEventsService, |
79
|
|
|
TransactionAwareEventDispatcher $eventDispatcher |
80
|
|
|
) { |
81
|
|
|
$this->collection = $collection; |
82
|
|
|
$this->projectorCollection = $projectorCollection; |
83
|
|
|
$this->pastEventsService = $pastEventsService; |
84
|
|
|
$this->eventDispatcher = $eventDispatcher; |
85
|
|
|
parent::__construct(); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
89
|
|
|
{ |
90
|
|
|
$availableEvents = $this->collection->getEventNames(); |
91
|
|
|
$availableProjectors = $this->projectorCollection->getProjectorNames(); |
92
|
|
|
|
93
|
|
View Code Duplication |
if ($input->getOption(self::OPTION_LIST_EVENTS)) { |
|
|
|
|
94
|
|
|
$output->writeln('<info>The following events can be replayed:</info>'); |
95
|
|
|
$output->writeln(!empty($availableEvents) ? $availableEvents : 'None.'); |
|
|
|
|
96
|
|
|
|
97
|
|
|
return; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
View Code Duplication |
if ($input->getOption(self::OPTION_LIST_PROJECTORS)) { |
|
|
|
|
101
|
|
|
$output->writeln('<info>Events can be replayed for the following projectors:</info>'); |
102
|
|
|
$output->writeln(!empty($availableProjectors) ? $availableProjectors : 'None.'); |
|
|
|
|
103
|
|
|
|
104
|
|
|
return; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
if (count($availableProjectors) === 0) { |
108
|
|
|
$output->writeln('<error>There are no projectors configured to reply events for</error>'); |
109
|
|
|
|
110
|
|
|
return; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** @var QuestionHelper $questionHelper */ |
114
|
|
|
$questionHelper = $this->getHelper('question'); |
115
|
|
|
|
116
|
|
|
$selectEventsQuestion = new ChoiceQuestion( |
117
|
|
|
'Which events would you like to replay? Please supply a comma-separated list of numbers.', |
118
|
|
|
$availableEvents |
119
|
|
|
); |
120
|
|
|
$selectEventsQuestion->setMultiselect(true); |
121
|
|
|
|
122
|
|
|
$chosenEvents = $questionHelper->ask($input, $output, $selectEventsQuestion); |
123
|
|
|
$eventSelection = $this->collection->select($chosenEvents); |
124
|
|
|
|
125
|
|
|
$selectProjectorsQuestion = new ChoiceQuestion( |
126
|
|
|
'For which projectors would you like to replay the selected events? ' |
127
|
|
|
. 'Please supply a comma-separated list of numbers.', |
128
|
|
|
$availableProjectors |
129
|
|
|
); |
130
|
|
|
$selectProjectorsQuestion->setMultiselect(true); |
131
|
|
|
|
132
|
|
|
$chosenProjectors = $questionHelper->ask($input, $output, $selectProjectorsQuestion); |
133
|
|
|
$projectorSelection = $this->projectorCollection->selectByNames($chosenProjectors); |
134
|
|
|
|
135
|
|
|
$events = $this->pastEventsService->findEventsBy($eventSelection); |
136
|
|
|
|
137
|
|
|
$output->writeln('<info>Registering projectors</info>'); |
138
|
|
|
foreach ($projectorSelection as $projector) { |
139
|
|
|
$this->eventDispatcher->registerProjector($projector); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
$output->writeln('<info>Dispatching events</info>'); |
143
|
|
|
$this->eventDispatcher->dispatch($events); |
|
|
|
|
144
|
|
|
} |
145
|
|
|
} |
146
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.