diff --git a/islandora/config/install/rdf.mapping.fedora_resource_type.rdf_source.yml b/islandora/config/install/rdf.mapping.fedora_resource_type.rdf_source.yml index cc55ce2d..6697ebc7 100644 --- a/islandora/config/install/rdf.mapping.fedora_resource_type.rdf_source.yml +++ b/islandora/config/install/rdf.mapping.fedora_resource_type.rdf_source.yml @@ -30,6 +30,9 @@ fieldMappings: rdf_type: properties: - 'rdf:type' + vclock: + properties: + - 'islandora:vclock' uid: properties: - 'schema:author' diff --git a/islandora/islandora.module b/islandora/islandora.module index ac28cddc..7250ef53 100644 --- a/islandora/islandora.module +++ b/islandora/islandora.module @@ -80,5 +80,6 @@ function islandora_rdf_namespaces() { 'owl' => 'http://www.w3.org/2002/07/owl#', 'ore' => 'http://www.openarchives.org/ore/terms/', 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', + 'islandora' => 'http://islandora.ca/CLAW/', ); } diff --git a/islandora/src/Entity/FedoraResource.php b/islandora/src/Entity/FedoraResource.php index a39ac73c..ac59060a 100644 --- a/islandora/src/Entity/FedoraResource.php +++ b/islandora/src/Entity/FedoraResource.php @@ -121,6 +121,18 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac ); } + /** + * {@inheritdoc} + */ + public function preSave(EntityStorageInterface $storage) { + parent::preSave($storage); + + // Increment the vclock. + if (!$this->isNew()) { + $this->set("vclock", $this->get("vclock")->value + 1); + } + } + /** * {@inheritdoc} */ @@ -261,6 +273,13 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac return array('root'); } + /** + * {@inheritdoc} + */ + public function getVclock() { + return $this->get('vclock')->value; + } + /** * {@inheritdoc} */ @@ -283,6 +302,11 @@ class FedoraResource extends ContentEntityBase implements FedoraResourceInterfac ->setLabel(t('UUID')) ->setDescription(t('The UUID of the Fedora resource entity.')) ->setReadOnly(TRUE); + $fields['vclock'] = BaseFieldDefinition::create('integer') + ->setLabel(t('Vector Clock')) + ->setDescription(t('Simple accumulator used for causality tracking')) + ->setDefaultValue(0) + ->setSetting('unsigned', TRUE); $fields['user_id'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('Authored by')) diff --git a/islandora/src/FedoraResourceInterface.php b/islandora/src/FedoraResourceInterface.php index baefb5a8..806504d7 100644 --- a/islandora/src/FedoraResourceInterface.php +++ b/islandora/src/FedoraResourceInterface.php @@ -117,4 +117,12 @@ interface FedoraResourceInterface extends ContentEntityInterface, EntityChangedI */ public function setParent(EntityTypeInterface $entity); + /** + * Gets the vector clock of this entity. + * + * @return int + * The vector clock, used for determining causality. + */ + public function getVclock(); + } diff --git a/islandora/tests/src/Kernel/EventGeneratorTest.php b/islandora/tests/src/Kernel/EventGeneratorTest.php index 4e297c57..e1b63559 100644 --- a/islandora/tests/src/Kernel/EventGeneratorTest.php +++ b/islandora/tests/src/Kernel/EventGeneratorTest.php @@ -4,7 +4,6 @@ namespace Drupal\Tests\islandora\Kernel; use Drupal\islandora\Entity\FedoraResource; use Drupal\islandora\EventGenerator\EventGenerator; -use Drupal\KernelTests\KernelTestBase; use Drupal\simpletest\UserCreationTrait; /** @@ -12,7 +11,7 @@ use Drupal\simpletest\UserCreationTrait; * * @group islandora */ -class EventGeneratorTest extends KernelTestBase { +class EventGeneratorTest extends IslandoraKernelTestBase { use UserCreationTrait { createUser as drupalCreateUser; @@ -39,39 +38,12 @@ class EventGeneratorTest extends KernelTestBase { */ protected $eventGenerator; - /** - * {@inheritdoc} - */ - public static $modules = [ - 'system', - 'user', - 'field', - 'filter', - 'block', - 'node', - 'path', - 'text', - 'options', - 'inline_entity_form', - 'serialization', - 'rest', - 'rdf', - 'jsonld', - 'islandora' - ]; - /** * {@inheritdoc} */ public function setUp() { parent::setUp(); - // Bootstrap minimal Drupal environment to run the tests. - $this->installSchema('system', 'sequences'); - $this->installEntitySchema('user'); - $this->installConfig('filter'); - $this->installEntitySchema('fedora_resource'); - // Create a test user. $this->user = $this->drupalCreateUser(); diff --git a/islandora/tests/src/Kernel/IslandoraKernelTestBase.php b/islandora/tests/src/Kernel/IslandoraKernelTestBase.php new file mode 100644 index 00000000..fb5932ab --- /dev/null +++ b/islandora/tests/src/Kernel/IslandoraKernelTestBase.php @@ -0,0 +1,48 @@ +installSchema('system', 'sequences'); + $this->installEntitySchema('user'); + $this->installConfig('filter'); + $this->installEntitySchema('fedora_resource'); + } + +} + diff --git a/islandora/tests/src/Kernel/VectorClockTest.php b/islandora/tests/src/Kernel/VectorClockTest.php new file mode 100644 index 00000000..c73df8ee --- /dev/null +++ b/islandora/tests/src/Kernel/VectorClockTest.php @@ -0,0 +1,54 @@ +entity = FedoraResource::create([ + "type" => "rdf_source", + "uid" => 1, + "name" => "Test Fixture", + "langcode" => "und", + "status" => 1, + ]); + $this->entity->save(); + + } + + /** + * Tests the basic behavior of the vector clock. + */ + public function testVectorClock() { + // Check the vclock is set to 0 when a new entity is created. + $this->assertTrue($this->entity->getVclock() == 0, "Vector clock initialized to zero."); + + // Edit the entity. + $this->entity->setName("Edited Test Fixture")->save(); + + // Check the vclock is incremented when the entity is updated. + $this->assertTrue($this->entity->getVclock() == 1, "Vector clock incremented on update."); + } + +} diff --git a/islandora_collection/config/install/rdf.mapping.fedora_resource_type.collection.yml b/islandora_collection/config/install/rdf.mapping.fedora_resource_type.collection.yml index 25d05a00..0ccef80c 100644 --- a/islandora_collection/config/install/rdf.mapping.fedora_resource_type.collection.yml +++ b/islandora_collection/config/install/rdf.mapping.fedora_resource_type.collection.yml @@ -40,6 +40,9 @@ fieldMappings: rdf_type: properties: - 'rdf:type' + vclock: + properties: + - 'islandora:vclock' uid: properties: - 'schema:author'