Import/Sync: cleanly rollback transactions
Helps to avoid side-effects
This commit is contained in:
parent
31e1b27628
commit
7cf1af15cb
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Icinga\Module\Director\Import;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Exception\IcingaException;
|
||||
use Icinga\Module\Director\Hook\ImportSourceHook;
|
||||
use Icinga\Module\Director\Objects\ImportSource;
|
||||
|
@ -322,43 +323,49 @@ class Import
|
|||
|
||||
$db->beginTransaction();
|
||||
|
||||
if ($this->isEmpty()) {
|
||||
$newRows = array();
|
||||
$newProperties = array();
|
||||
} else {
|
||||
$newRows = $this->newChecksums('imported_row', $this->rowChecksums);
|
||||
$newProperties = $this->newChecksums('imported_property', array_keys($this->properties));
|
||||
}
|
||||
try {
|
||||
|
||||
$db->insert('imported_rowset', array('checksum' => $this->quoteBinary($rowset)));
|
||||
|
||||
foreach ($newProperties as $checksum) {
|
||||
$db->insert('imported_property', $this->properties[$checksum]);
|
||||
}
|
||||
|
||||
foreach ($newRows as $row) {
|
||||
$db->insert('imported_row', $rows[$row]);
|
||||
foreach ($this->rowProperties[$row] as $property) {
|
||||
$db->insert('imported_row_property', array(
|
||||
'row_checksum' => $this->quoteBinary($row),
|
||||
'property_checksum' => $property
|
||||
));
|
||||
if ($this->isEmpty()) {
|
||||
$newRows = array();
|
||||
$newProperties = array();
|
||||
} else {
|
||||
$newRows = $this->newChecksums('imported_row', $this->rowChecksums);
|
||||
$newProperties = $this->newChecksums('imported_property', array_keys($this->properties));
|
||||
}
|
||||
|
||||
$db->insert('imported_rowset', array('checksum' => $this->quoteBinary($rowset)));
|
||||
|
||||
foreach ($newProperties as $checksum) {
|
||||
$db->insert('imported_property', $this->properties[$checksum]);
|
||||
}
|
||||
|
||||
foreach ($newRows as $row) {
|
||||
$db->insert('imported_row', $rows[$row]);
|
||||
foreach ($this->rowProperties[$row] as $property) {
|
||||
$db->insert('imported_row_property', array(
|
||||
'row_checksum' => $this->quoteBinary($row),
|
||||
'property_checksum' => $property
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array_keys($rows) as $row) {
|
||||
$db->insert(
|
||||
'imported_rowset_row',
|
||||
array(
|
||||
'rowset_checksum' => $this->quoteBinary($rowset),
|
||||
'row_checksum' => $this->quoteBinary($row)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$db->commit();
|
||||
|
||||
$this->rowsetExists = true;
|
||||
} catch (Exception $e) {
|
||||
$db->rollBack();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
foreach (array_keys($rows) as $row) {
|
||||
$db->insert(
|
||||
'imported_rowset_row',
|
||||
array(
|
||||
'rowset_checksum' => $this->quoteBinary($rowset),
|
||||
'row_checksum' => $this->quoteBinary($row)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$db->commit();
|
||||
|
||||
$this->rowsetExists = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Icinga\Module\Director\Import;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Module\Director\Objects\IcingaObject;
|
||||
use Icinga\Module\Director\Objects\ImportSource;
|
||||
|
@ -685,63 +686,70 @@ class Sync
|
|||
$db = $this->db;
|
||||
$dba = $db->getDbAdapter();
|
||||
$dba->beginTransaction();
|
||||
$formerActivityChecksum = Util::hex2binary(
|
||||
$db->getLastActivityChecksum()
|
||||
);
|
||||
$created = 0;
|
||||
$modified = 0;
|
||||
$deleted = 0;
|
||||
foreach ($objects as $object) {
|
||||
if ($object instanceof IcingaObject && $object->isTemplate()) {
|
||||
// TODO: allow to sync templates
|
||||
if ($object->hasBeenModified()) {
|
||||
throw new IcingaException(
|
||||
'Sync is not allowed to modify template "%s"',
|
||||
$object->$objectKey
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($object instanceof IcingaObject && $object->shouldBeRemoved()) {
|
||||
$object->delete($db);
|
||||
$deleted++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($object->hasBeenModified()) {
|
||||
if ($object->hasBeenLoadedFromDb()) {
|
||||
$modified++;
|
||||
} else {
|
||||
$created++;
|
||||
}
|
||||
$object->store($db);
|
||||
}
|
||||
}
|
||||
|
||||
$runProperties = array(
|
||||
'objects_created' => $created,
|
||||
'objects_deleted' => $deleted,
|
||||
'objects_modified' => $modified,
|
||||
);
|
||||
|
||||
if ($created + $deleted + $modified > 0) {
|
||||
// TODO: What if this has been the very first activity?
|
||||
$runProperties['last_former_activity'] = $db->quoteBinary($formerActivityChecksum);
|
||||
$runProperties['last_related_activity'] = $db->quoteBinary(Util::hex2binary(
|
||||
try {
|
||||
$formerActivityChecksum = Util::hex2binary(
|
||||
$db->getLastActivityChecksum()
|
||||
));
|
||||
);
|
||||
$created = 0;
|
||||
$modified = 0;
|
||||
$deleted = 0;
|
||||
foreach ($objects as $object) {
|
||||
if ($object instanceof IcingaObject && $object->isTemplate()) {
|
||||
// TODO: allow to sync templates
|
||||
if ($object->hasBeenModified()) {
|
||||
throw new IcingaException(
|
||||
'Sync is not allowed to modify template "%s"',
|
||||
$object->$objectKey
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($object instanceof IcingaObject && $object->shouldBeRemoved()) {
|
||||
$object->delete($db);
|
||||
$deleted++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($object->hasBeenModified()) {
|
||||
if ($object->hasBeenLoadedFromDb()) {
|
||||
$modified++;
|
||||
} else {
|
||||
$created++;
|
||||
}
|
||||
$object->store($db);
|
||||
}
|
||||
}
|
||||
|
||||
$runProperties = array(
|
||||
'objects_created' => $created,
|
||||
'objects_deleted' => $deleted,
|
||||
'objects_modified' => $modified,
|
||||
);
|
||||
|
||||
if ($created + $deleted + $modified > 0) {
|
||||
// TODO: What if this has been the very first activity?
|
||||
$runProperties['last_former_activity'] = $db->quoteBinary($formerActivityChecksum);
|
||||
$runProperties['last_related_activity'] = $db->quoteBinary(Util::hex2binary(
|
||||
$db->getLastActivityChecksum()
|
||||
));
|
||||
}
|
||||
|
||||
$this->run->setProperties($runProperties)->store();
|
||||
|
||||
$dba->commit();
|
||||
|
||||
// Store duration after commit, as the commit might take some time
|
||||
$this->run->set('duration_ms', (int) round(
|
||||
(microtime(true) - $this->runStartTime) * 1000
|
||||
))->store();
|
||||
|
||||
} catch (Exception $e) {
|
||||
$dba->rollBack();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->run->setProperties($runProperties)->store();
|
||||
|
||||
$dba->commit();
|
||||
|
||||
// Store duration after commit, as the commit might take some time
|
||||
$this->run->set('duration_ms', (int) round(
|
||||
(microtime(true) - $this->runStartTime) * 1000
|
||||
))->store();
|
||||
|
||||
return $this->run->id;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue