Passed
Pull Request — main (#557)
by Johan
10:46 queued 05:30
created

ReplayEventsCommand::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 2
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright 2014 SURFnet bv
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\Service\EventStreamReplayer;
22
use Symfony\Component\Console\Attribute\AsCommand;
23
use Symfony\Component\Console\Attribute\Option;
24
use Symfony\Component\Console\Helper\FormatterHelper;
25
use Symfony\Component\Console\Helper\QuestionHelper;
26
use Symfony\Component\Console\Input\InputInterface;
27
use Symfony\Component\Console\Output\OutputInterface;
28
use Symfony\Component\Console\Question\ConfirmationQuestion;
29
30
#[AsCommand(
31
    name: 'middleware:event:replay',
32
    description: 'Wipes all read models and repopulates the tables from the event store. Use the 
33
                --no-interaction option to perform the event replay without the additional confirmation question.'
34
)]
35
class ReplayEventsCommand
36
{
37
    public function __construct(private readonly EventStreamReplayer $replayer, private readonly string $environment)
38
    {
39
    }
40
41
    public function __invoke(
42
        OutputInterface $output,
43
        InputInterface $input,
44
        #[Option(
45
            description: 'The amount of events that are replayed at once (repeated until all events are replayed)',
46
            name: 'increments',
47
            shortcut: 'i'
48
        )
49
        ]
50
        int $increments = 1000,
51
    ): int {
52
        $formatter = new FormatterHelper();
53
54
        // Be careful, when using the no-interaction option you will not get the confirmation question
55
56
        if (!in_array($this->environment, ['dev_event_replay', 'prod_event_replay', 'smoketest_event_replay'])) {
57
            $output->writeln(
58
                $formatter->formatBlock(
59
                    [
60
                        '',
61
                        'This command may only be executed using env "dev_event_replay", "prod_event_replay", or 
62
                    "smoketest_event_replay"',
63
                        '',
64
                    ],
65
                    'error',
66
                ),
67
            );
68
69
            return 1;
70
        }
71
72
        $interrogator = new QuestionHelper();
73
        if ($this->environment === 'prod_event_replay') {
74
            $wantToRunOnProd = new ConfirmationQuestion(
75
                '<question>You have selected to run this on production. Have you disabled all access to the production '
76
                . 'environment? (y/N)</question>',
77
                false,
78
            );
79
80
            if (!$interrogator->ask($input, $output, $wantToRunOnProd)) {
81
                $output->writeln('<comment>Not starting the replay</comment>');
82
83
                return 1;
84
            }
85
        }
86
        if ($increments < 1) {
87
            $output->writeln(
88
                $formatter->formatBlock(
89
                    sprintf('Increments must be a positive integer, "%s" given', $increments),
90
                    'error',
91
                ),
92
            );
93
94
            return 1;
95
        }
96
97
        if ($input->isInteractive()) {
98
            $output->writeln(['', $formatter->formatBlock(['', 'WARNING!!!!', ''], 'error'), '']);
99
100
            $question = <<<QUESTION
101
You are about to WIPE all read data and recreate all data based on the events present, in steps of %d.
102
103
  <%s>>> This can take a while and should not be interrupted <<</%s>
104
105
Are you sure you wish to continue? (y/N)
106
QUESTION;
107
108
            $question = sprintf($question, $increments, 'error', 'error');
109
            $areYouSure = new ConfirmationQuestion(sprintf("<question>%s</question>\n", $question), false);
110
            if (!$interrogator->ask($input, $output, $areYouSure)) {
111
                $output->writeln('<comment>Replay cancelled!</comment>');
112
113
                return 1;
114
            }
115
        }
116
117
        $output->writeln(['', $formatter->formatBlock('Starting Event Replay', 'info')]);
118
        $output->writeln(
119
            $formatter->formatBlock(' >> If it is interrupted it must be rerun till completed', 'comment'),
120
        );
121
122
        $this->replayer->replayEvents($output, $increments);
123
        return 0;
124
    }
125
}
126