Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert resource map to Drupal Entity API #4027

Merged
merged 46 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
a6e7940
compat layer for drupal entities
paul-m Sep 18, 2023
fdb96ef
Merge branch '2.x' into entity-abstract-database
paul-m Sep 19, 2023
b03a685
mapper
paul-m Sep 21, 2023
ba4247e
more entity change
paul-m Sep 21, 2023
3c1c39b
resourcemapper refactored
paul-m Sep 22, 2023
de6819f
still failing against testResourcePurgeDraft
paul-m Sep 23, 2023
4762a21
ouch I lost the work
paul-m Sep 23, 2023
269af2c
passing...........
paul-m Sep 24, 2023
7d94c52
Merge branch '2.x' into entity-abstract-database
paul-m Sep 24, 2023
35366d3
removed some cruft
paul-m Sep 24, 2023
36d5884
update hook, cs changes
paul-m Sep 24, 2023
969afd5
removed form
paul-m Sep 24, 2023
3090410
handy view, cs
paul-m Sep 24, 2023
bd2ea9a
remove view config
paul-m Sep 24, 2023
273b883
Merge branch '2.x' into entity-resource-mapping
paul-m Sep 28, 2023
eb470d6
no more jsonserializable
paul-m Sep 28, 2023
50eb803
Merge branch '2.x' into entity-resource-mapping
paul-m Oct 5, 2023
3f19925
Merge branch '2.x' into entity-resource-mapping
paul-m Oct 5, 2023
29fa209
Merge branch '2.x' into entity-resource-mapping
paul-m Oct 9, 2023
181dd76
Merge branch '2.x' into entity-resource-mapping
paul-m Nov 2, 2023
2399611
starting a test conversion
paul-m Nov 2, 2023
b0d0899
minor
paul-m Nov 2, 2023
dcf1e37
Merge branch '2.x' into entity-resource-mapping
paul-m Dec 12, 2023
2e8ebc4
some test tweaks
paul-m Dec 26, 2023
a46f173
Merge branch '2.x' into entity-resource-mapping
paul-m Dec 28, 2023
62c58da
minor
paul-m Dec 28, 2023
1154269
stopped half way through fixing tests
paul-m Dec 28, 2023
026d2a3
Merge branch '2.x' into entity-resource-mapping
paul-m Jan 3, 2024
0fc0496
tiny bit of test improvement
paul-m Jan 3, 2024
69c7392
consolidated mime type tests
paul-m Jan 5, 2024
3e136a5
Merge branch '2.x' into entity-resource-mapping
paul-m Jan 7, 2024
d4d9e3a
fixed localcopyofremote test
paul-m Jan 7, 2024
5c14a64
Merge branch '2.x' into entity-resource-mapping
paul-m Jan 9, 2024
364fcaa
entity does not need to be jsonencodable
paul-m Jan 9, 2024
f6b0985
fix some tests
paul-m Jan 10, 2024
c6d3c54
fix referencer for test
paul-m Jan 10, 2024
795115c
Merge branch '2.x' into entity-resource-mapping
paul-m Jan 11, 2024
6cf5880
revert unneeded change
paul-m Jan 11, 2024
0e22aa9
Merge branch '2.x' into entity-resource-mapping
paul-m Jan 26, 2024
1791afb
important documentation
paul-m Jan 26, 2024
c14bf82
Merge branch '2.x' into entity-resource-mapping
paul-m Jan 29, 2024
f58eeb5
deprecates DataResource::createFromRecord, better type hints
paul-m Jan 30, 2024
d4206fb
CS
paul-m Jan 30, 2024
5b7a5cb
minor nits
paul-m Jan 30, 2024
b1b8ab7
Merge branch '2.x' into entity-resource-mapping
paul-m Jan 31, 2024
a5769e7
inline comment updates
paul-m Feb 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 42 additions & 2 deletions modules/common/src/DataResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Drupal\datastore\DatastoreResource;
use Drupal\datastore\Service\ResourceLocalizer;
use Drupal\metastore\ResourceMappingInterface;
use Procrastinator\JsonSerializeTrait;

/**
Expand All @@ -17,10 +18,10 @@
* Currently, the allowable perspectives are:
* - 'source' which represents a CSV file somewhere on the internet. In this
* case the file path will be an http:// URL.
* - 'local_path' which represents the same CSV file as a source file, but
* - 'local_file' which represents the same CSV file as a source file, but
* stored locally in the file system. The file path will be a local URI,
* probably in the public:// scheme.
* - 'local_url' which also can exist.
* - 'local_url' which is the 'hostified' version of the local URL to the file.
*
* Feed these various permutations of the DataResource object to the
* ResourceMapper, and it will store these differences in a database table.
Expand All @@ -39,6 +40,8 @@
* For more details refer to the methods governing these behaviors:
* 1. Resource::createNewVersion()
* 2. Resource::createNewPerspective()
*
* @see \Drupal\metastore\Entity\ResourceMapping
*/
class DataResource implements \JsonSerializable {

Expand Down Expand Up @@ -123,6 +126,10 @@ public function __construct($file_path, $mimeType, $perspective = self::DEFAULT_
*
* @return \Drupal\common\DataResource
* DataResource object.
*
* @deprecated Use DataResource::createFromEntity() instead.
*
* @see self::createFromEntity()
*/
public static function createFromRecord(object $record): DataResource {
$resource = new static($record->filePath, $record->mimeType, $record->perspective);
Expand All @@ -133,6 +140,28 @@ public static function createFromRecord(object $record): DataResource {
return $resource;
}

/**
* Create a DataResource object from a Drupal entity.
*
* @param \Drupal\metastore\ResourceMappingInterface $mapping
* A resource_mapping entity.
*
* @return \Drupal\common\DataResource
* DataResource object.
*/
public static function createFromEntity(ResourceMappingInterface $mapping): DataResource {
$resource = new static(
$mapping->get('filePath')->getString(),
$mapping->get('mimeType')->getString(),
$mapping->get('perspective')->getString()
);
// MD5 of record's file path can differ from the MD5 generated in the
// constructor, so we have to explicitly set the identifier.
$resource->identifier = $mapping->get('identifier')->getString();
$resource->version = $mapping->get('version')->getString();
return $resource;
}

/**
* Clone the current resource with a new version identifier.
*
Expand Down Expand Up @@ -243,6 +272,17 @@ public function getPerspective() {
return $this->perspective;
}

/**
* Get the checksum for this resource.
*
* @return string|null
* The checksum for the local file perspective. NULL if it has not yet been
* computed, or if this resource is a different perspective.
*/
public function getChecksum(): ?string {
return $this->checksum;
}

/**
* Get a unique identifier for this data resource.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Drupal\common\DataResource;
use Drupal\common\FileFetcher\FileFetcherRemoteUseExisting;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\datastore\Service\ResourceLocalizer;
use Drupal\Tests\BrowserTestBase;
use FileFetcher\FileFetcher;
Expand Down Expand Up @@ -45,11 +46,14 @@ public function test() {

$identifier = uniqid();

// Get mapping entity storage.
/** @var \Drupal\Core\Entity\EntityStorageInterface $mapping_entity_storage */
$mapping_entity_storage = $this->container
->get('entity_type.manager')
->getStorage('resource_mapping');

// There should be no mapper records.
/** @var \Drupal\metastore\ResourceMapper $resource_mapper */
$resource_mapper = $this->container->get('dkan.metastore.resource_mapper');
$mapping_store = $resource_mapper->getStore();
$this->assertEquals(0, $mapping_store->count());
$this->assertEquals(0, $this->getEntityCount($mapping_entity_storage));

// Post our dataset.
/** @var \Drupal\metastore\MetastoreService $metastore_service */
Expand All @@ -63,25 +67,28 @@ public function test() {
);

// 1 mapping after posting the datastore.
$this->assertEquals(1, $mapping_store->count());
$this->assertEquals(1, $this->getEntityCount($mapping_entity_storage));

// Get our resource info from the dataset info service.
/** @var \Drupal\common\DatasetInfo $dataset_info_service */
$dataset_info_service = $this->container->get('dkan.common.dataset_info');
$info = $dataset_info_service->gather($identifier);

// Having gotten the info, there should still only be 1 record.
$this->assertEquals(1, $mapping_store->count());
$this->assertEquals(1, $this->getEntityCount($mapping_entity_storage));

// Let's interrogate it. It should be a source mapping.
$all_mappings = $mapping_store->retrieveAll();
$mapping = $mapping_store->retrieve(reset($all_mappings));
$all_mapping_ids = $this->getAllEntityIds($mapping_entity_storage);
/** @var \Drupal\Core\Entity\EntityInterface $mapping */
$mapping = $mapping_entity_storage->load(reset($all_mapping_ids));
$this->assertEquals(
DataResource::DEFAULT_SOURCE_PERSPECTIVE,
$mapping->perspective
$mapping->get('perspective')->getString()
);

// Now let's ask the mapper instead of its storage.
/** @var \Drupal\metastore\ResourceMapper $resource_mapper */
$resource_mapper = $this->container->get('dkan.metastore.resource_mapper');
$this->assertNotNull(
$resource_id = $info['latest_revision']['distributions'][0]['resource_id'] ?? NULL
);
Expand All @@ -90,7 +97,7 @@ public function test() {
$source_resource = $resource_mapper->get($resource_id)
);
// Getting the source resource should not change the record count.
$this->assertEquals(1, $mapping_store->count());
$this->assertEquals(1, $this->getEntityCount($mapping_entity_storage));
// No local file perspective yet.
$this->assertNull($resource_mapper->get(
$resource_id,
Expand Down Expand Up @@ -157,7 +164,7 @@ public function test() {
);

// Now there should be three mappings.
$this->assertEquals(3, $mapping_store->count());
$this->assertEquals(3, $this->getEntityCount($mapping_entity_storage));
// Get the info again after localization.
$localized_info = $dataset_info_service->gather($identifier);
$this->assertNotEquals($localized_info, $info);
Expand All @@ -167,6 +174,37 @@ public function test() {
);
}

/**
* Count the number of entities present for the given storage.
*
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The entity storage object.
*
* @return int
* The count of arrays present in the storage.
*/
protected function getEntityCount(EntityStorageInterface $storage) {
return $storage->getQuery()
->count()
->accessCheck(FALSE)
->execute();
}

/**
* Get all the IDs available for the given entity storage.
*
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The entity storage object.
*
* @return array
* Array of entity IDs for all the entities in the storage.
*/
protected function getAllEntityIds(EntityStorageInterface $storage) {
return $storage->getQuery()
->accessCheck(FALSE)
->execute();
}

/**
* Generate dataset metadata, possibly with multiple distributions.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class ImportQueueWorkerTest extends KernelTestBase {
];

public function testErrorPath() {
$this->installEntitySchema('resource_mapping');

// The result we'll mock to come from the datastore service.
$result = new Result();
$result->setStatus(Result::ERROR);
Expand Down Expand Up @@ -79,6 +81,7 @@ public function testErrorPath() {
}

public function testRequeue() {
$this->installEntitySchema('resource_mapping');
// The result we'll mock to come from the datastore service.
$result = new Result();
$result->setStatus(Result::STOPPED);
Expand Down Expand Up @@ -166,6 +169,7 @@ public function testProcessItemAlreadyImported() {
* @covers ::processItem
*/
public function testProcessItemImportException() {
$this->installEntitySchema('resource_mapping');
// Mock the logger so we can tell when the error occurs.
$logger = $this->getMockForAbstractClass(LoggerChannelInterface::class);
// We expect an error to be logged, and we set an expectation for the message.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ class LocalizeQueueWorkerTest extends KernelTestBase {
'node',
];

protected function setUp() : void {
parent::setUp();
$this->installEntitySchema('resource_mapping');
}

public function provideUseExisting() {
return [
'Use existing localized file' => [TRUE],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ class ImportInfoTest extends KernelTestBase {

protected const SOURCE_URL = 'https://dkan-default-content-files.s3.amazonaws.com/phpunit/district_centerpoints_small.csv';

protected function setUp() : void {
parent::setUp();
$this->installEntitySchema('resource_mapping');
}

public function testFileSize() {
$source_resource = new DataResource(
self::SOURCE_URL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ class ResourceLocalizerTest extends KernelTestBase {

protected const SOURCE_URL = 'https://dkan-default-content-files.s3.amazonaws.com/phpunit/district_centerpoints_small.csv';

protected function setUp() : void {
parent::setUp();
// All our tests need the resource_mapping entity.
$this->installEntitySchema('resource_mapping');
}

public function testNoResourceFound() {
$service = $this->container->get('dkan.datastore.service.resource_localizer');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ class UseLocalWithPrepareLocalizeTest extends KernelTestBase {

protected const SOURCE_URL = 'https://dkan-default-content-files.s3.amazonaws.com/phpunit/district_centerpoints_small.csv';

protected function setUp() : void {
parent::setUp();
$this->installEntitySchema('resource_mapping');
}

public function test() {
$this->installConfig(['common']);

Expand Down
13 changes: 13 additions & 0 deletions modules/metastore/metastore.install
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,16 @@ function metastore_update_8007() {
$config = \Drupal::service('config.factory')->getEditable('node.type.data');
$config->set('preview_mode', 1)->save();
}

/**
* Ensure the entity manager knows about resource_mapping entities.
*
* Note: The dkan_metastore_resource_mapper table might already exist in your
* database. The resource_mapping entity is designed to use it without
* modification.
*/
function metastore_update_8008(&$sandbox) {
\Drupal::entityTypeManager()->clearCachedDefinitions();
\Drupal::entityDefinitionUpdateManager()
->installEntityType(\Drupal::entityTypeManager()->getDefinition('resource_mapping'));
}
4 changes: 4 additions & 0 deletions modules/metastore/metastore.permissions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@
description: 'Administer data dictionary settings'



administer resource mapping:
title: 'Administer resource mapping settings'
restrict access: true
2 changes: 1 addition & 1 deletion modules/metastore/metastore.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ services:
class: \Drupal\metastore\ResourceMapper
arguments:
- '@dkan.metastore.resource_mapper_database_table'
- '@event_dispatcher'
- '@entity_type.manager'

dkan.metastore.resource_mapper_database_table:
class: \Drupal\metastore\Storage\ResourceMapperDatabaseTable
Expand Down