Skip to content

Commit

Permalink
Queuing datastore imports on dataset creation/update (#137)
Browse files Browse the repository at this point in the history
  • Loading branch information
ketwaroo authored and fmizzell committed Jun 7, 2019
1 parent c9c5c8a commit 20045ce
Show file tree
Hide file tree
Showing 8 changed files with 812 additions and 166 deletions.
1 change: 1 addition & 0 deletions modules/custom/dkan_api/dkan_api.info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ dependencies:
- dkan_data
- basic_auth
- dkan_common
- dkan_datastore
package: DKAN
38 changes: 38 additions & 0 deletions modules/custom/dkan_api/src/Storage/DrupalNodeDataset.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

use Harvest\Storage\Storage;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\RfcLogLevel;

/**
* DrupalNodeDataset.
*/
class DrupalNodeDataset implements Storage {

use \Drupal\Core\Logger\LoggerChannelTrait;

/**
* Entity Type Manager.
*
Expand Down Expand Up @@ -150,12 +153,47 @@ public function store(string $data, string $id = NULL): string {
'field_json_metadata' => json_encode($data),
]);
$node->save();

$uuid = $node->uuid();
$this->enqueueDeferredImport($uuid);
return $node->uuid();
}

return NULL;
}

/**
* Enqueue the dataset for further processing.
*
* @param string $uuid
* Uuid of node.
*
* @todo pass import config.
*
* @return int|bool
* New queue ID or false on failure
*/
protected function enqueueDeferredImport(string $uuid) {

try {
// Using \Drupal::service() to avoid overloading constructor with single use dependencies.
/** @var \Drupal\dkan_datastore\Manager\DatastoreManagerBuilderHelper $managerBuilderHelper */
$managerBuilderHelper = \Drupal::service('dkan_datastore.manager.datastore_manager_builder_helper');

$resource = $managerBuilderHelper->newResourceFromEntity($uuid);

/** @var \Drupal\dkan_datastore\Manager\DeferredImportQueuer $deferredImporter */
$deferredImporter = \Drupal::service('dkan_datastore.manager.deferred_import_queuer');

return $deferredImporter->createDeferredResourceImport($uuid, $resource);
} catch (\Exception $e) {
$logger = $this->getLogger('dkan_api');

$logger->log(RfcLogLevel::ERROR, "Failed to enqueue dataset import for {$uuid}. Reason: " . $e->getMessage());
$logger->log(RfcLogLevel::DEBUG, $e->getTraceAsString());
}
}

/**
* Fetch node id of a current type given uuid.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@
use Drupal\dkan_api\Storage\DrupalNodeDataset;
use Drupal\node\NodeStorageInterface;
use Drupal\dkan_api\Storage\ThemeValueReferencer;
use Drupal\dkan_datastore\Manager\DatastoreManagerBuilderHelper;
use Drupal\dkan_datastore\Manager\DeferredImportQueuer;
use Dkan\Datastore\Resource;
use Psr\Log\LoggerInterface;
use Drupal\Core\Logger\RfcLogLevel;

/**
* Tests Drupal\dkan_api\Storage\DrupalNodeDataset.
*
* @coversDefaultClass \Drupal\dkan_api\Storage\DrupalNodeDataset
* @group dkan_api
* @author Yaasir Ketwaroo <yaasir.ketwaroo@semanticbits.com>
*/
class DrupalNodeDatasetTest extends DkanTestBase {

Expand Down Expand Up @@ -90,6 +94,112 @@ public function testGetType() {
$this->assertEquals($expected, $actual);
}

/**
* Tests EnqueueDeferredImport().
*/
public function testEnqueueDeferredImport() {
// Setup.
$mock = $this->getMockBuilder(DrupalNodeDataset::class)
->setMethods(NULL)
->disableOriginalConstructor()
->getMock();

$mockBuilderHelper = $this->getMockBuilder(DatastoreManagerBuilderHelper::class)
->setMethods(['newResourceFromEntity'])
->disableOriginalConstructor()
->getMock();

$mockDeferredImporter = $this->getMockBuilder(DeferredImportQueuer::class)
->setMethods(['createDeferredResourceImport'])
->disableOriginalConstructor()
->getMock();
$this->setActualContainer([
'dkan_datastore.manager.datastore_manager_builder_helper' => $mockBuilderHelper,
'dkan_datastore.manager.deferred_import_queuer' => $mockDeferredImporter,
]);

$mockResource = $this->createMock(Resource::class);
$uuid = uniqid('foo');
$expected = 42;

// Expect.
$mockBuilderHelper->expects($this->once())
->method('newResourceFromEntity')
->with($uuid)
->willReturn($mockResource);

$mockDeferredImporter->expects($this->once())
->method('createDeferredResourceImport')
->with($uuid, $mockResource)
->willReturn($expected);

// Assert.
$actual = $this->invokeProtectedMethod($mock, 'enqueueDeferredImport', $uuid);
$this->assertEquals($expected, $actual);
}

/**
* Tests EnqueueDeferredImport().
*/
public function testEnqueueDeferredImportOnException() {
// Setup.
$mock = $this->getMockBuilder(DrupalNodeDataset::class)
->setMethods(['getLogger'])
->disableOriginalConstructor()
->getMock();

$mockBuilderHelper = $this->getMockBuilder(DatastoreManagerBuilderHelper::class)
->setMethods(['newResourceFromEntity'])
->disableOriginalConstructor()
->getMock();

$mockDeferredImporter = $this->getMockBuilder(DeferredImportQueuer::class)
->setMethods(['createDeferredResourceImport'])
->disableOriginalConstructor()
->getMock();

$this->setActualContainer([
'dkan_datastore.manager.datastore_manager_builder_helper' => $mockBuilderHelper,
'dkan_datastore.manager.deferred_import_queuer' => $mockDeferredImporter,
]);

$mockLogger = $this->getMockBuilder(LoggerInterface::class)
->setMethods(['log'])
->disableOriginalConstructor()
->getMockForAbstractClass();

$uuid = uniqid('foo');
$exceptionMessage = 'something went fubar.';

// Expect.
$mockBuilderHelper->expects($this->once())
->method('newResourceFromEntity')
->with($uuid)
->willThrowException(new \Exception($exceptionMessage));

$mockDeferredImporter->expects($this->never())
->method('createDeferredResourceImport');

$mock->expects($this->once())
->method('getLogger')
->with('dkan_api')
->willReturn($mockLogger);

$mockLogger->expects($this->exactly(2))
->method('log')
->withConsecutive(
[RfcLogLevel::ERROR, "Failed to enqueue dataset import for {$uuid}. Reason: " .$exceptionMessage],
// value of trace may change depending of debugger so just assume it's a string.
[RfcLogLevel::DEBUG, $this->isType('string')]
);

// Assert.
$this->invokeProtectedMethod($mock, 'enqueueDeferredImport', $uuid);

}



/**
* Placeholder.
*/
Expand Down
3 changes: 3 additions & 0 deletions modules/custom/dkan_datastore/dkan_datastore.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ services:
class: Drupal\dkan_datastore\Manager\DatastoreManagerBuilder
arguments: ['@service_container']
shared: false
dkan_datastore.manager.datastore_manager_builder_helper:
class: Drupal\dkan_datastore\Manager\DatastoreManagerBuilderHelper
arguments: ['@service_container']
dkan_datastore.manager.deferred_import_queuer:
class: Drupal\dkan_datastore\Manager\DeferredImportQueuer

Loading

0 comments on commit 20045ce

Please sign in to comment.