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
|
4 |
|
public function __construct( |
55
|
|
|
JobRepositoryInterface $oJobRepositoryLocal, |
56
|
|
|
JobRepositoryInterface $oJobRepositoryChronos, |
57
|
|
|
DiffCompareInterface $oDiffCompare, |
58
|
|
|
DatePeriodFactoryInterface $oDatePeriodFactory, |
59
|
|
|
LoggerInterface $oLogger |
60
|
|
|
) |
61
|
|
|
{ |
62
|
4 |
|
$this->oJobRepositoryLocal = $oJobRepositoryLocal; |
63
|
4 |
|
$this->oJobRepositoryChronos = $oJobRepositoryChronos; |
64
|
4 |
|
$this->oDiffCompare = $oDiffCompare; |
65
|
4 |
|
$this->oDatePeriodFactory = $oDatePeriodFactory; |
66
|
4 |
|
$this->oLogger = $oLogger; |
67
|
4 |
|
} |
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
|
2 |
|
public function getLocalJobUpdates() |
95
|
|
|
{ |
96
|
2 |
|
$_aJobsLocal = $this->oJobRepositoryLocal->getJobs(); |
97
|
2 |
|
$_aLocalJobUpdates = []; |
98
|
|
|
|
99
|
|
|
/** @var JobEntity $_oJobEntity */ |
100
|
2 |
|
foreach ($_aJobsLocal as $_oJobEntityLocal) |
101
|
|
|
{ |
102
|
2 |
|
$_oJobEntityChronos = $this->oJobRepositoryChronos->getJob($_oJobEntityLocal->name); |
103
|
|
|
|
104
|
|
|
// if job already exist in chronos (not new or deleted in chronos) |
105
|
2 |
|
if (!empty($_oJobEntityChronos->name)) |
106
|
2 |
|
{ |
107
|
2 |
|
$_aNonidenticalProperties = $this->compareJobEntities($_oJobEntityLocal, $_oJobEntityChronos); |
108
|
2 |
|
if (!empty($_aNonidenticalProperties)) |
109
|
2 |
|
{ |
110
|
2 |
|
$_aLocalJobUpdates[] = $_oJobEntityLocal->name; |
111
|
2 |
|
} |
112
|
2 |
|
} |
113
|
2 |
|
} |
114
|
|
|
|
115
|
2 |
|
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
|
2 |
|
private function compareJobEntities(JobEntity $oJobEntityA, JobEntity $oJobEntityB) |
164
|
|
|
{ |
165
|
2 |
|
$_aNonidenticalProperties = []; |
166
|
|
|
|
167
|
2 |
|
$_aDiff = array_merge( |
168
|
2 |
|
array_diff_assoc( |
169
|
2 |
|
$oJobEntityA->getSimpleArrayCopy(), |
170
|
2 |
|
$oJobEntityB->getSimpleArrayCopy() |
171
|
2 |
|
), |
172
|
2 |
|
array_diff_assoc( |
173
|
2 |
|
$oJobEntityB->getSimpleArrayCopy(), |
174
|
2 |
|
$oJobEntityA->getSimpleArrayCopy() |
175
|
2 |
|
) |
176
|
2 |
|
); |
177
|
|
|
|
178
|
2 |
|
if (count($_aDiff) > 0) |
179
|
2 |
|
{ |
180
|
2 |
|
$_aDiffKeys = array_keys($_aDiff); |
181
|
2 |
|
foreach ($_aDiffKeys as $_sDiffKey) |
182
|
|
|
{ |
183
|
2 |
|
if (!$this->isJobEntityValueIdentical($_sDiffKey, $oJobEntityA, $oJobEntityB)) |
184
|
2 |
|
{ |
185
|
2 |
|
$_aNonidenticalProperties[] = $_sDiffKey; |
186
|
2 |
|
} |
187
|
2 |
|
} |
188
|
2 |
|
} |
189
|
|
|
|
190
|
2 |
|
return $_aNonidenticalProperties; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* @param string $sProperty |
195
|
|
|
* @param JobEntity $oJobEntityA |
196
|
|
|
* @param JobEntity $oJobEntityB |
197
|
|
|
* @return bool |
198
|
|
|
*/ |
199
|
2 |
|
private function isJobEntityValueIdentical($sProperty, JobEntity $oJobEntityA, JobEntity $oJobEntityB) |
200
|
|
|
{ |
201
|
2 |
|
$mValueA = $oJobEntityA->{$sProperty}; |
202
|
2 |
|
$mValueB = $oJobEntityB->{$sProperty}; |
203
|
|
|
|
204
|
|
|
switch ($sProperty) |
205
|
|
|
{ |
206
|
2 |
|
case 'schedule': |
207
|
1 |
|
return $this->isSchedulePropertyIdentical($oJobEntityA, $oJobEntityB); |
208
|
|
|
|
209
|
2 |
|
case 'scheduleTimeZone': |
210
|
1 |
|
return $this->isScheduleTimeZonePropertyIdentical($oJobEntityA, $oJobEntityB); |
211
|
|
|
|
212
|
1 |
|
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
|
1 |
|
case 'successCount': |
221
|
1 |
|
case 'lastSuccess': |
222
|
1 |
|
case 'errorCount': |
223
|
1 |
|
case 'errorsSinceLastSuccess': |
224
|
1 |
|
case 'lastError': |
225
|
|
|
return true; |
226
|
|
|
|
227
|
1 |
|
default: |
228
|
1 |
|
return ($mValueA == $mValueB); |
229
|
1 |
|
} |
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
|
|
|
// if the clean interval is different return directly false (P1D != P1M) |
273
|
1 |
|
if (!$this->isEqualInterval($oJobEntityA->schedule, $oJobEntityB->schedule)) |
274
|
1 |
|
{ |
275
|
1 |
|
$this->oLogger->debug(sprintf('%s::DIFFERENT INTERVAL FOR "%s"', 'ScheduleComparison', $oJobEntityA->name)); |
276
|
1 |
|
return false; |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
// start to check by DatePeriods |
280
|
1 |
|
$_aDatesA = []; |
281
|
1 |
|
$_aDatesB = []; |
282
|
|
|
|
283
|
|
|
/** @var \DatePeriod $_oPeriodB */ |
284
|
1 |
|
$_oPeriodA = $this->oDatePeriodFactory->createDatePeriod($oJobEntityA->schedule, $oJobEntityA->scheduleTimeZone); |
285
|
|
|
|
286
|
|
|
/** @var \DateTime $_oDateTime */ |
287
|
1 |
|
foreach ($_oPeriodA as $_oDateTime) { |
288
|
1 |
|
$_aDatesA[] = $_oDateTime; |
289
|
1 |
|
} |
290
|
|
|
|
291
|
|
|
/** @var \DatePeriod $_oPeriodB */ |
292
|
1 |
|
$_oPeriodB = $this->oDatePeriodFactory->createDatePeriod($oJobEntityB->schedule, $oJobEntityB->scheduleTimeZone); |
293
|
|
|
|
294
|
|
|
/** @var \DateTime $_oDateTime */ |
295
|
1 |
|
foreach ($_oPeriodB as $_oDateTime) { |
296
|
1 |
|
$_aDatesB[] = $_oDateTime; |
297
|
1 |
|
} |
298
|
|
|
|
299
|
|
|
/** @var \DateTime $_oLastDateTimeA */ |
300
|
1 |
|
$_oLastDateTimeA = end($_aDatesA); |
301
|
|
|
/** @var \DateTime $_oLastDateTimeB */ |
302
|
1 |
|
$_oLastDateTimeB = end($_aDatesB); |
303
|
|
|
|
304
|
|
|
// $_oLastDateTimeA !== false happen if no dates are in the period |
305
|
1 |
|
if ($_oLastDateTimeA !== false && $_oLastDateTimeB !== false) |
306
|
1 |
|
{ |
307
|
1 |
|
$_oDiffInterval = $_oLastDateTimeA->diff($_oLastDateTimeB); |
308
|
1 |
|
$_iDiffInterval = (int) $_oDiffInterval->format('%Y%M%D%H%I'); |
309
|
|
|
|
310
|
1 |
|
$this->oLogger->debug(sprintf('%s::INTERVAL DIFF OF "%d" FOR "%s"', 'ScheduleComparison', $_iDiffInterval, $oJobEntityA->name)); |
311
|
|
|
|
312
|
1 |
|
return ($_iDiffInterval == 0); |
313
|
|
|
} |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
$this->oLogger->warning(sprintf('%s::CAN\'T COMPARE INTERVAL FOR "%s"', 'ScheduleComparison', $oJobEntityA->name)); |
317
|
|
|
return false; |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* @param string $sIso8601String |
322
|
|
|
* @param string $sTimeZone |
323
|
|
|
* @return \DateTime |
324
|
|
|
*/ |
325
|
1 |
|
private function createDateTimeObj($sIso8601String, $sTimeZone = '') |
326
|
|
|
{ |
327
|
1 |
|
$_oIso8601Entity = $this->oDatePeriodFactory->createIso8601Entity($sIso8601String); |
328
|
|
|
|
329
|
1 |
View Code Duplication |
if (!empty($sTimeZone)) |
|
|
|
|
330
|
1 |
|
{ |
331
|
1 |
|
$_oDateTime = new \DateTime(str_replace('Z', '', $_oIso8601Entity->sStartTime)); |
332
|
1 |
|
$_oDateTime->setTimezone(new \DateTimeZone($sTimeZone)); |
333
|
1 |
|
} |
334
|
|
|
else |
335
|
|
|
{ |
336
|
1 |
|
$_oDateTime = new \DateTime($_oIso8601Entity->sStartTime); |
337
|
|
|
} |
338
|
|
|
|
339
|
1 |
|
return $_oDateTime; |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
/** |
343
|
|
|
* @param string $sIso8601StringA |
344
|
|
|
* @param string $sIso8601StringB |
345
|
|
|
* @return bool |
346
|
|
|
*/ |
347
|
1 |
|
private function isEqualInterval($sIso8601StringA, $sIso8601StringB) |
348
|
|
|
{ |
349
|
1 |
|
$_oIso8601EntityA = $this->oDatePeriodFactory->createIso8601Entity($sIso8601StringA); |
350
|
1 |
|
$_oIso8601EntityB = $this->oDatePeriodFactory->createIso8601Entity($sIso8601StringB); |
351
|
|
|
|
352
|
1 |
|
return ($_oIso8601EntityA->sInterval == $_oIso8601EntityB->sInterval); |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* @param JobCollection $oJobCollectionA |
357
|
|
|
* @param JobCollection $oJobCollectionB |
358
|
|
|
* @return string[] |
|
|
|
|
359
|
|
|
*/ |
360
|
|
|
private function getMissingJobsInCollectionA(JobCollection $oJobCollectionA, JobCollection $oJobCollectionB) |
361
|
|
|
{ |
362
|
|
|
return array_diff( |
363
|
|
|
array_keys($oJobCollectionB->getArrayCopy()), |
364
|
|
|
array_keys($oJobCollectionA->getArrayCopy()) |
365
|
|
|
); |
366
|
|
|
} |
367
|
|
|
} |
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.