Completed
Push — master ( 84281b...d54de7 )
by Nils
02:31
created

LeankoalaReporter   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 259
Duplicated Lines 8.49 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 9
Bugs 0 Features 2
Metric Value
wmc 35
c 9
b 0
f 2
lcom 1
cbo 14
dl 22
loc 259
rs 9

10 Methods

Rating   Name   Duplication   Size   Complexity  
B init() 0 30 3
A setResponseRetriever() 0 4 1
A processResults() 0 4 1
A finish() 0 8 2
A getComponent() 0 7 1
C sendCollectedResults() 0 53 11
B sendSingleResults() 0 53 8
A getIdentifier() 0 10 2
A getPrefix() 0 4 1
B send() 22 22 5

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace whm\Smoke\Extensions\SmokeReporter\Reporter;
4
5
use Koalamon\Client\Reporter\Event;
6
use Koalamon\Client\Reporter\Event\Attribute;
7
use Koalamon\Client\Reporter\Event\Processor\MongoDBProcessor;
8
use Koalamon\Client\Reporter\KoalamonException;
9
use Koalamon\Client\Reporter\Reporter as KoalaReporter;
10
use phm\HttpWebdriverClient\Http\Response\TimeoutAwareResponse;
11
use Psr\Http\Message\ResponseInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use whm\Smoke\Config\Configuration;
14
use whm\Smoke\Extensions\Leankoala\LeankoalaExtension;
15
use whm\Smoke\Extensions\SmokeResponseRetriever\Retriever\Retriever;
16
use whm\Smoke\Rules\CheckResult;
17
use whm\Smoke\Scanner\Result;
18
19
/**
20
 * Class XUnitReporter.
21
 */
22
class LeankoalaReporter implements Reporter
23
{
24
    /**
25
     * @var Result[]
26
     */
27
    private $results = [];
28
29
    /**
30
     * @var Configuration
31
     */
32
    private $config;
33
    private $system;
34
    private $collect;
35
    private $identifier;
36
    private $systemUseRetriever;
37
    private $tool = 'smoke';
38
    private $groupBy;
39
    private $server;
40
    private $addComingFrom;
41
    private $useUrlAsIdentifier;
42
43
    /**
44
     * @var KoalaReporter
45
     */
46
    private $reporter;
47
48
    /**
49
     * @var Retriever
50
     */
51
    private $retriever;
52
53
    /**
54
     * @var OutputInterface
55
     */
56
    private $output;
57
58
    /**
59
     * @var LeankoalaExtension
60
     */
61
    private $leankoalaExtension;
62
63
    const STATUS_SUCCESS = 'success';
64
    const STATUS_FAILURE = 'failure';
65
66
    public function init($apiKey, Configuration $_configuration, OutputInterface $_output, $server = 'https://webhook.koalamon.com', $system = '', $identifier = '', $tool = '', $collect = true, $systemUseRetriever = false, $groupBy = false, $addComingFrom = true, $useMongo = true, $useUrlAsIdentifier = false)
67
    {
68
        $httpClient = new \GuzzleHttp\Client();
69
70
        $this->reporter = new KoalaReporter('', $apiKey, $httpClient, $server);
71
72
        if ($useMongo) {
73
            $this->reporter->setEventProcessor(MongoDBProcessor::createByEnvironmentVars('leankoala'));
74
        }
75
76
        $this->config = $_configuration;
77
        $this->systemUseRetriever = $systemUseRetriever;
78
79
        $this->system = $system;
80
        $this->collect = $collect;
81
        $this->identifier = $identifier;
82
        $this->useUrlAsIdentifier = $useUrlAsIdentifier;
83
        $this->groupBy = $groupBy;
84
85
        $this->addComingFrom = $addComingFrom;
86
87
        if ($tool) {
88
            $this->tool = $tool;
89
        }
90
91
        $this->leankoalaExtension = $_configuration->getExtension('Leankoala');
92
93
        $this->server = $server;
94
        $this->output = $_output;
95
    }
96
97
    public function setResponseRetriever(Retriever $retriever)
98
    {
99
        $this->retriever = $retriever;
100
    }
101
102
    public function processResults($results)
103
    {
104
        $this->results[] = $results;
105
    }
106
107
    public function finish()
108
    {
109
        if ($this->collect) {
110
            $this->sendCollectedResults();
111
        } else {
112
            $this->sendSingleResults();
113
        }
114
    }
115
116
    private function getComponent($ruleName)
117
    {
118
        $ruleArray = explode('_', $ruleName);
119
        $component = array_pop($ruleArray);
120
121
        return $component;
122
    }
123
124
    private function sendCollectedResults()
125
    {
126
        $checks = [];
127
128
        foreach ($this->results as $results) {
129
            foreach ($results as $result) {
0 ignored issues
show
Bug introduced by
The expression $results of type object<whm\Smoke\Scanner\Result> is not traversable.
Loading history...
130
                /* @var CheckResult $result */
131
                $tool = 'Smoke' . $result->getRuleName();
132
                $checks[$tool][] = $result;
133
            }
134
        }
135
136
        foreach ($checks as $toolName => $results) {
137
            $attributes = array();
138
139
            if (count($results) === 0) {
140
                continue;
141
            }
142
143
            $message = 'The smoke test for #system_name# failed (Rule: ' . $toolName . ').<ul>';
144
            $status = Event::STATUS_SUCCESS;
145
            $failureCount = 0;
146
            $identifier = $toolName . '_' . $this->system;
147
148
            foreach ($results as $result) {
149
                /** @var CheckResult $result */
150
                if ($result->getStatus() === CheckResult::STATUS_FAILURE) {
151
                    $comingFrom = '';
152
                    if ($this->addComingFrom && $this->retriever->getComingFrom($result->getResponse()->getUri())) {
153
                        $comingFrom = ', coming from: ' . $this->retriever->getComingFrom($result->getResponse()->getUri());
154
                    }
155
                    $message .= '<li>' . $result->getMessage() . ' (url: ' . (string)$result->getResponse()->getUri() . $comingFrom . ')</li>';
156
                    ++$failureCount;
157
                }
158
            }
159
            if ($failureCount > 0) {
160
                $status = Event::STATUS_FAILURE;
161
                $message .= '</ul>';
162
                $firstResult = array_pop($results);
163
                $response = $firstResult->getResponse();
164
                /** @var ResponseInterface $response */
165
166
                $attributes[] = new Attribute('html-content', (string)$response->getBody(), true);
167
                if ($response instanceof TimeoutAwareResponse) {
0 ignored issues
show
Bug introduced by
The class phm\HttpWebdriverClient\...se\TimeoutAwareResponse does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
168
                    $attributes[] = new Attribute('timeout', $response->isTimeout());
169
                }
170
            } else {
171
                $message = 'All checks for system "#system_name#" succeeded [SmokeBasic:' . $toolName . '].';
172
            }
173
174
            $this->send($identifier, $this->system, $message, $status, $failureCount, $this->tool, $this->system, $attributes);
175
        }
176
    }
177
178
    private function sendSingleResults()
179
    {
180
        foreach ($this->results as $results) {
181
            foreach ($results as $result) {
0 ignored issues
show
Bug introduced by
The expression $results of type object<whm\Smoke\Scanner\Result> is not traversable.
Loading history...
182
                /* @var CheckResult $result */
183
184
                $identifier = '_' . $this->getIdentifier($result);
185
                $tool = $this->getPrefix($result->getRuleName());
186
187
                $component = $this->getComponent($result->getRuleName());
188
                $system = $this->leankoalaExtension->getSystem($component);
189
190
                $attributes = array();
191
                if ($result->getStatus() == CheckResult::STATUS_FAILURE) {
192
                    $body = (string)$result->getResponse()->getBody();
193
                    if ($body == "") {
194
                        $attributes[] = new Attribute('html content', '<empty>');
195
                    } else {
196
                        $attributes[] = new Attribute('html content', $body, true);
197
                    }
198
                    $attributes[] = new Attribute('http header', json_encode($result->getResponse()->getHeaders()), true);
199
                    $attributes[] = new Attribute('http status code', $result->getResponse()->getStatusCode());
200
201
                    if ($result->getResponse() instanceof TimeoutAwareResponse) {
0 ignored issues
show
Bug introduced by
The class phm\HttpWebdriverClient\...se\TimeoutAwareResponse does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
202
                        $attributes[] = new Attribute('timeout', $result->getResponse()->isTimeout());
203
                    }
204
                }
205
206
                $checkResultAttributes = $result->getAttributes();
207
                foreach ($checkResultAttributes as $checkResultAttribute) {
208
                    $attributes[] = new Attribute($checkResultAttribute->getKey(), $checkResultAttribute->getValue(), $checkResultAttribute->isIsStorable());
209
                }
210
211
                if ($this->system) {
212
                    $currentSystem = $this->system;
213
                } else {
214
                    $currentSystem = $system;
215
                }
216
217
                $this->send(
218
                    $identifier,
219
                    $currentSystem,
220
                    $result->getMessage() . ' (url: ' . (string)$result->getResponse()->getUri() . ')',
221
                    $result->getStatus(),
222
                    $result->getValue(),
223
                    $tool,
224
                    $component,
225
                    $attributes,
226
                    $result->getUrl()
227
                );
228
            }
229
        }
230
    }
231
232
    private function getIdentifier(CheckResult $result)
233
    {
234
        if ($this->useUrlAsIdentifier) {
235
            $suffix = '_' . md5((string)$result->getResponse()->getUri());
236
        } else {
237
            $suffix = '';
238
        }
239
240
        return $this->tool . '_' . $result->getRuleName() . $suffix;
241
    }
242
243
    private function getPrefix($string)
244
    {
245
        return substr($string, 0, strpos($string, '_'));
246
    }
247
248
    /**
249
     * @param $identifier
250
     * @param $system
251
     * @param $message
252
     * @param $status
253
     * @param $value
254
     * @param $tool
255
     * @param $component
256
     * @param Attribute[] $attributes
257
     */
258 View Code Duplication
    private function send($identifier, $system, $message, $status, $value, $tool, $component, $attributes = [], $url = "")
259
    {
260
        if ($status !== CheckResult::STATUS_NONE) {
261
            $event = new Event($identifier, $system, $status, $tool, $message, $value, $url, $component);
262
            $event->addAttribute(new Attribute('_config', json_encode($this->config->getConfigArray()), true));
263
264
            foreach ($attributes as $attribute) {
265
                $event->addAttribute($attribute);
266
            }
267
268
            try {
269
                $this->reporter->sendEvent($event);
270
            } catch (KoalamonException $e) {
271
                $this->output->writeln("\n  <error> Error sending result to leankoala. </error>");
272
                $this->output->writeln('   Url: ' . $e->getUrl());
273
                $this->output->writeln('   Payload: ' . $e->getPayload());
274
                $this->output->writeln("");
275
            } catch (\Exception $e) {
276
                $this->output->writeln($e->getMessage());
277
            }
278
        }
279
    }
280
}
281