Skip to content

Commit

Permalink
feat: Check new license and alternative license names in OSORI DB
Browse files Browse the repository at this point in the history
Signed-off-by: Oleg Kopysov <[email protected]>
  • Loading branch information
o-kopysov committed May 3, 2024
1 parent 5808878 commit 566068b
Show file tree
Hide file tree
Showing 12 changed files with 466 additions and 113 deletions.
140 changes: 122 additions & 18 deletions src/main/java/com/lpvs/service/LPVSLicenseService.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,19 @@
import com.lpvs.repository.LPVSLicenseRepository;
import com.lpvs.util.LPVSExitHandler;

import com.lpvs.util.LPVSPayloadUtil;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import jakarta.annotation.PostConstruct;

import java.io.BufferedReader;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;

/**
Expand Down Expand Up @@ -67,6 +74,17 @@ public class LPVSLicenseService {
*/
private LPVSExitHandler exitHandler;

/**
* URL of the source of the new licenses.
*/
@Value("${license_source:}")
private String osoriDbUrl;

/**
* The object used to make HTTP requests to the OSORI DB.
*/
private OsoriConnection osoriConnection = new OsoriConnection();

/**
* Repository for accessing and managing LPVSLicense entities in the database.
*/
Expand Down Expand Up @@ -198,7 +216,9 @@ public LPVSLicense findLicenseBySPDX(String name) {
* @param license The license to add.
*/
public void addLicenseToList(LPVSLicense license) {
licenses.add(license);
if (!licenses.contains(license)) {
licenses.add(license);
}
}

/**
Expand All @@ -212,10 +232,87 @@ public LPVSLicense findLicenseByName(String name) {
if (license.getLicenseName().equalsIgnoreCase(name)) {
return license;
}
if (license.getAlternativeNames() != null
&& !license.getAlternativeNames().trim().isEmpty()) {
String[] names = license.getAlternativeNames().split(",");
for (String n : names) {
if (n.trim().equalsIgnoreCase(name)) {
return license;
}
}
}
}
return null;
}

/**
* Gets a license object from the database using the specified license SPDX ID and license name.
* @param licenseSpdxId The license SPDX ID to search for
* @param licenseName The license name to use if the license is not found in the database
* @return The license object that was found or created
*/
public LPVSLicense getLicenseBySpdxIdAndName(
String licenseSpdxId, Optional<String> licenseName) {
String licName = licenseName.orElse(licenseSpdxId);
// check by license SPDX ID
LPVSLicense lic = findLicenseBySPDX(licenseSpdxId);
if (null == lic) {
// check by license name and alternative names
lic = findLicenseByName(licName);
}
// create new license
if (lic == null) {

if (osoriDbUrl != null && !osoriDbUrl.trim().isEmpty()) {
// check OSORI DB and try to find the license there
try {
HttpURLConnection connection =
osoriConnection.createConnection(osoriDbUrl, licenseSpdxId);
connection.setRequestMethod("GET");
connection.connect();

if (connection.getResponseCode() != 200) {
throw new Exception(
"HTTP error code ("
+ connection.getResponseCode()
+ "): "
+ connection.getResponseMessage());
}

BufferedReader in =
LPVSPayloadUtil.createBufferReader(
LPVSPayloadUtil.createInputStreamReader(
connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();

while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();

// if found, create new license with field values taken from OSORI DB
lic = LPVSPayloadUtil.convertOsoriDbResponseToLicense(response.toString());
} catch (Exception e) {
log.error("Error connecting OSORI DB: " + e.getMessage());
}
}

if (lic == null) {
// if not found, create new license with default field values
lic = new LPVSLicense();
lic.setSpdxId(licenseSpdxId);
lic.setLicenseName(licName);
lic.setAlternativeNames(null);
lic.setAccess("UNREVIEWED");
}
// save new license and add it to the license list
lic = lpvsLicenseRepository.saveAndFlush(lic);
}
addLicenseToList(lic);
return lic;
}

/**
* Adds a license conflict to the list of conflicts.
*
Expand All @@ -229,23 +326,6 @@ public void addLicenseConflict(String license1, String license2) {
}
}

/**
* Checks a license by SPDX identifier and returns the corresponding license object.
*
* @param spdxId SPDX identifier of the license.
* @return The corresponding LPVSLicense object.
*/
public LPVSLicense checkLicense(String spdxId) {
LPVSLicense newLicense = findLicenseBySPDX(spdxId);
if (newLicense == null && spdxId.contains("+")) {
newLicense = findLicenseBySPDX(spdxId.replace("+", "") + "-or-later");
}
if (newLicense == null && spdxId.contains("+")) {
newLicense = findLicenseBySPDX(spdxId.replace("+", "") + "-only");
}
return newLicense;
}

/**
* Finds license conflicts based on the provided scan results and repository information.
*
Expand Down Expand Up @@ -369,4 +449,28 @@ public int hashCode() {
return Objects.hash(l1, l2);
}
}

/**
* The OsoriConnection class provides methods for creating a connection to the OSORI database.
*/
@NoArgsConstructor
public static class OsoriConnection {

/**
* Creates a connection to the OSORI database using the specified OSORI server and license SPDX identifier.
*
* @param osoriDbUrl The URL of the OSORI server.
* @param licenseSpdxId The license SPDX identifier.
* @return A HttpURLConnection object representing the connection to the OSORI database.
*/
public HttpURLConnection createConnection(String osoriDbUrl, String licenseSpdxId)
throws IOException {
URL url =
new URL(
osoriDbUrl
+ "/api/v1/user/licenses/spdx_identifier?searchWord="
+ URLEncoder.encode(licenseSpdxId, "UTF-8"));
return (HttpURLConnection) url.openConnection();
}
}
}
7 changes: 5 additions & 2 deletions src/main/java/com/lpvs/service/LPVSQueueService.java
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,12 @@ public void processWebHook(LPVSQueue webhookConfig) {
}
// check repository license
String repositoryLicense = gitHubService.getRepositoryLicense(webhookConfig);
if (licenseService.checkLicense(repositoryLicense) != null) {
if (licenseService.getLicenseBySpdxIdAndName(repositoryLicense, Optional.empty())
!= null) {
webhookConfig.setRepositoryLicense(
licenseService.checkLicense(repositoryLicense).getSpdxId());
licenseService
.getLicenseBySpdxIdAndName(repositoryLicense, Optional.empty())
.getSpdxId());
} else if (licenseService.findLicenseByName(repositoryLicense) != null) {
webhookConfig.setRepositoryLicense(
licenseService.findLicenseByName(repositoryLicense).getSpdxId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,21 +227,11 @@ public List<LPVSFile> checkLicenses(LPVSQueue webhookConfig) {
if (object.licenses != null) {
for (ScanossJsonStructure.ScanossLicense license : object.licenses) {
// Check detected licenses
LPVSLicense lic = licenseService.findLicenseBySPDX(license.name);
if (lic != null) {
lic.setChecklistUrl(license.checklist_url);
licenses.add(lic);
} else {
LPVSLicense newLicense = new LPVSLicense();
newLicense.setSpdxId(license.name);
newLicense.setLicenseName(license.name);
newLicense.setAccess("UNREVIEWED");
newLicense.setChecklistUrl(license.checklist_url);
newLicense.setAlternativeNames(null);
newLicense = lpvsLicenseRepository.save(newLicense);
licenseService.addLicenseToList(newLicense);
licenses.add(newLicense);
}
LPVSLicense lic =
licenseService.getLicenseBySpdxIdAndName(
license.name, Optional.empty());
lic.setChecklistUrl(license.checklist_url);
licenses.add(lic);

// Check for the license conflicts if the property
// "license_conflict=scanner"
Expand Down
38 changes: 38 additions & 0 deletions src/main/java/com/lpvs/util/LPVSPayloadUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
package com.lpvs.util;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.lpvs.entity.LPVSLicense;
import com.lpvs.entity.LPVSQueue;
import com.lpvs.entity.enums.LPVSPullRequestAction;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -19,6 +21,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

Expand Down Expand Up @@ -52,6 +55,41 @@ public static BufferedReader createBufferReader(InputStreamReader inputStreamRea
return new BufferedReader(inputStreamReader);
}

/**
* Parses the given payload from the OSORI DB and converts it into a LPVSLicense object.
*
* @param payload the JSON payload from the OSORI DB
* @return the LPVSLicense object containing the parsed information from the payload, or null if the payload is invalid
*/
public static LPVSLicense convertOsoriDbResponseToLicense(String payload) {
try {
Gson gson = new Gson();
JsonObject json = gson.fromJson(payload, JsonObject.class);
JsonObject messageList = json.getAsJsonObject("messageList");
JsonArray detailInfoArray = messageList.getAsJsonArray("detailInfo");

LPVSLicense lic = new LPVSLicense();
lic.setLicenseName(detailInfoArray.get(0).getAsJsonObject().get("name").getAsString());
lic.setSpdxId(
detailInfoArray.get(0).getAsJsonObject().get("spdx_identifier").getAsString());
lic.setAccess("UNREVIEWED");

List<String> nicknameList = new ArrayList<>();
detailInfoArray
.get(0)
.getAsJsonObject()
.get("nicknameList")
.getAsJsonArray()
.forEach(element -> nicknameList.add(element.getAsString()));
lic.setAlternativeNames(String.join(",", nicknameList));

return lic;
} catch (Exception e) {
log.error("Error parsing OSORI DB payload: " + e.getMessage());
}
return null;
}

/**
* Parses the GitHub webhook payload and extracts relevant information to create an LPVSQueue object.
*
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ scanner=scanoss
# Corresponding env. variable LPVS_LICENSE_CONFLICT
license_conflict=db

# URL of the external OSORI license database. Default is empty.
license_source=http://223.255.204.223:8082

# Logger configuration
logging.pattern.console=%d{dd-MM-yyyy HH:mm:ss.SSS} %magenta([%thread]) %highlight(%-5level) %logger.%M - %msg%n
spring.profiles.active=
Expand Down
8 changes: 0 additions & 8 deletions src/test/java/com/lpvs/service/LPVSGitHubServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4343,14 +4343,6 @@ public void testCheckEmpty()
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

environmentVars.set("LPVS_GITHUB_TOKEN", "");

LPVSPullRequestRepository mocked_pullRequestRepository =
mock(LPVSPullRequestRepository.class);
LPVSDetectedLicenseRepository mocked_lpvsDetectedLicenseRepository =
mock(LPVSDetectedLicenseRepository.class);
LPVSLicenseRepository mocked_lpvsLicenseRepository = mock(LPVSLicenseRepository.class);
LPVSLicenseConflictRepository mocked_lpvsLicenseConflictRepository =
mock(LPVSLicenseConflictRepository.class);
LPVSExitHandler exitHandler = mock(LPVSExitHandler.class);
LPVSGitHubConnectionService lpvsGitHubConnectionService =
new LPVSGitHubConnectionService("", "", "", exitHandler);
Expand Down
Loading

0 comments on commit 566068b

Please sign in to comment.