schema/mysql: add sync_run history table

This commit is contained in:
Thomas Gelf 2016-02-24 10:50:57 +01:00
parent 5c202b57ff
commit 42e87476fb
6 changed files with 87 additions and 44 deletions

View File

@ -61,12 +61,12 @@ class JobsCommand extends Command
foreach (SyncRule::loadAll($this->db) as $rule) {
Benchmark::measure('Checking sync rule ' . $rule->rule_name);
$mod = Sync::getExpectedModifications($rule);
if (count($mod) > 0) {
$sync = new Sync($rule);
if ($sync->hasModifications()) {
printf('Sync rule "%s" provides changes, triggering sync... ', $rule->rule_name);
Benchmark::measure('Got modifications for sync rule ' . $rule->rule_name);
if (Sync::run($rule)) {
if ($sync->apply()) {
Benchmark::measure('Successfully synced rule ' . $rule->rule_name);
print "SUCCEEDED\n";
}

View File

@ -22,7 +22,8 @@ class SyncruleController extends ActionController
public function runAction()
{
if ($runId = Sync::run(SyncRule::load($this->params->get('id'), $this->db()))) {
$sync = new Sync(SyncRule::load($this->params->get('id'), $this->db()));
if ($runId = $sync->apply()) {
Notification::success('Source has successfully been synchronized');
$this->redirectNow('director/list/syncrule');
} else {

View File

@ -51,9 +51,9 @@ class SyncruleTable extends QuickTable
try {
// $mod = Sync::hasModifications(
$mod = Sync::getExpectedModifications(
SyncRule::load($row->id, $this->connection())
);
$sync = new Sync(SyncRule::load($row->id, $this->connection()));
$mod = $sync->getExpectedModifications();
if (count($mod) > 0) {
$row->rule_name = $row->rule_name . ' (' . count($mod) . ')';
return 'pending-changes';

View File

@ -60,51 +60,32 @@ class Sync
* Constructor. No direct initialization allowed right now. Please use one
* of the available static factory methods
*/
protected function __construct(SyncRule $rule)
public function __construct(SyncRule $rule)
{
$this->rule = $rule;
$this->db = $rule->getConnection();
$this->syncProperties = $rule->fetchSyncProperties();
}
/**
* Run the given sync rule
*/
public static function run(SyncRule $rule)
{
$sync = new static($rule);
// Raise limits. TODO: do this in a failsafe way, and only if necessary
ini_set('memory_limit', '768M');
ini_set('max_execution_time', 0);
return $sync->apply();
}
/**
* Whether the given sync rule would apply modifications
*
* @param SyncRule $rule SyncRule object
*
* @return boolean
*/
public static function hasModifications(SyncRule $rule)
public function hasModifications()
{
return count(self::getExpectedModifications()) > 0;
return count($this->getExpectedModifications()) > 0;
}
/**
* Retrieve modifications a given SyncRule would apply
*
* @param SyncRule $rule SyncRule object
*
* @return array Array of IcingaObject elements
*/
public static function getExpectedModifications(SyncRule $rule)
public function getExpectedModifications()
{
$modified = array();
$sync = new static($rule);
$objects = $sync->prepare();
$objects = $this->prepare();
foreach ($objects as $object) {
if ($object->hasBeenModified()) {
$modified[] = $object;
@ -234,6 +215,21 @@ class Sync
return preg_replace_callback('/\${([A-Za-z0-9\._-]+)}/', $func, $string);
}
/**
* Raise PHP resource limits
*
* TODO: do this in a failsafe way, and only if necessary
*
* @return self;
*/
protected function raiseLimits()
{
ini_set('memory_limit', '768M');
ini_set('max_execution_time', 0);
return $this;
}
/**
* Instantiates all related ImportSource objects
*
@ -291,6 +287,7 @@ class Sync
if ($this->rule->object_type === 'service') {
$hasHost = false;
$hasObjectName = false;
foreach ($this->syncProperties as $key => $property) {
if ($property->destination_field === 'host') {
$hasHost = $property->source_expression;
@ -302,8 +299,13 @@ class Sync
if ($hasHost !== false && $hasObjectName !== false) {
$this->hasCombinedKey = true;
$this->sourceKeyPattern = sprintf('%s!%s', $hasHost, $hasObjectName);
$this->destinationKeyPattern = 'host!object_name';
$this->sourceKeyPattern = sprintf(
'%s!%s',
$hasHost,
$hasObjectName
);
$this->destinationKeyPattern = '${host}!${object_name}';
}
}
}
@ -505,7 +507,8 @@ class Sync
protected function prepare()
{
$rule = $this->rule;
$this->prepareRelatedImportSources()
$this->raiseLimits()
->prepareRelatedImportSources()
->prepareSourceColumns()
->fetchImportedData()
->loadExistingObjects();
@ -515,7 +518,7 @@ class Sync
foreach ($newObjects as $key => $object) {
if (array_key_exists($key, $this->objects)) {
switch ($rule->update_policy) {
switch ($this->rule->update_policy) {
case 'override':
$this->objects[$key]->replaceWith($object);
break;
@ -534,7 +537,6 @@ class Sync
}
}
$objectKey = $rule->object_type === 'datalistEntry' ? 'entry_name' : 'object_name';
$noAction = array();
foreach ($this->objects as $key => $object) {
@ -542,7 +544,7 @@ class Sync
if (array_key_exists($key, $newObjects)) {
// Stats?
} elseif ($object->hasBeenLoadedFromDb() && $rule->purge_existing === 'y') {
} elseif ($object->hasBeenLoadedFromDb() && $this->rule->purge_existing === 'y') {
$object->markForRemoval();
// TODO: this is for stats, preview, summary:
@ -567,14 +569,12 @@ class Sync
*
* @return int
*/
protected function apply()
public function apply()
{
$db = $this->db;
// TODO: Evaluate whether fetching data should happen within the same transaction
$objects = $this->prepare();
$dba = $db->getDbAdapter();
$dba = $this->db->getDbAdapter();
$dba->beginTransaction();
foreach ($objects as $object) {
if ($object instanceof IcingaObject && $object->isTemplate()) {
@ -588,12 +588,12 @@ class Sync
}
if ($object instanceof IcingaObject && $object->shouldBeRemoved()) {
$object->delete($db);
$object->delete($this->db);
continue;
}
if ($object->hasBeenModified()) {
$object->store($db);
$object->store($this->db);
}
}

View File

@ -0,0 +1,23 @@
CREATE TABLE sync_run (
id BIGINT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
rule_id INT(10) UNSIGNED DEFAULT NULL,
rule_name VARCHAR(255) NOT NULL,
start_time DATETIME NOT NULL,
duration_ms INT(10) UNSIGNED NOT NULL,
objects_deleted INT(10) UNSIGNED DEFAULT 0,
objects_created INT(10) UNSIGNED DEFAULT 0,
objects_modified INT(10) UNSIGNED DEFAULT 0,
first_related_activity VARBINARY(20) DEFAULT NULL,
last_related_activity VARBINARY(20) DEFAULT NULL,
PRIMARY KEY (id),
CONSTRAINT sync_run_rule
FOREIGN KEY sync_rule (rule_id)
REFERENCES sync_rule (id)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO director_schema_migration
SET migration_time = NOW(),
schema_version = 67;

View File

@ -1055,7 +1055,26 @@ CREATE TABLE sync_property (
ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE sync_run (
id BIGINT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
rule_id INT(10) UNSIGNED DEFAULT NULL,
rule_name VARCHAR(255) NOT NULL,
start_time DATETIME NOT NULL,
duration_ms INT(10) UNSIGNED NOT NULL,
objects_deleted INT(10) UNSIGNED DEFAULT 0,
objects_created INT(10) UNSIGNED DEFAULT 0,
objects_modified INT(10) UNSIGNED DEFAULT 0,
first_related_activity VARBINARY(20) DEFAULT NULL,
last_related_activity VARBINARY(20) DEFAULT NULL,
PRIMARY KEY (id),
CONSTRAINT sync_run_rule
FOREIGN KEY sync_rule (rule_id)
REFERENCES sync_rule (id)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO director_schema_migration
SET migration_time = NOW(),
schema_version = 66;
schema_version = 67;