Skip to content

Commit 38e46d2

Browse files
authored
fix: Implement alternative parser of OSORI response (#793)
* fix: Implement alternative parser of OSORI response Signed-off-by: Oleg Kopysov <o.kopysov@samsung.com> * fix: Fix coding style and code coverage Signed-off-by: Oleg Kopysov <o.kopysov@samsung.com> * test: Add more unit tests to improve coverage Signed-off-by: Oleg Kopysov <o.kopysov@samsung.com> --------- Signed-off-by: Oleg Kopysov <o.kopysov@samsung.com>
1 parent ce7134f commit 38e46d2

File tree

8 files changed

+410
-26
lines changed

8 files changed

+410
-26
lines changed

src/main/java/com/lpvs/service/LPVSLicenseService.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2022-2024, Samsung Electronics Co., Ltd. All rights reserved.
2+
* Copyright (c) 2022-2025, Samsung Electronics Co., Ltd. All rights reserved.
33
*
44
* Use of this source code is governed by a MIT license that can be
55
* found in the LICENSE file.
@@ -13,7 +13,6 @@
1313

1414
import com.lpvs.util.LPVSPayloadUtil;
1515
import io.micrometer.common.util.StringUtils;
16-
import lombok.NoArgsConstructor;
1716
import lombok.extern.slf4j.Slf4j;
1817
import org.springframework.beans.factory.annotation.Autowired;
1918
import org.springframework.beans.factory.annotation.Value;
@@ -77,6 +76,12 @@ public class LPVSLicenseService {
7776
@Value("${license_source:}")
7877
private String osoriDbUrl;
7978

79+
/**
80+
* Flag to indicate if this is an internal LPVS instance.
81+
*/
82+
@Value("${internal:false}")
83+
private boolean internalMode;
84+
8085
/**
8186
* The object used to make HTTP requests to the OSORI DB.
8287
*/
@@ -110,6 +115,7 @@ public LPVSLicenseService(
110115
LPVSExitHandler exitHandler) {
111116
this.licenseConflictsSource = licenseConflictsSource;
112117
this.exitHandler = exitHandler;
118+
this.osoriConnection = new OsoriConnection();
113119
}
114120

115121
/**
@@ -283,7 +289,7 @@ public LPVSLicense findLicenseInOsoriDB(String licenseSpdxId) {
283289
// Try to find the license in the OSORI database
284290
try {
285291
HttpURLConnection connection =
286-
osoriConnection.createConnection(osoriDbUrl, licenseSpdxId);
292+
osoriConnection.createConnection(osoriDbUrl, licenseSpdxId, internalMode);
287293
connection.setRequestMethod("GET");
288294
connection.connect();
289295

@@ -301,7 +307,11 @@ public LPVSLicense findLicenseInOsoriDB(String licenseSpdxId) {
301307
LPVSPayloadUtil.convertInputStreamToString(connection.getInputStream());
302308
// If the license is found, create a new LPVSLicense object with the field values from
303309
// the OSORI database
304-
return LPVSPayloadUtil.convertOsoriDbResponseToLicense(response);
310+
if (internalMode) {
311+
return LPVSPayloadUtil.convertOsoriDbResponseToLicenseAlternative(response);
312+
} else {
313+
return LPVSPayloadUtil.convertOsoriDbResponseToLicense(response);
314+
}
305315
} catch (Exception e) {
306316
log.error("Error connecting OSORI DB: " + e.getMessage());
307317
return null;
@@ -411,23 +421,29 @@ public List<LPVSConflict<String, String>> findConflicts(
411421
/**
412422
* The OsoriConnection class provides methods for creating a connection to the OSORI database.
413423
*/
414-
@NoArgsConstructor
415424
public static class OsoriConnection {
416425

417426
/**
418427
* Creates a connection to the OSORI database using the specified OSORI server and license SPDX identifier.
419428
*
420429
* @param osoriDbUrl The URL of the OSORI server.
421430
* @param licenseSpdxId The license SPDX identifier.
431+
* @param internalMode Flag indicating whether to use internal or external API format.
422432
* @return A HttpURLConnection object representing the connection to the OSORI database.
423433
*/
424-
public HttpURLConnection createConnection(String osoriDbUrl, String licenseSpdxId)
425-
throws IOException {
426-
URL url =
427-
new URL(
428-
osoriDbUrl
429-
+ "/api/v1/user/licenses/spdx_identifier?searchWord="
430-
+ URLEncoder.encode(licenseSpdxId, "UTF-8"));
434+
public HttpURLConnection createConnection(
435+
String osoriDbUrl, String licenseSpdxId, boolean internalMode) throws IOException {
436+
String apiUrl;
437+
if (internalMode) {
438+
apiUrl = osoriDbUrl + "/api/v1/licenses/" + licenseSpdxId;
439+
} else {
440+
apiUrl =
441+
osoriDbUrl
442+
+ "/api/v1/user/licenses/spdx_identifier?searchWord="
443+
+ URLEncoder.encode(licenseSpdxId, "UTF-8");
444+
}
445+
446+
URL url = new URL(apiUrl);
431447
return (HttpURLConnection) url.openConnection();
432448
}
433449
}

src/main/java/com/lpvs/util/LPVSPayloadUtil.java

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2022-2024, Samsung Electronics Co., Ltd. All rights reserved.
2+
* Copyright (c) 2022-2025, Samsung Electronics Co., Ltd. All rights reserved.
33
*
44
* Use of this source code is governed by a MIT license that can be
55
* found in the LICENSE file.
@@ -103,6 +103,54 @@ public static LPVSLicense convertOsoriDbResponseToLicense(String payload) {
103103
return null;
104104
}
105105

106+
/**
107+
* Parses the given payload from the alternative OSORI DB and converts it into a LPVSLicense object.
108+
*
109+
* @param payload the JSON payload from the alternative OSORI DB
110+
* @return the LPVSLicense object containing the parsed information from the payload, or null if the payload is invalid
111+
*/
112+
public static LPVSLicense convertOsoriDbResponseToLicenseAlternative(String payload) {
113+
try {
114+
Gson gson = new Gson();
115+
JsonObject json = gson.fromJson(payload, JsonObject.class);
116+
117+
LPVSLicense lic = new LPVSLicense();
118+
lic.setLicenseName(json.get("name").getAsString());
119+
lic.setSpdxId(json.get("spdxIdentifier").getAsString());
120+
121+
// Set access based on trafficLight field
122+
JsonElement trafficLightElement = json.get("trafficLight");
123+
if (trafficLightElement != null && !trafficLightElement.isJsonNull()) {
124+
String trafficLight = trafficLightElement.getAsString();
125+
if ("🔴".equals(trafficLight)) {
126+
lic.setAccess("PROHIBITED");
127+
} else if ("🟡".equals(trafficLight)) {
128+
lic.setAccess("RESTRICTED");
129+
} else if ("🟢".equals(trafficLight)) {
130+
lic.setAccess("PERMITTED");
131+
} else {
132+
lic.setAccess("UNREVIEWED");
133+
}
134+
} else {
135+
lic.setAccess("UNREVIEWED");
136+
}
137+
138+
List<String> nicknameList = new ArrayList<>();
139+
JsonElement nicknamesArray = json.get("nicknames");
140+
if (nicknamesArray != null && nicknamesArray.isJsonArray()) {
141+
nicknamesArray
142+
.getAsJsonArray()
143+
.forEach(element -> nicknameList.add(element.getAsString()));
144+
}
145+
lic.setAlternativeNames(String.join(",", nicknameList));
146+
147+
return lic;
148+
} catch (Exception e) {
149+
log.error("Error parsing alternative OSORI DB payload: " + e.getMessage());
150+
}
151+
return null;
152+
}
153+
106154
/**
107155
* Convert an InputStream into a String by reading the contents line by line.
108156
*

src/test/java/com/lpvs/service/LPVSLicenseServiceTest.java

Lines changed: 78 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2022-2024, Samsung Electronics Co., Ltd. All rights reserved.
2+
* Copyright (c) 2022-2025, Samsung Electronics Co., Ltd. All rights reserved.
33
*
44
* Use of this source code is governed by a MIT license that can be
55
* found in the LICENSE file.
@@ -520,6 +520,10 @@ public void getLicenseBySpdxIdAndNameTest_connectToOSORI()
520520
osoriDbUrl.setAccessible(true);
521521
osoriDbUrl.set(licenseService, "http://127.0.0.1:8080");
522522

523+
Field internalMode = licenseService.getClass().getDeclaredField("internalMode");
524+
internalMode.setAccessible(true);
525+
internalMode.set(licenseService, false); // external mode
526+
523527
HttpURLConnection mockConnection = Mockito.mock(HttpURLConnection.class);
524528
when(mockConnection.getResponseCode()).thenReturn(200);
525529

@@ -529,7 +533,7 @@ public void getLicenseBySpdxIdAndNameTest_connectToOSORI()
529533
osoriConnection.setAccessible(true);
530534
osoriConnection.set(licenseService, mockOsoriConnection);
531535

532-
when(mockOsoriConnection.createConnection(anyString(), anyString()))
536+
when(mockOsoriConnection.createConnection(anyString(), anyString(), anyBoolean()))
533537
.thenReturn(mockConnection);
534538

535539
Path path =
@@ -551,6 +555,51 @@ public void getLicenseBySpdxIdAndNameTest_connectToOSORI()
551555
assertEquals("UNREVIEWED", result.getAccess());
552556
}
553557

558+
@Test
559+
public void getLicenseBySpdxIdAndNameTest_connectToOSORI_Internal()
560+
throws NoSuchFieldException,
561+
IllegalAccessException,
562+
IOException,
563+
URISyntaxException {
564+
Field osoriDbUrl = licenseService.getClass().getDeclaredField("osoriDbUrl");
565+
osoriDbUrl.setAccessible(true);
566+
osoriDbUrl.set(licenseService, "http://127.0.0.1:8080");
567+
568+
Field internalMode = licenseService.getClass().getDeclaredField("internalMode");
569+
internalMode.setAccessible(true);
570+
internalMode.set(licenseService, true); // internal mode
571+
572+
HttpURLConnection mockConnection = Mockito.mock(HttpURLConnection.class);
573+
when(mockConnection.getResponseCode()).thenReturn(200);
574+
575+
LPVSLicenseService.OsoriConnection mockOsoriConnection =
576+
Mockito.mock(LPVSLicenseService.OsoriConnection.class);
577+
Field osoriConnection = licenseService.getClass().getDeclaredField("osoriConnection");
578+
osoriConnection.setAccessible(true);
579+
osoriConnection.set(licenseService, mockOsoriConnection);
580+
581+
when(mockOsoriConnection.createConnection(anyString(), anyString(), anyBoolean()))
582+
.thenReturn(mockConnection);
583+
584+
Path path =
585+
Paths.get(
586+
Objects.requireNonNull(
587+
getClass()
588+
.getClassLoader()
589+
.getResource("osori_db_response_internal.json"))
590+
.toURI());
591+
592+
when(mockConnection.getInputStream()).thenReturn(Files.newInputStream(path));
593+
when(licenseRepository.saveAndFlush(Mockito.any(LPVSLicense.class)))
594+
.thenAnswer(i -> i.getArguments()[0]);
595+
596+
LPVSLicense result =
597+
licenseService.getLicenseBySpdxIdAndName("Apache-2.0", Optional.empty());
598+
assertEquals("Apache-2.0", result.getSpdxId());
599+
assertEquals("Apache License 2.0", result.getLicenseName());
600+
assertEquals("PERMITTED", result.getAccess());
601+
}
602+
554603
@Test
555604
public void getLicenseBySpdxIdAndNameTest_createNewLicense()
556605
throws NoSuchFieldException,
@@ -570,7 +619,7 @@ public void getLicenseBySpdxIdAndNameTest_createNewLicense()
570619
osoriConnection.setAccessible(true);
571620
osoriConnection.set(licenseService, mockOsoriConnection);
572621

573-
when(mockOsoriConnection.createConnection(anyString(), anyString()))
622+
when(mockOsoriConnection.createConnection(anyString(), anyString(), anyBoolean()))
574623
.thenReturn(mockConnection);
575624

576625
Path path =
@@ -624,7 +673,7 @@ public void getLicenseBySpdxIdAndNameTest_errorCodeInOSORI_N()
624673
osoriConnection.setAccessible(true);
625674
osoriConnection.set(licenseService, mockOsoriConnection);
626675

627-
when(mockOsoriConnection.createConnection(anyString(), anyString()))
676+
when(mockOsoriConnection.createConnection(anyString(), anyString(), anyBoolean()))
628677
.thenReturn(mockConnection);
629678
when(licenseRepository.saveAndFlush(Mockito.any(LPVSLicense.class)))
630679
.thenAnswer(i -> i.getArguments()[0]);
@@ -656,7 +705,7 @@ public void findLicenseInOsoriDBTest()
656705
osoriConnection.setAccessible(true);
657706
osoriConnection.set(licenseService, mockOsoriConnection);
658707

659-
when(mockOsoriConnection.createConnection(anyString(), anyString()))
708+
when(mockOsoriConnection.createConnection(anyString(), anyString(), anyBoolean()))
660709
.thenReturn(mockConnection);
661710

662711
Path path =
@@ -678,11 +727,13 @@ public void findLicenseInOsoriDBTest()
678727
}
679728

680729
@Test
681-
public void findLicenseTest() {
682-
LPVSLicense result = licenseService.findLicense("GPL-3.0-only", "GPL-3.0-only");
683-
assertEquals("GPL-3.0-only", result.getSpdxId());
684-
assertEquals("GNU General Public License v3.0 only", result.getLicenseName());
685-
assertEquals("PROHIBITED", result.getAccess());
730+
public void testCreateConnectionThrowsIOException_N() {
731+
String licenseSpdxId = "Apache-2.0";
732+
LPVSLicenseService.OsoriConnection connection =
733+
new LPVSLicenseService.OsoriConnection();
734+
assertThrows(
735+
IOException.class,
736+
() -> connection.createConnection(null, licenseSpdxId, false));
686737
}
687738
}
688739

@@ -696,18 +747,33 @@ public void testCreateConnection() throws IOException {
696747
LPVSLicenseService.OsoriConnection connection =
697748
new LPVSLicenseService.OsoriConnection();
698749
HttpURLConnection httpURLConnection =
699-
connection.createConnection(osoriDbUrl, licenseSpdxId);
750+
connection.createConnection(osoriDbUrl, licenseSpdxId, false); // external mode
700751
assertEquals(
701752
osoriDbUrl + "/api/v1/user/licenses/spdx_identifier?searchWord=Apache-2.0",
702753
httpURLConnection.getURL().toString());
703754
}
704755

756+
@Test
757+
public void testCreateConnectionInternal() throws IOException {
758+
String osoriDbUrl = "https://ossori.com";
759+
String licenseSpdxId = "Apache-2.0";
760+
LPVSLicenseService.OsoriConnection connection =
761+
new LPVSLicenseService.OsoriConnection();
762+
HttpURLConnection httpURLConnection =
763+
connection.createConnection(osoriDbUrl, licenseSpdxId, true); // internal mode
764+
assertEquals(
765+
osoriDbUrl + "/api/v1/licenses/Apache-2.0",
766+
httpURLConnection.getURL().toString());
767+
}
768+
705769
@Test
706770
public void testCreateConnectionThrowsIOException_N() {
707771
String licenseSpdxId = "Apache-2.0";
708772
LPVSLicenseService.OsoriConnection connection =
709773
new LPVSLicenseService.OsoriConnection();
710-
assertThrows(IOException.class, () -> connection.createConnection(null, licenseSpdxId));
774+
assertThrows(
775+
IOException.class,
776+
() -> connection.createConnection(null, licenseSpdxId, false));
711777
}
712778
}
713779
}

0 commit comments

Comments
 (0)