Skip to content

Commit

Permalink
Harvest status page should reflect all registered harvests (#4048)
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-m authored Nov 29, 2023
1 parent 91ef1b5 commit afa9734
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 33 deletions.
9 changes: 9 additions & 0 deletions modules/harvest/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ table.dashboard-datasets td.done
background-color: #f3faef;
}

/**
* Waiting.
*/
table.dashboard-harvests td.registered
{
color: #5c5e1c;
background-color: #faf8ef;
}

/*
* Warning.
*/
Expand Down
68 changes: 48 additions & 20 deletions modules/harvest/src/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

namespace Drupal\harvest;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Link;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Controller.
*/
class DashboardController {
class DashboardController implements ContainerInjectionInterface {

use StringTranslationTrait;

Expand All @@ -25,13 +27,22 @@ class DashboardController {
*
* @var \Drupal\harvest\HarvestService
*/
protected $harvest;
protected $harvestService;

/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('dkan.harvest.service')
);
}

/**
* Controller constructor.
*/
public function __construct() {
$this->harvest = \Drupal::service('dkan.harvest.service');
public function __construct(HarvestService $harvestService) {
$this->harvestService = $harvestService;
}

/**
Expand All @@ -42,15 +53,17 @@ public function harvests(): array {
date_default_timezone_set(date_default_timezone_get());

$rows = [];
foreach ($this->harvest->getAllHarvestIds() as $harvestId) {
// @todo Make Harvest Service's private getLastHarvestRunId() public,
// And replace 7-8 cases where we recreate it.
$runIds = $this->harvest->getAllHarvestRunInfo($harvestId);

if ($runId = end($runIds)) {
$info = json_decode($this->harvest->getHarvestRunInfo($harvestId, $runId));
foreach ($this->harvestService->getAllHarvestIds() as $harvestPlanId) {
if ($runId = $this->harvestService->getLastHarvestRunId($harvestPlanId)) {
// There is a run identifier, so we should get that info.
$info = json_decode($this->harvestService->getHarvestRunInfo($harvestPlanId, $runId));

$rows[] = $this->buildHarvestRow($harvestId, $runId, $info);
$rows[] = $this->buildHarvestRow($harvestPlanId, $runId, $info);
}
else {
// There is no recent run identifier, so we should display some default
// info to the user.
$rows[] = $this->buildHarvestRow($harvestPlanId, '', NULL);
}
}

Expand All @@ -60,25 +73,40 @@ public function harvests(): array {
'#rows' => $rows,
'#attributes' => ['class' => 'dashboard-harvests'],
'#attached' => ['library' => ['harvest/style']],
'#empty' => "No harvests found",
'#empty' => 'No harvests found',
];
}

/**
* Private.
*/
private function buildHarvestRow(string $harvestId, string $runId, $info) {
$url = Url::fromRoute('datastore.datasets_import_status_dashboard', ['harvest_id' => $harvestId]);
private function buildHarvestRow(string $harvestId, string $runId, $info): array {
$url = Url::fromRoute(
'datastore.datasets_import_status_dashboard',
['harvest_id' => $harvestId]
);

return [
// Default values if there is no run information. This will show the harvest
// in the list, even if there is no run status to report.
$row = [
'harvest_link' => Link::fromTextAndUrl($harvestId, $url),
'extract_status' => [
'data' => $info->status->extract,
'class' => strtolower($info->status->extract),
'data' => 'REGISTERED',
'class' => 'registered',
],
'last_run' => date('m/d/y H:m:s T', $runId),
'dataset_count' => count(array_keys((array) $info->status->load)),
'last_run' => 'never',
'dataset_count' => 'unknown',
];
// Add run information if available.
if ($info) {
$row['extract_status'] = [
'data' => $info->status->extract,
'class' => strtolower($info->status->extract),
];
$row['last_run'] = date('m/d/y H:m:s T', $runId);
$row['dataset_count'] = count(array_keys((array) $info->status->load));
}
return $row;
}

}
13 changes: 9 additions & 4 deletions modules/harvest/src/HarvestService.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,18 @@ public function getAllHarvestRunInfo($id) {
}

/**
* Get a harvest's most recent run identifier, i.e. timestamp.
* Get a harvest's most recent run identifier.
*
* @param string $id
* Since the run record id is a timestamp, we can sort on the id.
*
* @param string $planId
* The harvest identifier.
*
* @return string
* The most recent harvest run record identifier.
*/
private function getLastHarvestRunId(string $id) {
$runs = $this->getAllHarvestRunInfo($id);
public function getLastHarvestRunId(string $planId) {
$runs = $this->getAllHarvestRunInfo($planId);
rsort($runs);
return reset($runs);
}
Expand Down
66 changes: 66 additions & 0 deletions modules/harvest/tests/src/Kernel/DashboardControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace Drupal\Tests\harvest\Kernel;

use Drupal\harvest\DashboardController;
use Drupal\KernelTests\KernelTestBase;
use Harvest\ETL\Extract\DataJson;
use Harvest\ETL\Load\Simple;

/**
* @covers \Drupal\harvest\DashboardController
* @coversDefaultClass \Drupal\harvest\DashboardController
*
* @group dkan
* @group harvest
* @group kernel
*/
class DashboardControllerTest extends KernelTestBase {

protected static $modules = [
'common',
'harvest',
'metastore',
];

public function testRegisteredPlan() {
/** @var \Drupal\harvest\HarvestService $harvest_service */
$harvest_service = $this->container->get('dkan.harvest.service');

$dashboard_controller = DashboardController::create($this->container);

// There are no registered harvests, so there should be zero rows. We also
// verify the empty table value.
$render_array = $dashboard_controller->harvests();
$this->assertCount(0, $render_array['#rows'] ?? NULL);
$this->assertEquals('No harvests found', $render_array['#empty'] ?? NULL);

// Register a harvest plan but don't run it...
$plan_identifier = 'test_plan';
$plan = (object) [
'identifier' => $plan_identifier,
'extract' => (object) [
'type' => DataJson::class,
'uri' => 'file://' . __DIR__ . '/../../files/data.json',
],
'transforms' => [],
'load' => (object) [
'type' => Simple::class,
],
];
$this->assertNotNull($harvest_service->registerHarvest($plan));

// Revisit the dashboard. It should show the registered harvest.
$render_array = $dashboard_controller->harvests();
$this->assertCount(1, $render_array['#rows'] ?? NULL);
$this->assertNotNull($row = $render_array['#rows'][0] ?? NULL);
/** @var \Drupal\Core\Link $link */
$this->assertNotNull($link = $row['harvest_link'] ?? NULL);
$this->assertEquals($plan_identifier, $link->getText());
// Harvest was registered, but never run.
$this->assertEquals('REGISTERED', $row['extract_status']['data'] ?? NULL);
$this->assertEquals('never', $row['last_run'] ?? NULL);
$this->assertEquals('unknown', $row['dataset_count'] ?? NULL);
}

}
12 changes: 3 additions & 9 deletions modules/harvest/tests/src/Unit/DashboardControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ public function testNoHarvests() {
->add(HarvestService::class, 'getAllHarvestIds', [])
->getMock();

\Drupal::setContainer($container);

$controller = new DashboardController();
$controller = DashboardController::create($container);
$response = $controller->harvests();

$json = json_encode($response);
Expand All @@ -36,9 +34,7 @@ public function testRegisteredHarvest() {
->add(HarvestService::class, 'getAllHarvestRunInfo', [])
->getMock();

\Drupal::setContainer($container);

$controller = new DashboardController();
$controller = DashboardController::create($container);
$response = $controller->harvests();

$json = json_encode($response);
Expand All @@ -56,9 +52,7 @@ public function testGoodHarvestRun() {
->add(HarvestService::class, 'getAllHarvestRunInfo', [$time])
->getMock();

\Drupal::setContainer($container);

$controller = new DashboardController();
$controller = DashboardController::create($container);
$response = $controller->harvests();

$json = json_encode((array)$response);
Expand Down

0 comments on commit afa9734

Please sign in to comment.