|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* @package: chapi |
|
4
|
|
|
* |
|
5
|
|
|
* @author: msiebeneicher |
|
6
|
|
|
* @since: 2015-07-29 |
|
7
|
|
|
* |
|
8
|
|
|
*/ |
|
9
|
|
|
|
|
10
|
|
|
namespace Chapi\BusinessCase\Comparison; |
|
11
|
|
|
|
|
12
|
|
|
use Chapi\Component\Comparison\DiffCompareInterface; |
|
13
|
|
|
use Chapi\Component\DatePeriod\DatePeriodFactoryInterface; |
|
14
|
|
|
use Chapi\Entity\Chronos\JobCollection; |
|
15
|
|
|
use Chapi\Entity\Chronos\JobEntity; |
|
16
|
|
|
use Chapi\Service\JobRepository\JobRepositoryInterface; |
|
17
|
|
|
use Psr\Log\LoggerInterface; |
|
18
|
|
|
|
|
19
|
|
|
class JobComparisonBusinessCase implements JobComparisonInterface |
|
20
|
|
|
{ |
|
21
|
|
|
/** |
|
22
|
|
|
* @var JobRepositoryInterface |
|
23
|
|
|
*/ |
|
24
|
|
|
private $oJobRepositoryLocal; |
|
25
|
|
|
|
|
26
|
|
|
/** |
|
27
|
|
|
* @var JobRepositoryInterface |
|
28
|
|
|
*/ |
|
29
|
|
|
private $oJobRepositoryChronos; |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* @var DiffCompareInterface |
|
33
|
|
|
*/ |
|
34
|
|
|
private $oDiffCompare; |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* @var DatePeriodFactoryInterface |
|
38
|
|
|
*/ |
|
39
|
|
|
private $oDatePeriodFactory; |
|
40
|
|
|
|
|
41
|
|
|
/** |
|
42
|
|
|
* @var LoggerInterface |
|
43
|
|
|
*/ |
|
44
|
|
|
private $oLogger; |
|
45
|
|
|
|
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* @param JobRepositoryInterface $oJobRepositoryLocal |
|
49
|
|
|
* @param JobRepositoryInterface $oJobRepositoryChronos |
|
50
|
|
|
* @param DiffCompareInterface $oDiffCompare |
|
51
|
|
|
* @param DatePeriodFactoryInterface $oDatePeriodFactory |
|
52
|
|
|
* @param LoggerInterface $oLogger |
|
53
|
|
|
*/ |
|
54
|
5 |
|
public function __construct( |
|
55
|
|
|
JobRepositoryInterface $oJobRepositoryLocal, |
|
56
|
|
|
JobRepositoryInterface $oJobRepositoryChronos, |
|
57
|
|
|
DiffCompareInterface $oDiffCompare, |
|
58
|
|
|
DatePeriodFactoryInterface $oDatePeriodFactory, |
|
59
|
|
|
LoggerInterface $oLogger |
|
60
|
|
|
) |
|
61
|
|
|
{ |
|
62
|
5 |
|
$this->oJobRepositoryLocal = $oJobRepositoryLocal; |
|
63
|
5 |
|
$this->oJobRepositoryChronos = $oJobRepositoryChronos; |
|
64
|
5 |
|
$this->oDiffCompare = $oDiffCompare; |
|
65
|
5 |
|
$this->oDatePeriodFactory = $oDatePeriodFactory; |
|
66
|
5 |
|
$this->oLogger = $oLogger; |
|
67
|
5 |
|
} |
|
68
|
|
|
|
|
69
|
|
|
/** |
|
70
|
|
|
* @return string[] |
|
|
|
|
|
|
71
|
|
|
*/ |
|
72
|
|
|
public function getLocalMissingJobs() |
|
73
|
|
|
{ |
|
74
|
|
|
return $this->getMissingJobsInCollectionA( |
|
75
|
|
|
$this->oJobRepositoryLocal->getJobs(), |
|
76
|
|
|
$this->oJobRepositoryChronos->getJobs() |
|
77
|
|
|
); |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
/** |
|
81
|
|
|
* @return string[] |
|
|
|
|
|
|
82
|
|
|
*/ |
|
83
|
|
|
public function getChronosMissingJobs() |
|
84
|
|
|
{ |
|
85
|
|
|
return $this->getMissingJobsInCollectionA( |
|
86
|
|
|
$this->oJobRepositoryChronos->getJobs(), |
|
87
|
|
|
$this->oJobRepositoryLocal->getJobs() |
|
88
|
|
|
); |
|
89
|
|
|
} |
|
90
|
|
|
|
|
91
|
|
|
/** |
|
92
|
|
|
* @return string[] |
|
93
|
|
|
*/ |
|
94
|
3 |
|
public function getLocalJobUpdates() |
|
95
|
|
|
{ |
|
96
|
3 |
|
$_aJobsLocal = $this->oJobRepositoryLocal->getJobs(); |
|
97
|
3 |
|
$_aLocalJobUpdates = []; |
|
98
|
|
|
|
|
99
|
|
|
/** @var JobEntity $_oJobEntity */ |
|
100
|
3 |
|
foreach ($_aJobsLocal as $_oJobEntityLocal) |
|
101
|
|
|
{ |
|
102
|
3 |
|
$_oJobEntityChronos = $this->oJobRepositoryChronos->getJob($_oJobEntityLocal->name); |
|
103
|
|
|
|
|
104
|
|
|
// if job already exist in chronos (not new or deleted in chronos) |
|
105
|
3 |
|
if (!empty($_oJobEntityChronos->name)) |
|
106
|
3 |
|
{ |
|
107
|
3 |
|
$_aNonidenticalProperties = $this->compareJobEntities($_oJobEntityLocal, $_oJobEntityChronos); |
|
108
|
3 |
|
if (!empty($_aNonidenticalProperties)) |
|
109
|
3 |
|
{ |
|
110
|
3 |
|
$_aLocalJobUpdates[] = $_oJobEntityLocal->name; |
|
111
|
3 |
|
} |
|
112
|
3 |
|
} |
|
113
|
3 |
|
} |
|
114
|
|
|
|
|
115
|
3 |
|
return $_aLocalJobUpdates; |
|
116
|
|
|
} |
|
117
|
|
|
|
|
118
|
|
|
/** |
|
119
|
|
|
* @param string $sJobName |
|
120
|
|
|
* @return string[] |
|
121
|
|
|
*/ |
|
122
|
|
|
public function getJobDiff($sJobName) |
|
123
|
|
|
{ |
|
124
|
|
|
$_aReturn = []; |
|
125
|
|
|
|
|
126
|
|
|
$_oJobEntityLocal = $this->oJobRepositoryLocal->getJob($sJobName); |
|
127
|
|
|
$_oJobEntityChronos = $this->oJobRepositoryChronos->getJob($sJobName); |
|
128
|
|
|
|
|
129
|
|
|
$_aNonidenticalProperties = $this->compareJobEntities( |
|
130
|
|
|
$_oJobEntityLocal, |
|
131
|
|
|
$_oJobEntityChronos |
|
132
|
|
|
); |
|
133
|
|
|
|
|
134
|
|
|
foreach ($_aNonidenticalProperties as $_sProperty) |
|
135
|
|
|
{ |
|
136
|
|
|
$_aReturn[$_sProperty] = $this->oDiffCompare->compare( |
|
137
|
|
|
$_oJobEntityChronos->{$_sProperty}, |
|
138
|
|
|
$_oJobEntityLocal->{$_sProperty} |
|
139
|
|
|
); |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
return $_aReturn; |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
/** |
|
146
|
|
|
* @param JobEntity $oJobEntityA |
|
147
|
|
|
* @param JobEntity $oJobEntityB |
|
148
|
|
|
* @return bool |
|
149
|
|
|
*/ |
|
150
|
2 |
|
public function hasSameJobType(JobEntity $oJobEntityA, JobEntity $oJobEntityB) |
|
151
|
|
|
{ |
|
152
|
|
|
return ( |
|
153
|
2 |
|
($oJobEntityA->isSchedulingJob() && $oJobEntityB->isSchedulingJob()) |
|
154
|
2 |
|
|| ($oJobEntityA->isDependencyJob() && $oJobEntityB->isDependencyJob()) |
|
155
|
2 |
|
); |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
/** |
|
159
|
|
|
* @param JobEntity $oJobEntityA |
|
160
|
|
|
* @param JobEntity $oJobEntityB |
|
161
|
|
|
* @return array |
|
162
|
|
|
*/ |
|
163
|
3 |
|
private function compareJobEntities(JobEntity $oJobEntityA, JobEntity $oJobEntityB) |
|
164
|
|
|
{ |
|
165
|
3 |
|
$_aNonidenticalProperties = []; |
|
166
|
|
|
|
|
167
|
3 |
|
$_aDiff = array_merge( |
|
168
|
3 |
|
array_diff_assoc( |
|
169
|
3 |
|
$oJobEntityA->getSimpleArrayCopy(), |
|
170
|
3 |
|
$oJobEntityB->getSimpleArrayCopy() |
|
171
|
3 |
|
), |
|
172
|
3 |
|
array_diff_assoc( |
|
173
|
3 |
|
$oJobEntityB->getSimpleArrayCopy(), |
|
174
|
3 |
|
$oJobEntityA->getSimpleArrayCopy() |
|
175
|
3 |
|
) |
|
176
|
3 |
|
); |
|
177
|
|
|
|
|
178
|
3 |
|
if (count($_aDiff) > 0) |
|
179
|
3 |
|
{ |
|
180
|
3 |
|
$_aDiffKeys = array_keys($_aDiff); |
|
181
|
3 |
|
foreach ($_aDiffKeys as $_sDiffKey) |
|
182
|
|
|
{ |
|
183
|
3 |
|
if (!$this->isJobEntityValueIdentical($_sDiffKey, $oJobEntityA, $oJobEntityB)) |
|
184
|
3 |
|
{ |
|
185
|
3 |
|
$_aNonidenticalProperties[] = $_sDiffKey; |
|
186
|
3 |
|
} |
|
187
|
3 |
|
} |
|
188
|
3 |
|
} |
|
189
|
|
|
|
|
190
|
3 |
|
return $_aNonidenticalProperties; |
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
|
/** |
|
194
|
|
|
* @param string $sProperty |
|
195
|
|
|
* @param JobEntity $oJobEntityA |
|
196
|
|
|
* @param JobEntity $oJobEntityB |
|
197
|
|
|
* @return bool |
|
198
|
|
|
*/ |
|
199
|
3 |
|
private function isJobEntityValueIdentical($sProperty, JobEntity $oJobEntityA, JobEntity $oJobEntityB) |
|
200
|
|
|
{ |
|
201
|
3 |
|
$mValueA = $oJobEntityA->{$sProperty}; |
|
202
|
3 |
|
$mValueB = $oJobEntityB->{$sProperty}; |
|
203
|
|
|
|
|
204
|
|
|
switch ($sProperty) |
|
205
|
|
|
{ |
|
206
|
3 |
|
case 'schedule': |
|
207
|
1 |
|
return $this->isSchedulePropertyIdentical($oJobEntityA, $oJobEntityB); |
|
208
|
|
|
|
|
209
|
3 |
|
case 'scheduleTimeZone': |
|
210
|
1 |
|
return $this->isScheduleTimeZonePropertyIdentical($oJobEntityA, $oJobEntityB); |
|
211
|
|
|
|
|
212
|
2 |
|
case 'parents': |
|
213
|
|
|
return ( |
|
214
|
|
|
is_array($mValueA) |
|
215
|
|
|
&& is_array($mValueB) |
|
216
|
|
|
&& count(array_diff($mValueA, $mValueB)) == 0 |
|
217
|
|
|
&& count(array_diff($mValueB, $mValueA)) == 0 |
|
218
|
|
|
); |
|
219
|
|
|
|
|
220
|
2 |
|
case 'successCount': |
|
221
|
2 |
|
case 'lastSuccess': |
|
222
|
2 |
|
case 'errorCount': |
|
223
|
2 |
|
case 'errorsSinceLastSuccess': |
|
224
|
2 |
|
case 'lastError': |
|
225
|
|
|
return true; |
|
226
|
|
|
|
|
227
|
2 |
|
default: |
|
228
|
2 |
|
return ($mValueA == $mValueB); |
|
229
|
2 |
|
} |
|
230
|
|
|
} |
|
231
|
|
|
|
|
232
|
|
|
/** |
|
233
|
|
|
* @param JobEntity $oJobEntityA |
|
234
|
|
|
* @param JobEntity $oJobEntityB |
|
235
|
|
|
* @return bool |
|
236
|
|
|
*/ |
|
237
|
1 |
|
private function isScheduleTimeZonePropertyIdentical(JobEntity $oJobEntityA, JobEntity $oJobEntityB) |
|
238
|
|
|
{ |
|
239
|
1 |
|
if ($oJobEntityA->scheduleTimeZone == $oJobEntityB->scheduleTimeZone) |
|
240
|
1 |
|
{ |
|
241
|
|
|
return true; |
|
242
|
|
|
} |
|
243
|
|
|
|
|
244
|
1 |
|
if (!empty($oJobEntityA->schedule) && !empty($oJobEntityB->schedule)) |
|
245
|
1 |
|
{ |
|
246
|
1 |
|
$_oDateA = $this->createDateTimeObj($oJobEntityA->schedule, $oJobEntityA->scheduleTimeZone); |
|
247
|
1 |
|
$_oDateB = $this->createDateTimeObj($oJobEntityB->schedule, $oJobEntityB->scheduleTimeZone); |
|
248
|
|
|
|
|
249
|
1 |
|
return ($_oDateA->getOffset() == $_oDateB->getOffset()); |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
return false; |
|
253
|
|
|
} |
|
254
|
|
|
|
|
255
|
|
|
/** |
|
256
|
|
|
* @param JobEntity $oJobEntityA |
|
257
|
|
|
* @param JobEntity $oJobEntityB |
|
258
|
|
|
* @return bool |
|
259
|
|
|
*/ |
|
260
|
1 |
|
private function isSchedulePropertyIdentical(JobEntity $oJobEntityA, JobEntity $oJobEntityB) |
|
261
|
|
|
{ |
|
262
|
|
|
// if values are exact the same |
|
263
|
1 |
|
if ($oJobEntityA->schedule === $oJobEntityB->schedule) |
|
264
|
1 |
|
{ |
|
265
|
|
|
$this->oLogger->debug(sprintf('%s::EXCACT INTERVAL FOR "%s"', 'ScheduleComparison', $oJobEntityA->name)); |
|
266
|
|
|
return true; |
|
267
|
|
|
} |
|
268
|
|
|
|
|
269
|
|
|
// if one value is empty and not both, compare the time periods |
|
270
|
1 |
|
if (!empty($oJobEntityA->schedule) && !empty($oJobEntityB->schedule)) |
|
271
|
1 |
|
{ |
|
272
|
1 |
|
$_oIso8601EntityA = $this->oDatePeriodFactory->createIso8601Entity($oJobEntityA->schedule); |
|
273
|
1 |
|
$_oIso8601EntityB = $this->oDatePeriodFactory->createIso8601Entity($oJobEntityB->schedule); |
|
274
|
|
|
|
|
275
|
|
|
// if the clean interval is different return directly false (P1D != P1M) |
|
276
|
1 |
|
if ($_oIso8601EntityA->sInterval != $_oIso8601EntityB->sInterval) |
|
277
|
1 |
|
{ |
|
278
|
1 |
|
$this->oLogger->debug(sprintf('%s::DIFFERENT INTERVAL FOR "%s"', 'ScheduleComparison', $oJobEntityA->name)); |
|
279
|
1 |
|
return false; |
|
280
|
|
|
} |
|
281
|
|
|
|
|
282
|
|
|
// else if the interval is <= 1Min return directly true (performance) |
|
283
|
1 |
|
if ($_oIso8601EntityA->sInterval == 'PT1M' || $_oIso8601EntityA->sInterval == 'PT1S') |
|
284
|
1 |
|
{ |
|
285
|
1 |
|
$this->oLogger->debug(sprintf('%s::PT1M|PT1S INTERVAL FOR "%s" - Job execution should be equal', 'ScheduleComparison', $oJobEntityA->name)); |
|
286
|
1 |
|
return true; |
|
287
|
|
|
} |
|
288
|
|
|
|
|
289
|
|
|
// start to check by DatePeriods |
|
290
|
1 |
|
$_oLastDateTimeA = null; |
|
291
|
1 |
|
$_oLastDateTimeB = null; |
|
292
|
|
|
|
|
293
|
|
|
/** @var \DatePeriod $_oPeriodB */ |
|
294
|
1 |
|
$_oPeriodA = $this->oDatePeriodFactory->createDatePeriod($oJobEntityA->schedule, $oJobEntityA->scheduleTimeZone); |
|
295
|
|
|
|
|
296
|
|
|
/** @var \DateTime $_oDateTime */ |
|
297
|
1 |
|
foreach ($_oPeriodA as $_oDateTime) { |
|
298
|
1 |
|
$_oLastDateTimeA = $_oDateTime; |
|
299
|
1 |
|
} |
|
300
|
|
|
|
|
301
|
|
|
/** @var \DatePeriod $_oPeriodB */ |
|
302
|
1 |
|
$_oPeriodB = $this->oDatePeriodFactory->createDatePeriod($oJobEntityB->schedule, $oJobEntityB->scheduleTimeZone); |
|
303
|
|
|
|
|
304
|
|
|
/** @var \DateTime $_oDateTime */ |
|
305
|
1 |
|
foreach ($_oPeriodB as $_oDateTime) { |
|
306
|
1 |
|
$_oLastDateTimeB = $_oDateTime; |
|
307
|
1 |
|
} |
|
308
|
|
|
|
|
309
|
|
|
// $_oLastDateTimeA !== false happen if no dates are in the period |
|
310
|
1 |
|
if ($_oLastDateTimeA !== null && $_oLastDateTimeB !== null) |
|
311
|
1 |
|
{ |
|
312
|
1 |
|
$_oDiffInterval = $_oLastDateTimeA->diff($_oLastDateTimeB); |
|
313
|
1 |
|
$_iDiffInterval = (int) $_oDiffInterval->format('%Y%M%D%H%I'); |
|
314
|
|
|
|
|
315
|
1 |
|
$this->oLogger->debug(sprintf('%s::INTERVAL DIFF OF "%d" FOR "%s"', 'ScheduleComparison', $_iDiffInterval, $oJobEntityA->name)); |
|
316
|
|
|
|
|
317
|
1 |
|
return ($_iDiffInterval == 0); |
|
318
|
|
|
} |
|
319
|
|
|
} |
|
320
|
|
|
|
|
321
|
|
|
$this->oLogger->warning(sprintf('%s::CAN\'T COMPARE INTERVAL FOR "%s"', 'ScheduleComparison', $oJobEntityA->name)); |
|
322
|
|
|
return false; |
|
323
|
|
|
} |
|
324
|
|
|
|
|
325
|
|
|
/** |
|
326
|
|
|
* @param string $sIso8601String |
|
327
|
|
|
* @param string $sTimeZone |
|
328
|
|
|
* @return \DateTime |
|
329
|
|
|
*/ |
|
330
|
1 |
|
private function createDateTimeObj($sIso8601String, $sTimeZone = '') |
|
331
|
|
|
{ |
|
332
|
1 |
|
$_oIso8601Entity = $this->oDatePeriodFactory->createIso8601Entity($sIso8601String); |
|
333
|
|
|
|
|
334
|
1 |
View Code Duplication |
if (!empty($sTimeZone)) |
|
|
|
|
|
|
335
|
1 |
|
{ |
|
336
|
1 |
|
$_oDateTime = new \DateTime(str_replace('Z', '', $_oIso8601Entity->sStartTime)); |
|
337
|
1 |
|
$_oDateTime->setTimezone(new \DateTimeZone($sTimeZone)); |
|
338
|
1 |
|
} |
|
339
|
|
|
else |
|
340
|
|
|
{ |
|
341
|
1 |
|
$_oDateTime = new \DateTime($_oIso8601Entity->sStartTime); |
|
342
|
|
|
} |
|
343
|
|
|
|
|
344
|
1 |
|
return $_oDateTime; |
|
345
|
|
|
} |
|
346
|
|
|
|
|
347
|
|
|
/** |
|
348
|
|
|
* @param JobCollection $oJobCollectionA |
|
349
|
|
|
* @param JobCollection $oJobCollectionB |
|
350
|
|
|
* @return string[] |
|
|
|
|
|
|
351
|
|
|
*/ |
|
352
|
|
|
private function getMissingJobsInCollectionA(JobCollection $oJobCollectionA, JobCollection $oJobCollectionB) |
|
353
|
|
|
{ |
|
354
|
|
|
return array_diff( |
|
355
|
|
|
array_keys($oJobCollectionB->getArrayCopy()), |
|
356
|
|
|
array_keys($oJobCollectionA->getArrayCopy()) |
|
357
|
|
|
); |
|
358
|
|
|
} |
|
359
|
|
|
} |
This check compares the return type specified in the
@returnannotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.