Open Data Catalog v2.0.0
Service.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Drupal\harvest;
4 
5 use Contracts\BulkRetrieverInterface;
6 use Contracts\FactoryInterface;
7 use Contracts\StorerInterface;
8 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
9 use Drupal\Core\Entity\EntityTypeManager;
12 use Harvest\ETL\Factory;
13 use Harvest\Harvester as DkanHarvester;
14 use Symfony\Component\DependencyInjection\ContainerInterface;
15 
19 class Service implements ContainerInjectionInterface {
20 
21  use LoggerTrait;
22  use OrphanDatasetsProcessor;
23 
24  private $storeFactory;
25 
31  private $metastore;
32 
38  private $entityTypeManager;
39 
45  public static function create(ContainerInterface $container) {
46  return new self(
47  $container->get("dkan.harvest.storage.database_table"),
48  $container->get('dkan.metastore.service'),
49  $container->get('entity_type.manager')
50  );
51  }
52 
56  public function __construct(FactoryInterface $storeFactory, Metastore $metastore, EntityTypeManager $entityTypeManager) {
57  $this->storeFactory = $storeFactory;
58  $this->metastore = $metastore;
59  $this->entityTypeManager = $entityTypeManager;
60  }
61 
68  public function getAllHarvestIds() {
69  $store = $this->storeFactory->getInstance("harvest_plans");
70 
71  if ($store instanceof BulkRetrieverInterface) {
72  return $store->retrieveAll();
73  }
74  throw new \Exception("The store created by {get_class($this->storeFactory)} does not implement {BulkRetrieverInterface::class}");
75  }
76 
88  public function getHarvestPlan($plan_id) {
89  $store = $this->storeFactory->getInstance("harvest_plans");
90 
91  if ($store instanceof BulkRetrieverInterface) {
92  return $store->retrieve($plan_id);
93  }
94  throw new \Exception("The store created by {get_class($this->storeFactory)} does not implement {RetrieverInterface::class}");
95  }
96 
109  public function registerHarvest($plan) {
110 
111  $this->validateHarvestPlan($plan);
112 
113  $store = $this->storeFactory->getInstance("harvest_plans");
114 
115  if ($store instanceof StorerInterface) {
116  return $store->store(json_encode($plan), $plan->identifier);
117  }
118  throw new \Exception("The store created by {get_class($this->storeFactory)} does not implement {StorerInterface::class}");
119  }
120 
130  public function deregisterHarvest(string $id) {
131  try {
132  $this->revertHarvest($id);
133  }
134  catch (\Exception $e) {
135  }
136 
137  $plan_store = $this->storeFactory->getInstance("harvest_plans");
138 
139  return $plan_store->remove($id);
140  }
141 
147  public function revertHarvest($id) {
148  $run_store = $this->storeFactory->getInstance("harvest_{$id}_runs");
149  if (!method_exists($run_store, "destruct")) {
150  throw new \Exception("Storage of class " . get_class($run_store) . " does not implement destruct method.");
151  }
152  $run_store->destruct();
153  $harvester = $this->getHarvester($id);
154  return $harvester->revert();
155  }
156 
160  public function runHarvest($id) {
161  $harvester = $this->getHarvester($id);
162 
163  $result = $harvester->harvest();
164  if (is_null($result['status']['extracted_items_ids'])) {
165  throw new \Exception("No items found to extract, review your harvest plan.");
166  }
167  $result['status']['orphan_ids'] = $this->getOrphanIdsFromResult($id, $result['status']['extracted_items_ids']);
168  $this->processOrphanIds($result['status']['orphan_ids']);
169 
170  $run_store = $this->storeFactory->getInstance("harvest_{$id}_runs");
171  $current_time = time();
172  $run_store->store(json_encode($result), "{$current_time}");
173 
174  return $result;
175  }
176 
183  public function getHarvestRunInfo($id, $runId) {
184  $allRuns = $this->getAllHarvestRunInfo($id);
185  $found = array_search($runId, $allRuns);
186 
187  if ($found !== FALSE) {
188  $run_store = $this->storeFactory->getInstance("harvest_{$id}_runs");
189  return $run_store->retrieve($runId);
190  }
191 
192  return FALSE;
193  }
194 
198  public function getAllHarvestRunInfo($id) {
199  $run_store = $this->storeFactory->getInstance("harvest_{$id}_runs");
200  $runs = $run_store->retrieveAll();
201  return $runs;
202  }
203 
210  private function getLastHarvestRunId(string $id) {
211  $runs = $this->getAllHarvestRunInfo($id);
212  rsort($runs);
213  return reset($runs);
214  }
215 
225  public function publish(string $id): array {
226 
227  $lastRunInfoObj = $this->getLastRunInfoObj($id);
228  if (!isset($lastRunInfoObj->status->extracted_items_ids)) {
229  return [];
230  }
231 
232  return $this->publishHelper($id, $lastRunInfoObj->status);
233  }
234 
238  private function getLastRunInfoObj(string $harvestId) {
239  $lastRunId = $this->getLastHarvestRunId($harvestId);
240  $lastRunInfoJsonString = $this->getHarvestRunInfo($harvestId, $lastRunId);
241  return json_decode($lastRunInfoJsonString);
242  }
243 
247  private function publishHelper(string $harvestId, $lastRunStatus): array {
248  $publishedIdentifiers = [];
249 
250  foreach ($lastRunStatus->extracted_items_ids as $uuid) {
251  try {
252  if ($this->metastorePublishHelper($lastRunStatus, $uuid)) {
253  $publishedIdentifiers[] = $uuid;
254  }
255  }
256  catch (\Exception $e) {
257  $this->error("Error publishing dataset {$uuid} in harvest {$harvestId}: {$e->getMessage()}");
258  }
259  }
260 
261  return $publishedIdentifiers;
262  }
263 
267  private function metastorePublishHelper($runInfoStatus, string $uuid): bool {
268  return isset($runInfoStatus->load) &&
269  $runInfoStatus->load->{$uuid} &&
270  $runInfoStatus->load->{$uuid} != 'FAILURE' &&
271  $this->metastore->publish('dataset', $uuid);
272  }
273 
283  public function validateHarvestPlan($plan) {
284  return Factory::validateHarvestPlan($plan);
285  }
286 
290  private function getHarvester($id) {
291  $plan_store = $this->storeFactory->getInstance("harvest_plans");
292  $harvestPlan = json_decode($plan_store->retrieve($id));
293  $item_store = $this->storeFactory->getInstance("harvest_{$id}_items");
294  $hash_store = $this->storeFactory->getInstance("harvest_{$id}_hashes");
295  return $this->getDkanHarvesterInstance($harvestPlan, $item_store, $hash_store);
296  }
297 
303  protected function getDkanHarvesterInstance($harvestPlan, $item_store, $hash_store) {
304  return new DkanHarvester(new Factory($harvestPlan, $item_store, $hash_store));
305  }
306 
307 }
Drupal\common\LoggerTrait
trait LoggerTrait
Definition: LoggerTrait.php:11
Drupal\harvest\Service\registerHarvest
registerHarvest($plan)
Definition: Service.php:109
Drupal\harvest
Drupal\harvest\Service\getAllHarvestIds
getAllHarvestIds()
Definition: Service.php:68
Drupal\harvest\Service\validateHarvestPlan
validateHarvestPlan($plan)
Definition: Service.php:283
Drupal\harvest\Service
Definition: Service.php:19
Drupal\harvest\Service\publish
publish(string $id)
Definition: Service.php:225
Drupal\harvest\Service\revertHarvest
revertHarvest($id)
Definition: Service.php:147
Drupal\harvest\Service\getHarvestPlan
getHarvestPlan($plan_id)
Definition: Service.php:88
Drupal\metastore\Service
Definition: Uuid5.php:5
Drupal\harvest\Service\getDkanHarvesterInstance
getDkanHarvesterInstance($harvestPlan, $item_store, $hash_store)
Definition: Service.php:303
Drupal\harvest\Service\getAllHarvestRunInfo
getAllHarvestRunInfo($id)
Definition: Service.php:198
Drupal\harvest\Service\getHarvestRunInfo
getHarvestRunInfo($id, $runId)
Definition: Service.php:183
Drupal\harvest\Service\create
static create(ContainerInterface $container)
Definition: Service.php:45
Drupal\harvest\Service\deregisterHarvest
deregisterHarvest(string $id)
Definition: Service.php:130
Drupal\harvest\Service\runHarvest
runHarvest($id)
Definition: Service.php:160
Drupal\harvest\Service\__construct
__construct(FactoryInterface $storeFactory, Metastore $metastore, EntityTypeManager $entityTypeManager)
Definition: Service.php:56