FOSSology  4.7.1
Open Source License Compliance by Open Source Software
DecisionImporterDataCreator.php
Go to the documentation of this file.
1 <?php
2 /*
3  Author: Gaurav Mishra <mishra.gaurav@siemens.com>
4  SPDX-FileCopyrightText: © 2022 Siemens AG
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
8 
14 namespace Fossology\DecisionImporter;
15 
24 use UnexpectedValueException;
25 
26 require_once "FoDecisionData.php";
27 
32 {
37  private $dbManager;
38 
43  private $agentDao;
44 
49  private $copyrightDao;
50 
55  private $licenseDao;
56 
61  private $uploadDao;
62 
67  private $clearingDao;
68 
73  private $userId;
74 
79  private $groupId;
80 
85  private $uploadId;
86 
97  {
98  $this->dbManager = $dbManager;
99  $this->agentDao = $agentDao;
100  $this->copyrightDao = $copyrightDao;
101  $this->licenseDao = $licenseDao;
102  $this->uploadDao = $uploadDao;
103  $this->clearingDao = $clearingDao;
104  }
105 
109  public function setUserId(int $userId): void
110  {
111  $this->userId = $userId;
112  }
113 
117  public function setGroupId(int $groupId): void
118  {
119  $this->groupId = $groupId;
120  }
121 
125  public function setUploadId(int $uploadId): void
126  {
127  $this->uploadId = $uploadId;
128  }
129 
136  public function createClearingDecisions(FoDecisionData &$reportData,
137  DecisionImporterAgent &$agentObj): void
138  {
139  $clearingDecisionList = $reportData->getClearingDecisionList();
140  $clearingEventList = $reportData->getClearingEventList();
141  $clearingDecisionEventList = $reportData->getClearingDecisionEventList();
142 
143  $i = 0;
144  foreach ($clearingDecisionList as $oldDecisionId => $decisionItem) {
145  if ($decisionItem["new_itemid"] !== null) {
146  $newCdId = $this->dbManager->insertTableRow("clearing_decision", [
147  "uploadtree_fk" => $decisionItem["new_itemid"],
148  "pfile_fk" => $decisionItem["new_pfile"],
149  "decision_type" => $decisionItem["decision_type"],
150  "group_fk" => $this->groupId,
151  "user_fk" => $this->userId,
152  "scope" => $decisionItem["scope"],
153  "date_added" => $decisionItem["date_added"]
154  ], __METHOD__ . ".insertCd", "clearing_decision_pk");
155  } else {
156  $newCdId = null;
157  }
158  $clearingDecisionList[$oldDecisionId]["new_decision"] = $newCdId;
159  $i++;
162  $i = 0;
163  }
164  }
165  if ($i != 0) {
166  $agentObj->heartbeat($i);
167  }
168 
169  $i = 0;
170  foreach ($clearingEventList as $oldEventId => $eventItem) {
171  if ($eventItem["new_itemid"] !== null) {
172  $newCeId = $this->dbManager->insertTableRow("clearing_event", [
173  "uploadtree_fk" => $eventItem["new_itemid"],
174  "rf_fk" => $eventItem["new_rfid"],
175  "removed" => $eventItem["removed"],
176  "user_fk" => $this->userId,
177  "group_fk" => $this->groupId,
178  "job_fk" => null,
179  "type_fk" => $eventItem["type_fk"],
180  "comment" => $eventItem["comment"],
181  "reportinfo" => $eventItem["reportinfo"],
182  "acknowledgement" => $eventItem["acknowledgement"],
183  "date_added" => $eventItem["date_added"]
184  ], __METHOD__ . ".insertCe", "clearing_event_pk");
185  } else {
186  $newCeId = null;
187  }
188  $clearingEventList[$oldEventId]["new_event"] = $newCeId;
189  $i++;
192  $i = 0;
193  }
194  }
195  if ($i != 0) {
196  $agentObj->heartbeat($i);
197  }
198 
199  foreach ($clearingDecisionEventList as $oldCdId => $ceList) {
200  $newCdId = $clearingDecisionList[$oldCdId]["new_decision"];
201  if ($newCdId === null) {
202  continue;
203  }
204  foreach ($ceList as $oldCeId) {
205  $newCeId = $clearingEventList[$oldCeId]["new_event"];
206  if ($newCeId === null) {
207  continue;
208  }
209  $this->dbManager->insertTableRow("clearing_decision_event", [
210  "clearing_decision_fk" => $newCdId,
211  "clearing_event_fk" => $newCeId
212  ], __METHOD__ . ".insertCdCe");
213  }
214  }
215  $agentObj->heartbeat(0);
216 
217  $reportData->setClearingDecisionList($clearingDecisionList)
218  ->setClearingEventList($clearingEventList);
219  }
220 
226  public function createReportData(FoDecisionData &$reportData): void
227  {
228  $reportInfo = $reportData->getReportInfo();
229  $assocParams = [
230  "upload_fk" => $this->uploadId,
231  "ri_ga_checkbox_selection" => $reportInfo["ri_ga_checkbox_selection"],
232  "ri_spdx_selection" => $reportInfo["ri_spdx_selection"],
233  "ri_excluded_obligations" => $reportInfo["ri_excluded_obligations"],
234  "ri_reviewed" => $reportInfo["ri_reviewed"],
235  "ri_footer" => $reportInfo["ri_footer"],
236  "ri_report_rel" => $reportInfo["ri_report_rel"],
237  "ri_community" => $reportInfo["ri_community"],
238  "ri_component" => $reportInfo["ri_component"],
239  "ri_version" => $reportInfo["ri_version"],
240  "ri_release_date" => $reportInfo["ri_release_date"],
241  "ri_sw360_link" => $reportInfo["ri_sw360_link"],
242  "ri_general_assesment" => $reportInfo["ri_general_assesment"],
243  "ri_ga_additional" => $reportInfo["ri_ga_additional"],
244  "ri_ga_risk" => $reportInfo["ri_ga_risk"],
245  "ri_department" => $reportInfo["ri_department"],
246  "ri_depnotes" => $reportInfo["ri_depnotes"],
247  "ri_exportnotes" => $reportInfo["ri_exportnotes"],
248  "ri_copyrightnotes" => $reportInfo["ri_copyrightnotes"],
249  "ri_unifiedcolumns" => $reportInfo["ri_unifiedcolumns"],
250  "ri_globaldecision" => $reportInfo["ri_globaldecision"],
251  "ri_component_id" => $reportInfo["ri_component_id"],
252  "ri_component_type" => $reportInfo["ri_component_type"]
253  ];
254  // Exports made before CycloneDX settings existed do not carry the key.
255  if (array_key_exists("ri_cyclonedx_selection", $reportInfo)) {
256  $cyclonedxSettings = CycloneDxSettings::fromReportInfo($reportInfo["ri_cyclonedx_selection"]);
257  $assocParams["ri_cyclonedx_selection"] = $cyclonedxSettings === null ? null :
258  $cyclonedxSettings->toReportInfo();
259  }
260  $existsSql = "SELECT ri_pk FROM report_info WHERE upload_fk = $1;";
261  $existsStatement = __METHOD__ . ".reportInfoExists";
262 
263  if ($this->dbManager->getSingleRow($existsSql, [$this->uploadId], $existsStatement)) {
264  $this->dbManager->updateTableRow("report_info", $assocParams, "upload_fk", $this->uploadId,
265  __METHOD__ . ".updateReportInfo");
266  } else {
267  $this->dbManager->insertTableRow("report_info", $assocParams, __METHOD__ . ".insertReportInfo");
268  }
269  }
270 
282  public function createCopyrightData(FoDecisionData &$reportData,
283  DecisionImporterAgent &$agentObj,
284  string $agentName, int $jobId): void
285  {
286  $type = $agentName;
287  if ($agentName == "copyright") {
288  $type = "statement";
289  }
290  $capitalizedAgentName = strtoupper(substr($agentName, 0, 1)) . substr($agentName, 1);
291  $cxListMethod = "get" . $capitalizedAgentName . "List";
292  $decisionListMethod = "get" . $capitalizedAgentName . "DecisionList";
293  $eventListMethod = "get" . $capitalizedAgentName . "EventList";
294  $cxList = $reportData->$cxListMethod();
295  $decisionList = $reportData->$decisionListMethod();
296  $eventList = $reportData->$eventListMethod();
297 
298  if (!$cxList and !$decisionList and !$eventList) {
299  // No relevant data in the report - nothing to do
300  return;
301  }
302 
303  if (!$this->agentDao->arsTableExists($agentName)) {
304  // FIXME This requires the user to manually run the respective agent to get past this point
305  throw new UnexpectedValueException("No agent '$agentName' exists on server.");
306  }
307  $latestAgentId = $this->agentDao->getCurrentAgentId($agentName);
308  $this->createCxJobs($agentName, $jobId, $latestAgentId);
309  $cxExistSql = "SELECT " . $agentName . "_pk FROM $agentName WHERE pfile_fk = $1 AND agent_fk = $2 AND hash = $3;";
310  $cxExistStatement = __METHOD__ . ".$agentName" . "Exist";
311 
312  $ceExistSql = "SELECT " . $agentName . "_event_pk FROM " . $agentName .
313  "_event WHERE uploadtree_fk = $1 AND hash = $2 AND is_enabled = $3;";
314  $ceExistStatement = __METHOD__ . ".$agentName" . "EventExist";
315 
316  $i = 0;
317  foreach ($cxList as $oldId => $cItem) {
318  $newCp = $this->dbManager->getSingleRow($cxExistSql, [
319  $cItem["new_pfile"],
320  $latestAgentId,
321  $cItem["hash"]
322  ], $cxExistStatement);
323  if (empty($newCp) && !empty($cItem["new_pfile"]) && !empty($cItem["hash"])) {
324  $newCp = $this->dbManager->insertTableRow($agentName, [
325  "agent_fk" => $latestAgentId,
326  "pfile_fk" => $cItem["new_pfile"],
327  "content" => $cItem["content"],
328  "type" => $type,
329  "hash" => $cItem["hash"],
330  "copy_startbyte" => $cItem["copy_startbyte"],
331  "copy_endbyte" => $cItem["copy_endbyte"]
332  ], __METHOD__ . ".insertCp." . $agentName, $agentName . "_pk");
333  } else {
334  $newCp = $newCp[$agentName . "_pk"];
335  }
336  $cxList[$oldId]["new_id"] = $newCp;
337  $i++;
340  $i = 0;
341  }
342  }
343  if ($i != 0) {
344  $agentObj->heartbeat($i);
345  }
346 
347  $i = 0;
348  foreach ($decisionList as $oldId => $decisionItem) {
349  $newDecision = $this->copyrightDao->saveDecision($agentName . "_decision", $decisionItem['new_pfile'],
350  $this->userId, $decisionItem['clearing_decision_type_fk'], $decisionItem['description'],
351  $decisionItem['textfinding'], $decisionItem['comment']);
352  $decisionList[$oldId]["new_id"] = $newDecision;
353  $i++;
356  $i = 0;
357  }
358  }
359  if ($i != 0) {
360  $agentObj->heartbeat($i);
361  }
362 
363  $i = 0;
364  foreach ($eventList as $eventItem) {
365  if ($eventItem["new_itemid"] == null) {
366  echo "ItemId of event hash " . $eventItem["hash"] . " is NULL\n";
367  continue;
368  }
369  $ceId = $this->dbManager->getSingleRow($ceExistSql, [
370  $eventItem["new_itemid"],
371  $eventItem["hash"],
372  $eventItem["is_enabled"]
373  ], $ceExistStatement);
374  if (empty($ceId)) {
375  $this->dbManager->insertTableRow($agentName . "_event", [
376  "upload_fk" => $this->uploadId,
377  "uploadtree_fk" => $eventItem["new_itemid"],
378  $agentName . "_fk" => $cxList[$eventItem["old_cpid"]]["new_id"],
379  "content" => $eventItem["content"],
380  "hash" => $eventItem["hash"],
381  "is_enabled" => $eventItem["is_enabled"],
382  "scope" => $eventItem["scope"]
383  ], __METHOD__ . ".insertCe." . $agentName);
384  }
385  $i++;
388  $i = 0;
389  }
390  }
391  if ($i != 0) {
392  $agentObj->heartbeat($i);
393  }
394 
395  $cxListMethod = "set" . $capitalizedAgentName . "List";
396  $reportData->$cxListMethod($cxList);
397  }
398 
407  private function createCxJobs(string $agentName, int $currentJobId, int $agentId): void
408  {
409  $scanJobProxy = new ScanJobProxy($this->agentDao, $this->uploadId);
410  $scanJobProxy->createAgentStatus(array($agentName));
411  $selectedScanners = $scanJobProxy->getLatestSuccessfulAgentIds();
412  if (!empty($selectedScanners)) {
413  return;
414  }
415  $markJobCompletedSql = "UPDATE jobqueue SET jq_end_bits = 1, jq_endtext = 'Completed', jq_endtime = NOW(), " .
416  "jq_starttime = NOW() WHERE jq_pk = $1;";
417  $markJobCompletedStatement = __METHOD__ . ".markComplete";
418 
419  $jqId = JobQueueAdd($currentJobId, $agentName, $this->uploadId, "no", NULL);
420  $this->dbManager->getSingleRow($markJobCompletedSql, [$jqId], $markJobCompletedStatement);
421 
422  $arsId = $this->agentDao->writeArsRecord($agentName, $agentId, $this->uploadId);
423  $this->agentDao->writeArsRecord($agentName, $agentId, $this->uploadId, $arsId, true);
424  }
425 
436  public function createMonkBulkData(FoDecisionData &$reportData,
437  DecisionImporterAgent &$agentObj): void
438  {
439  $licenseRefBulkList = $reportData->getLicenseRefBulkList();
440  $licenseSetBulkList = $reportData->getLicenseSetBulkList();
441  $highlightBulkList = $reportData->getHighlightBulk();
442  $clearingEventList = $reportData->getClearingEventList();
443 
444  // NOTE: Always run monkbulk on entire upload even if it was set for a folder, as it is done in reuser with bulk.
445  // BulkReuser::rerunBulkAndDeciderOnUpload() ¯\_(ツ)_/¯
446  $parentItem = $this->uploadDao->getUploadParent($this->uploadId);
447 
448  $i = 0;
449  foreach ($licenseRefBulkList as $oldId => $licenseRefBulkItem) {
450  $oldEventId = $this->getClearingEventForLrb($clearingEventList, $oldId);
451  if (empty($oldEventId)) {
452  echo "No clearing event for old LRB: $oldId\n";
453  continue;
454  }
455  $licenseRemovals = [];
456  foreach ($licenseSetBulkList[$oldId] as $licenseSetItem) {
457  $licenseRemovals[$licenseSetItem["new_rfid"]] = [
458  $licenseSetItem["removing"],
459  $licenseSetItem["comment"],
460  $licenseSetItem["reportinfo"],
461  $licenseSetItem["acknowledgement"],
462  ];
463  }
464 
465  $newLrbId = $this->licenseDao->insertBulkLicense($this->userId, $this->groupId, $parentItem, $licenseRemovals,
466  $licenseRefBulkItem["rf_text"], $licenseRefBulkItem["ignore_irrelevant"],
467  $licenseRefBulkItem["bulk_delimiters"], $licenseRefBulkItem["scan_findings"]);
468  $licenseRefBulkList[$oldId]["new_lrbid"] = $newLrbId;
469  $jobId = $this->createMonkBulkJobs($newLrbId);
470  $clearingEventList[$oldEventId]["new_lrbid"] = $newLrbId;
471  $clearingEventList[$oldEventId]["job_fk"] = $jobId;
472  $i++;
475  $i = 0;
476  }
477  }
478  if ($i != 0) {
479  $agentObj->heartbeat($i);
480  }
481 
482  $i = 0;
483  foreach ($clearingEventList as $clearingEventItem) {
484  if (array_key_exists("job_fk", $clearingEventItem)) {
485  $assocParams = [
486  "job_fk" => $clearingEventItem["job_fk"]
487  ];
488  $this->dbManager->updateTableRow("clearing_event", $assocParams, "clearing_event_pk",
489  $clearingEventItem["new_event"], __METHOD__ . ".updateCeJob");
490  $i++;
493  $i = 0;
494  }
495  }
496  }
497  if ($i != 0) {
498  $agentObj->heartbeat($i);
499  }
500 
501  $i = 0;
502  foreach ($highlightBulkList as $highlightBulkItem) {
503  $assocParams = [
504  "clearing_event_fk" => $clearingEventList[$highlightBulkItem["old_ceid"]]["new_event"],
505  "lrb_fk" => $licenseRefBulkList[$highlightBulkItem["old_lrbid"]]["new_lrbid"],
506  "start" => $highlightBulkItem["start"],
507  "len" => $highlightBulkItem["len"]
508  ];
509  $this->dbManager->insertTableRow("highlight_bulk", $assocParams, __METHOD__ . ".insertHighlightBulk");
510  $i++;
512  $agentObj->heartbeat(0);
513  $i = 0;
514  }
515  }
516 
517  $reportData->setLicenseRefBulkList($licenseRefBulkList)
518  ->setClearingEventList($clearingEventList);
519  }
520 
527  private function getClearingEventForLrb(array $clearingEventList, int $oldLrbId)
528  {
529  foreach ($clearingEventList as $index => $clearingEventId) {
530  if ($clearingEventId["old_lrbid"] == $oldLrbId) {
531  return $index;
532  }
533  }
534  return null;
535  }
536 
543  private function createMonkBulkJobs(int $bulkId): int
544  {
545  $markJobCompletedSql = "UPDATE jobqueue SET jq_end_bits = 1, jq_endtext = 'Completed', jq_endtime = NOW(), " .
546  "jq_starttime = NOW() WHERE jq_pk = $1;";
547  $markJobCompletedStatement = __METHOD__ . ".markComplete";
548 
549  $upload = $this->uploadDao->getUpload($this->uploadId);
550  $uploadName = $upload->getFilename();
551  $latestDeciderAgentId = $this->agentDao->getCurrentAgentId("deciderjob");
552  $latestMonkBulkAgentId = $this->agentDao->getCurrentAgentId("monkbulk");
553  $jobId = JobAddJob($this->userId, $this->groupId, $uploadName, $this->uploadId);
554 
555  $monkbulkJobId = JobQueueAdd($jobId, "monkbulk", $bulkId, "no", null);
556 
557  $deciderJobId = JobQueueAdd($jobId, "deciderjob", $this->uploadId, "no", [$monkbulkJobId]);
558 
559  $monkbulkArsId = $this->agentDao->writeArsRecord("monkbulk", $latestMonkBulkAgentId, $this->uploadId);
560  $this->agentDao->writeArsRecord("monkbulk", $latestDeciderAgentId, $this->uploadId, $monkbulkArsId, true);
561  $this->dbManager->getSingleRow($markJobCompletedSql, [$monkbulkJobId], $markJobCompletedStatement);
562 
563  $deciderArsId = $this->agentDao->writeArsRecord("deciderjob", $latestDeciderAgentId, $this->uploadId);
564  $this->agentDao->writeArsRecord("deciderjob", $latestDeciderAgentId, $this->uploadId, $deciderArsId, true);
565  $this->dbManager->getSingleRow($markJobCompletedSql, [$deciderJobId], $markJobCompletedStatement);
566 
567  return $jobId;
568  }
569 
576  public function createMainLicenses(FoDecisionData &$reportData, int $uploadId, int $groupId)
577  {
578  $mainLicenseList = $reportData->getMainLicenseList();
579  foreach ($mainLicenseList as $mainLicenseItem) {
580  $this->clearingDao->makeMainLicense($uploadId, $groupId, $mainLicenseItem["new_rfid"]);
581  }
582  }
583 }
Import decisions generated by Decision Exporter from JSON files.
createClearingDecisions(FoDecisionData &$reportData, DecisionImporterAgent &$agentObj)
createMainLicenses(FoDecisionData &$reportData, int $uploadId, int $groupId)
getClearingEventForLrb(array $clearingEventList, int $oldLrbId)
createCxJobs(string $agentName, int $currentJobId, int $agentId)
createCopyrightData(FoDecisionData &$reportData, DecisionImporterAgent &$agentObj, string $agentName, int $jobId)
Create copyright and sibling agent's related data in DB.
createMonkBulkData(FoDecisionData &$reportData, DecisionImporterAgent &$agentObj)
Create monkbulk findings from the report.
__construct(DbManager $dbManager, AgentDao $agentDao, CopyrightDao $copyrightDao, LicenseDao $licenseDao, UploadDao $uploadDao, ClearingDao $clearingDao)
setLicenseRefBulkList(array $license_ref_bulkList)
setClearingDecisionList(array $clearing_decisionList)
heartbeat($newProcessed)
Send hear beat to the scheduler.
Definition: Agent.php:203
CycloneDX export settings of a user (defaults) or of an upload.
JobQueueAdd($job_pk, $jq_type, $jq_args, $jq_runonpfile, $Depends, $host=NULL, $jq_cmd_args=NULL)
Insert a jobqueue + jobdepends records.
Definition: common-job.php:157
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16
FUNCTION char * strtoupper(char *s)
Helper function to upper case a string.
Definition: utils.c:103