Skip to content

Commit ec5f084

Browse files
nnobelissschuberth
authored andcommitted
fix(fossid-webapp): creatScan response can be polymorphic
Under some rare circumstances, `createScan` can return an error message as data payload instead of the scan id. This commit changes the function's signature to reflect this polymorphicity. Fixes #8462. Signed-off-by: Nicolas Nobelis <[email protected]>
1 parent 434b368 commit ec5f084

File tree

8 files changed

+103
-6
lines changed

8 files changed

+103
-6
lines changed

clients/fossid-webapp/src/main/kotlin/Extensions.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import okio.sink
3030

3131
import org.apache.logging.log4j.kotlin.logger
3232

33+
import org.ossreviewtoolkit.clients.fossid.model.CreateScanResponse
3334
import org.ossreviewtoolkit.clients.fossid.model.identification.common.LicenseMatchType
3435
import org.ossreviewtoolkit.clients.fossid.model.report.ReportType
3536
import org.ossreviewtoolkit.clients.fossid.model.report.SelectionType
@@ -149,7 +150,7 @@ suspend fun FossIdRestService.createScan(
149150
gitRepoUrl: String,
150151
gitBranch: String,
151152
comment: String = ""
152-
): MapResponseBody<String> =
153+
): PolymorphicDataResponseBody<CreateScanResponse> =
153154
createScan(
154155
PostRequestBody(
155156
"create",

clients/fossid-webapp/src/main/kotlin/FossIdRestService.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import okhttp3.ResponseBody
4343

4444
import org.apache.logging.log4j.kotlin.logger
4545

46+
import org.ossreviewtoolkit.clients.fossid.model.CreateScanResponse
4647
import org.ossreviewtoolkit.clients.fossid.model.Project
4748
import org.ossreviewtoolkit.clients.fossid.model.Scan
4849
import org.ossreviewtoolkit.clients.fossid.model.identification.identifiedFiles.IdentifiedFile
@@ -273,7 +274,7 @@ interface FossIdRestService {
273274
suspend fun createProject(@Body body: PostRequestBody): MapResponseBody<String>
274275

275276
@POST("api.php")
276-
suspend fun createScan(@Body body: PostRequestBody): MapResponseBody<String>
277+
suspend fun createScan(@Body body: PostRequestBody): PolymorphicDataResponseBody<CreateScanResponse>
277278

278279
@POST("api.php")
279280
suspend fun runScan(@Body body: PostRequestBody): EntityResponseBody<Nothing>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (C) 2025 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
* License-Filename: LICENSE
18+
*/
19+
20+
package org.ossreviewtoolkit.clients.fossid.model
21+
22+
/**
23+
* This class is present to handle the high polymorphism of the 'createScan' response.
24+
*/
25+
data class CreateScanResponse(
26+
// Normal response.
27+
val scanId: String? = null,
28+
29+
// Error response when there is a credentials issue (see https://github.com/oss-review-toolkit/ort/issues/8462).
30+
val code: String? = null,
31+
val message: String? = null,
32+
val messageParameters: Map<String, String>? = null
33+
)

clients/fossid-webapp/src/test/kotlin/FossIdClientNewProjectTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class FossIdClientNewProjectTest : StringSpec({
9595
SCAN_CODE,
9696
"https://github.com/gundy/semver4j.git",
9797
"671aa533f7e33c773bf620b9f466650c3b9ab26e"
98-
).shouldNotBeNull().data.shouldNotBeNull() shouldContain("scan_id" to "4920")
98+
).shouldNotBeNull().data?.value?.scanId shouldBe "4920"
9999
}
100100

101101
"Download from Git can be triggered" {

clients/fossid-webapp/src/test/kotlin/FossIdClientReturnTypeTest.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import com.github.tomakehurst.wiremock.core.WireMockConfiguration
2424

2525
import io.kotest.core.spec.style.StringSpec
2626
import io.kotest.matchers.collections.beEmpty
27+
import io.kotest.matchers.maps.shouldContainValue
2728
import io.kotest.matchers.nulls.shouldNotBeNull
2829
import io.kotest.matchers.should
2930
import io.kotest.matchers.shouldBe
@@ -256,6 +257,28 @@ class FossIdClientReturnTypeTest : StringSpec({
256257
}
257258
}
258259

260+
"When create scan returns an error, no exception is thrown" {
261+
service.createScan(
262+
"",
263+
"",
264+
PROJECT_CODE_1,
265+
SCAN_CODE_1,
266+
"git_repo_url",
267+
"develop"
268+
) shouldNotBeNull {
269+
message shouldBe "These issues were found while parsing the request:"
270+
data?.value?.message shouldBe "Field git_repo_url: there was an issue executing command: timeout 200 git " +
271+
"ls-remote 'ssh git repo' 2>&1. Exit status: 128. Output: Repository not found The requested " +
272+
"repository does not exist, or you do not have permission to access it. fatal: Could not read from " +
273+
"remote repository. Please make sure you have the correct access rights and the repository exists."
274+
data?.value?.messageParameters?.shouldContainValue(
275+
"Repository not found The requested repository does not exist, or you do not have permission " +
276+
"to access it. fatal: Could not read from remote repository. Please make sure you have the " +
277+
"correct access rights and the repository exists."
278+
)
279+
}
280+
}
281+
259282
"A file can be marked as identified" {
260283
service.markAsIdentified(
261284
"",
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"id" : "ae6669fb-7ca6-496a-9268-7e4eebb64007",
3+
"name" : "apiphp",
4+
"request" : {
5+
"url" : "/api.php",
6+
"method" : "POST",
7+
"bodyPatterns" : [ {
8+
"equalToJson" : "{\"action\":\"create\",\"group\":\"scans\",\"data\":{\"username\":\"\",\"key\":\"\",\"scan_code\":\"semver4j_20201203_090342\",\"project_code\":\"semver4j\",\"git_repo_url\":\"git_repo_url\",\"git_branch\":\"develop\"}}",
9+
"ignoreArrayOrder" : true,
10+
"ignoreExtraElements" : true
11+
} ]
12+
},
13+
"response" : {
14+
"status" : 200,
15+
"body" : "{\"operation\":\"scans_create\", \"status\":\"0\", \"data\":[{\"code\": \"RequestData.Base.issue_with_executing_command\", \"message\":\"Field git_repo_url: there was an issue executing command: timeout 200 git ls-remote 'ssh git repo' 2>&1. Exit status: 128. Output: Repository not found The requested repository does not exist, or you do not have permission to access it. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.\", \"message_parameters\":{\"fieldname\":\"git_repo_url\", \"cmd\":\"timeout 200 git ls-remote 'ssh git repo' 2>&1\", \"exitStatus\":128, \"out\":\"Repository not found The requested repository does not exist, or you do not have permission to access it. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.\"} }], \"error\":\"RequestData.Base.issues_while_parsing_request\", \"message\":\"These issues were found while parsing the request:\", \"message_parameters\":[]}",
16+
"headers" : {
17+
"Content-Type" : "text/html; charset=UTF-8",
18+
"Date" : "Thu, 03 Dec 2020 08:03:42 GMT",
19+
"Server" : "Apache/2.4.38 (Debian)",
20+
"Vary" : "Accept-Encoding"
21+
}
22+
},
23+
"uuid" : "ae6669fb-7ca6-496a-9268-7e4eebb64007",
24+
"persistent" : true,
25+
"insertionIndex" : 5
26+
}

plugins/scanners/fossid/src/main/kotlin/FossId.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,16 @@ class FossId internal constructor(
679679
.createScan(config.user.value, config.apiKey.value, projectCode, scanCode, url, revision, reference)
680680
.checkResponse("create scan")
681681

682-
val scanId = response.data?.get("scan_id")
682+
val data = response.data?.value
683+
684+
if (data?.message != null) {
685+
logger.warn {
686+
"Create scan returned an error content as payload (see issue #8462)." +
687+
" Additional information: ${data.message}"
688+
}
689+
}
690+
691+
val scanId = data?.scanId
683692

684693
requireNotNull(scanId) { "Scan could not be created. The response was: ${response.message}." }
685694

plugins/scanners/fossid/src/test/kotlin/TestUtils.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ import java.util.concurrent.atomic.AtomicInteger
2929
import org.ossreviewtoolkit.clients.fossid.EntityResponseBody
3030
import org.ossreviewtoolkit.clients.fossid.FossIdRestService
3131
import org.ossreviewtoolkit.clients.fossid.FossIdServiceWithVersion
32-
import org.ossreviewtoolkit.clients.fossid.MapResponseBody
3332
import org.ossreviewtoolkit.clients.fossid.PolymorphicData
33+
import org.ossreviewtoolkit.clients.fossid.PolymorphicDataResponseBody
3434
import org.ossreviewtoolkit.clients.fossid.PolymorphicInt
3535
import org.ossreviewtoolkit.clients.fossid.PolymorphicList
3636
import org.ossreviewtoolkit.clients.fossid.PolymorphicResponseBody
@@ -48,6 +48,7 @@ import org.ossreviewtoolkit.clients.fossid.listMatchedLines
4848
import org.ossreviewtoolkit.clients.fossid.listPendingFiles
4949
import org.ossreviewtoolkit.clients.fossid.listScansForProject
5050
import org.ossreviewtoolkit.clients.fossid.listSnippets
51+
import org.ossreviewtoolkit.clients.fossid.model.CreateScanResponse
5152
import org.ossreviewtoolkit.clients.fossid.model.Scan
5253
import org.ossreviewtoolkit.clients.fossid.model.identification.common.LicenseMatchType
5354
import org.ossreviewtoolkit.clients.fossid.model.identification.identifiedFiles.IdentifiedFile
@@ -548,7 +549,10 @@ internal fun FossIdServiceWithVersion.expectCreateScan(
548549
): FossIdServiceWithVersion {
549550
coEvery {
550551
createScan(USER, API_KEY, projectCode, scanCode, vcsInfo.url, vcsInfo.revision, comment)
551-
} returns MapResponseBody(status = 1, data = mapOf("scan_id" to SCAN_ID.toString()))
552+
} returns PolymorphicDataResponseBody(
553+
status = 1,
554+
data = PolymorphicData(CreateScanResponse(SCAN_ID.toString()))
555+
)
552556
return this
553557
}
554558

0 commit comments

Comments
 (0)