FOSSology  4.5.0-rc1
Open Source License Compliance by Open Source Software
softwareHeritageAgent.php
Go to the documentation of this file.
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2019 Sandip Kumar Bhuyan <sandipbhuyan@gmail.com>
4  SPDX-FileCopyrightText: © 2020 Siemens AG
5  Author: Sandip Kumar Bhuyan<sandipbhuyan@gmail.com>,
6  Shaheem Azmal M MD<shaheem.azmal@siemens.com>
7 
8  SPDX-License-Identifier: GPL-2.0-only
9 */
10 
11 namespace Fossology\SoftwareHeritage;
12 
20 use GuzzleHttp\Psr7;
21 use GuzzleHttp\Exception\RequestException;
22 
23 include_once(__DIR__ . "/version.php");
24 
32 {
36  private $uploadDao;
37 
41  private $licenseDao;
42 
47  private $configuration;
48 
53  private $dbManeger;
54 
59  protected $agentDao;
60 
65  private $softwareHeritageDao;
66 
71  function __construct()
72  {
73  global $SysConf;
74  parent::__construct(SOFTWARE_HERITAGE_AGENT_NAME, AGENT_VERSION, AGENT_REV);
75  $this->uploadDao = $this->container->get('dao.upload');
76  $this->licenseDao = $this->container->get('dao.license');
77  $this->dbManeger = $this->container->get('db.manager');
78  $this->agentDao = $this->container->get('dao.agent');
79  $this->softwareHeritageDao = $this->container->get('dao.softwareHeritage');
80  $sysconfig = $SysConf['SYSCONFIG'];
81  $this->configuration = [
82  'url' => trim($sysconfig['SwhURL']),
83  'uri' => trim($sysconfig['SwhBaseURL']),
84  'content' => trim($sysconfig['SwhContent']),
85  'maxtime' => intval($sysconfig['SwhSleep']),
86  'token' => trim($sysconfig['SwhToken'])
87  ];
88 
89  $this->guzzleClient = HttpUtils::getGuzzleClient($SysConf, $this->configuration['url'], $this->configuration['token']);
90  }
91 
99  function processUploadId($uploadId)
100  {
101  $itemTreeBounds = $this->uploadDao->getParentItemBounds($uploadId);
102  $pfileFileDetails = $this->uploadDao->getPFileDataPerFileName($itemTreeBounds);
103  $pfileFks = $this->softwareHeritageDao->getSoftwareHeritagePfileFk($uploadId);
104  $agentId = $this->agentDao->getCurrentAgentId("softwareHeritage");
105  $maxTime = $this->configuration['maxtime'];
106  $maxTime = ($maxTime < 2) ? 2 : $maxTime;
107  foreach ($pfileFileDetails as $pfileDetail) {
108  if (!in_array($pfileDetail['pfile_pk'], array_column($pfileFks, 'pfile_fk'))) {
109  $this->processEachPfileForSWH($pfileDetail, $agentId, $maxTime);
110  }
111  $this->heartbeat(1);
112  }
113  return true;
114  }
115 
123  function processEachPfileForSWH($pfileDetail, $agentId, $maxTime)
124  {
125  list ($currentStatus, $currentResult) = $this->getSoftwareHeritageLicense($pfileDetail['sha256']);
126  if (SoftwareHeritageDao::SWH_RATELIMIT_EXCEED == $currentStatus) {
127  $this->heartbeat(0); //Fake heartbeat to keep the agent alive.
128  $timeToReset = $currentResult - time();
129  print "INFO :Software Heritage X-RateLimit-Limit reached. Next slot unlocks in ".gmdate("H:i:s", $timeToReset)."\n";
130  if ($timeToReset > $maxTime) {
131  sleep($maxTime);
132  } else {
133  sleep($timeToReset);
134  }
135  $this->processEachPfileForSWH($pfileDetail, $agentId, $maxTime);
136  } else {
137  $this->insertSoftwareHeritageRecord($pfileDetail['pfile_pk'], $currentResult, $agentId, $currentStatus);
138  }
139 
140  return true;
141  }
142 
149  protected function getSoftwareHeritageLicense($sha256)
150  {
151  $sha256 = strtolower($sha256);
152  $URIToGetContent = $this->configuration['uri'] . $sha256;
153  $URIToGetLicenses = $URIToGetContent . $this->configuration['content'];
154 
155  try {
156  $response = $this->guzzleClient->get($URIToGetLicenses);
157  $statusCode = $response->getStatusCode();
158  $cookedResult = array();
159  if ($statusCode == SoftwareHeritageDao::SWH_STATUS_OK) {
160  $responseContent = json_decode($response->getBody()->getContents(),true);
161  $cookedResult = $responseContent["facts"][0]["licenses"];
162  } else if ($statusCode == SoftwareHeritageDao::SWH_RATELIMIT_EXCEED) {
163  $responseContent = $response->getHeaders();
164  $cookedResult = $responseContent["X-RateLimit-Reset"][0];
165  } else if ($statusCode == SoftwareHeritageDao::SWH_NOT_FOUND) {
166  $response = $this->guzzleClient->get($URIToGetContent);
167  $responseContent = json_decode($response->getBody(),true);
168  if (isset($responseContent["status"])) {
169  $statusCode = SoftwareHeritageDao::SWH_STATUS_OK;
170  }
171  }
172  return array($statusCode, $cookedResult);
173  } catch (RequestException $e) {
174  echo "Sorry, something went wrong. check if the host is accessible!\n";
175  echo Psr7\str($e->getRequest());
176  if ($e->hasResponse()) {
177  echo Psr7\str($e->getResponse());
178  }
179  $this->scheduler_disconnect(1);
180  exit;
181  }
182  }
183 
191  protected function insertSoftwareHeritageRecord($pfileId, $licenses, $agentId, $status)
192  {
193  $licenseString = !empty($licenses) ? implode(", ", $licenses) : '';
194  $this->softwareHeritageDao->setSoftwareHeritageDetails($pfileId,
195  $licenseString, $status);
196  if (!empty($licenses)) {
197  foreach ($licenses as $license) {
198  $l = $this->licenseDao->getLicenseByShortName($license);
199  if ($l != NULL) {
200  $this->dbManeger->insertTableRow('license_file',['agent_fk' => $agentId,
201  'pfile_fk' => $pfileId,'rf_fk'=> $l->getId()]);
202  }
203  }
204  return true;
205  }
206  }
207 }
Structure of an Agent with all required parameters.
Definition: Agent.php:41
heartbeat($newProcessed)
Send hear beat to the scheduler.
Definition: Agent.php:203
scheduler_disconnect($exitvalue)
Closes connection from scheduler.
Definition: Agent.php:236
static getGuzzleClient(array $SysConf, string $baseUri, string $token="")
Definition: HttpUtils.php:22
processUploadId($uploadId)
Run software heritage for a package.
processEachPfileForSWH($pfileDetail, $agentId, $maxTime)
process each pfile for software heritage and wait till the reset time
insertSoftwareHeritageRecord($pfileId, $licenses, $agentId, $status)
Insert the License Details in softwareHeritage table.
getSoftwareHeritageLicense($sha256)
Get the license details from software heritage.
char * trim(char *ptext)
Trimming whitespace.
Definition: fossconfig.c:690