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
@return
annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.