SyncRule: introduce purge strategies

This commit is contained in:
Thomas Gelf 2016-06-24 17:07:00 +02:00
parent 39cf0a5fb8
commit 9387b92da1
4 changed files with 151 additions and 0 deletions

View File

@ -0,0 +1,73 @@
<?php
namespace Icinga\Module\Director\Import\PurgeStrategy;
use Icinga\Module\Director\Objects\ImportRun;
use Icinga\Module\Director\Objects\ImportSource;
class ImportRunBasedPurgeStrategy extends PurgeStrategy
{
public function listObjectsToPurge()
{
$remove = array();
foreach ($this->getSyncRule()->fetchInvolvedImportSources() as $source) {
$remove += $this->checkImportSource($source);
}
return $remove;
}
protected function getLastSync()
{
return strtotime($this->getSyncRule()->getLastSyncTimestamp());
}
// TODO: NAMING!
protected function checkImportSource(ImportSource $source)
{
if (null === ($lastSync = $this->getLastSync())) {
// No last sync, nothing to purge
return array();
}
$runA = $source->fetchLastRunBefore($lastSync);
if ($runA === null) {
// Nothing to purge for this source
return array();
}
$runB = $source->fetchLastRun();
if ($runA->rowset_checksum === $runB->rowset_checksum) {
// Same source data, nothing to purge
return array();
}
return $this->listKeysRemovedBetween($runA, $runB);
}
public function listKeysRemovedBetween(ImportRun $runA, ImportRun $runB)
{
$db = $this->getSyncRule()->getDb();
$selectA = $runA->prepareImportedObjectQuery();
$selectB = $runB->prepareImportedObjectQuery();
$query = $db->select()->from(
array('a' => $selectA),
'a.object_name'
)->joinLeft(
array('b' => $selectB),
'a.object_name = b.object_name',
array()
)->where('b.object_name IS NULL');
$result = $db->fetchCol($query);
if ($result) {
return array_combine($result, $result);
} else {
return array();
}
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Icinga\Module\Director\Import\PurgeStrategy;
class PurgeNothingPurgeStrategy extends PurgeStrategy
{
public function listObjectsToPurge()
{
return array();
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace Icinga\Module\Director\Import\PurgeStrategy;
use Icinga\Module\Director\Objects\SyncRule;
abstract class PurgeStrategy
{
private $rule;
public function __construct(SyncRule $rule)
{
$this->rule = $rule;
}
protected function getSyncRule()
{
return $this->rule;
}
abstract function listObjectsToPurge();
/**
* @return PurgeStrategy
*/
public static function load($name, SyncRule $rule)
{
$class = __NAMESPACE__ . '\\' . $name . 'PurgeStrategy';
return new $class($rule);
}
}

View File

@ -5,6 +5,7 @@ namespace Icinga\Module\Director\Objects;
use Icinga\Application\Benchmark;
use Icinga\Data\Filter\Filter;
use Icinga\Module\Director\Data\Db\DbObject;
use Icinga\Module\Director\Import\PurgeStrategy\PurgeStrategy;
use Icinga\Module\Director\Import\Sync;
use Exception;
@ -30,6 +31,8 @@ class SyncRule extends DbObject
private $sync;
private $purgeStrategy;
private $currentSyncRunId;
private $filter;
@ -52,6 +55,17 @@ class SyncRule extends DbObject
));
}
public function fetchInvolvedImportSources()
{
$sources = array();
foreach ($this->listInvolvedSourceIds() as $sourceId) {
$sources[$sourceId] = ImportSource::load($sourceId, $this->getConnection());
}
return $sources;
}
public function getLastSyncTimestamp()
{
if (! $this->hasBeenLoadedFromDb()) {
@ -117,6 +131,8 @@ class SyncRule extends DbObject
Benchmark::measure('Checking sync rule ' . $this->rule_name);
try {
$this->last_attempt = date('Y-m-d H:i:s');
$this->sync_state = 'unknown';
$sync = $this->sync();
if ($sync->hasModifications()) {
Benchmark::measure('Got modifications for sync rule ' . $this->rule_name);
@ -136,6 +152,7 @@ class SyncRule extends DbObject
$this->last_error_message = null;
} catch (Exception $e) {
throw $e;
$this->sync_state = 'failing';
$this->last_error_message = $e->getMessage();
}
@ -175,6 +192,25 @@ class SyncRule extends DbObject
return $this->filter;
}
public function purgeStrategy()
{
if ($this->purgeStrategy === null) {
$this->purgeStrategy = $this->loadConfiguredPurgeStrategy();
}
return $this->purgeStrategy;
}
// TODO: Allow for more
protected function loadConfiguredPurgeStrategy()
{
if ($this->purge_existing) {
return PurgeStrategy::load('ImportRunBased', $this);
} else {
return PurgeStrategy::load('PurgeNothing', $this);
}
}
public function fetchSyncProperties()
{
$db = $this->getDb();