FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
softwareHeritageAgent.php
Go to the documentation of this file.
1 <?php
2 /*
3  Copyright (C) 2019
4  Copyright (C) 2020, Siemens AG
5  Author: Sandip Kumar Bhuyan<sandipbhuyan@gmail.com>,
6  Shaheem Azmal M MD<shaheem.azmal@siemens.com>
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 version 2 as published by the Free Software Foundation.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 
23 
30 use \GuzzleHttp\Client;
31 use GuzzleHttp\Psr7;
33 
34 include_once(__DIR__ . "/version.php");
35 
43 {
47  private $uploadDao;
48 
52  private $licenseDao;
53 
58  private $configuration;
59 
64  private $dbManeger;
65 
70  protected $agentDao;
71 
76  private $softwareHeritageDao;
77 
82  function __construct()
83  {
84  parent::__construct(SOFTWARE_HERITAGE_AGENT_NAME, AGENT_VERSION, AGENT_REV);
85  $this->uploadDao = $this->container->get('dao.upload');
86  $this->licenseDao = $this->container->get('dao.license');
87  $this->dbManeger = $this->container->get('db.manager');
88  $this->agentDao = $this->container->get('dao.agent');
89  $this->softwareHeritageDao = $this->container->get('dao.softwareHeritage');
90  $this->configuration = parse_ini_file(__DIR__ . '/softwareHeritage.conf');
91  }
92 
100  function processUploadId($uploadId)
101  {
102  $itemTreeBounds = $this->uploadDao->getParentItemBounds($uploadId);
103  $pfileFileDetails = $this->uploadDao->getPFileDataPerFileName($itemTreeBounds);
104  $pfileFks = $this->softwareHeritageDao->getSoftwareHeritagePfileFk($uploadId);
105  $agentId = $this->agentDao->getCurrentAgentId("softwareHeritage");
106  $maxTime = $this->configuration['api']['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  global $SysConf;
152  $proxy = [];
153  $URIToGetLicenses = $this->configuration['api']['url'].$this->configuration['api']['uri'].$sha256.$this->configuration['api']['content'];
154  $URIToGetContent = $this->configuration['api']['url'].$this->configuration['api']['uri'].$sha256;
155 
156  if (array_key_exists('http_proxy', $SysConf['FOSSOLOGY']) &&
157  ! empty($SysConf['FOSSOLOGY']['http_proxy'])) {
158  $proxy['http'] = $SysConf['FOSSOLOGY']['http_proxy'];
159  }
160  if (array_key_exists('https_proxy', $SysConf['FOSSOLOGY']) &&
161  ! empty($SysConf['FOSSOLOGY']['https_proxy'])) {
162  $proxy['https'] = $SysConf['FOSSOLOGY']['https_proxy'];
163  }
164  if (array_key_exists('no_proxy', $SysConf['FOSSOLOGY']) &&
165  ! empty($SysConf['FOSSOLOGY']['no_proxy'])) {
166  $proxy['no'] = explode(',', $SysConf['FOSSOLOGY']['no_proxy']);
167  }
168 
169  $client = new Client(['http_errors' => false, 'proxy' => $proxy]);
170  try {
171  $response = $client->get($URIToGetLicenses);
172  $statusCode = $response->getStatusCode();
173  $cookedResult = array();
174  if ($statusCode == SoftwareHeritageDao::SWH_STATUS_OK) {
175  $responseContent = json_decode($response->getBody()->getContents(),true);
176  $cookedResult = $responseContent["facts"][0]["licenses"];
177  } else if ($statusCode == SoftwareHeritageDao::SWH_RATELIMIT_EXCEED) {
178  $responseContent = $response->getHeaders();
179  $cookedResult = $responseContent["X-RateLimit-Reset"][0];
180  } else if ($statusCode == SoftwareHeritageDao::SWH_NOT_FOUND) {
181  $response = $client->get($URIToGetContent);
182  $responseContent = json_decode($response->getBody(),true);
183  if (isset($responseContent["status"])) {
184  $statusCode = SoftwareHeritageDao::SWH_STATUS_OK;
185  }
186  }
187  return array($statusCode, $cookedResult);
188  } catch (RequestException $e) {
189  echo "Sorry, something went wrong. check if the host is accessible!\n";
190  echo Psr7\str($e->getRequest());
191  if ($e->hasResponse()) {
192  echo Psr7\str($e->getResponse());
193  }
194  $this->scheduler_disconnect(1);
195  exit;
196  }
197  }
198 
206  protected function insertSoftwareHeritageRecord($pfileId, $licenses, $agentId, $status)
207  {
208  $licenseString = !empty($licenses) ? implode(", ", $licenses) : '';
209  $this->softwareHeritageDao->setSoftwareHeritageDetails($pfileId,
210  $licenseString, $status);
211  if (!empty($licenses)) {
212  foreach ($licenses as $license) {
213  $l = $this->licenseDao->getLicenseByShortName($license);
214  if ($l != NULL) {
215  $this->dbManeger->insertTableRow('license_file',['agent_fk' => $agentId,
216  'pfile_fk' => $pfileId,'rf_fk'=> $l->getId()]);
217  }
218  }
219  return true;
220  }
221  }
222 }
scheduler_disconnect($exitvalue)
Closes connection from scheduler.
Definition: Agent.php:247
heartbeat($newProcessed)
Send hear beat to the scheduler.
Definition: Agent.php:214
Structure of an Agent with all required parameters.
Definition: Agent.php:51
insertSoftwareHeritageRecord($pfileId, $licenses, $agentId, $status)
Insert the License Details in softwareHeritage table.
processUploadId($uploadId)
Run software heritage for a package.
processEachPfileForSWH($pfileDetail, $agentId, $maxTime)
process each pfile for software heritage and wait till the reset time
getSoftwareHeritageLicense($sha256)
Get the license details from software heritage.