Skip to content

Commit 0db7e0f

Browse files
committed
refactor(advisor): Mitgrate plugins to ConfigurablePluginFactory
Relates to #6507. Signed-off-by: Sebastian Schuberth <[email protected]>
1 parent 5cfca01 commit 0db7e0f

File tree

11 files changed

+111
-186
lines changed

11 files changed

+111
-186
lines changed

advisor/src/main/kotlin/AdviceProviderFactory.kt

+11-36
Original file line numberDiff line numberDiff line change
@@ -19,52 +19,27 @@
1919

2020
package org.ossreviewtoolkit.advisor
2121

22-
import java.util.ServiceLoader
23-
2422
import org.ossreviewtoolkit.model.config.AdvisorConfiguration
25-
import org.ossreviewtoolkit.model.config.Options
23+
import org.ossreviewtoolkit.utils.common.ConfigurablePluginFactory
2624
import org.ossreviewtoolkit.utils.common.Plugin
27-
import org.ossreviewtoolkit.utils.ort.ORT_CONFIG_FILENAME
28-
import org.ossreviewtoolkit.utils.ort.ortConfigDirectory
2925

3026
/**
31-
* A common interface for use with [ServiceLoader] that all [AbstractAdviceProviderFactory] classes need to
32-
* implement.
27+
* The extension point for [AdviceProvider]s.
3328
*/
34-
interface AdviceProviderFactory : Plugin {
35-
/**
36-
* Create an [AdviceProvider] using the specified [config].
37-
*/
38-
fun create(config: AdvisorConfiguration): AdviceProvider
39-
}
29+
interface AdviceProviderFactory : ConfigurablePluginFactory<AdviceProvider> {
30+
companion object {
31+
val ALL = Plugin.getAll<AdviceProviderFactory>()
32+
}
4033

41-
/**
42-
* A generic factory class for an [AdviceProvider].
43-
*/
44-
abstract class AbstractAdviceProviderFactory<out T : AdviceProvider>(
45-
override val type: String
46-
) : AdviceProviderFactory {
47-
abstract override fun create(config: AdvisorConfiguration): T
34+
override fun create(config: Map<String, String>): AdviceProvider = create(parseConfig(config))
4835

4936
/**
50-
* For providers that require configuration, return the typed configuration dedicated to provider [T] or throw if it
51-
* does not exist.
37+
* Create a new [AdviceProvider] with [config].
5238
*/
53-
protected fun <T : Any> AdvisorConfiguration.forProvider(select: AdvisorConfiguration.() -> T?): T =
54-
requireNotNull(select()) {
55-
"No configuration for '$type' found in '${ortConfigDirectory.resolve(ORT_CONFIG_FILENAME)}'."
56-
}
57-
58-
/**
59-
* Return a map with options for the [AdviceProvider] managed by this factory or an empty map if no options are
60-
* available.
61-
*/
62-
protected fun AdvisorConfiguration.providerOptions(): Options =
63-
options.orEmpty()[type].orEmpty()
39+
fun create(config: AdvisorConfiguration): AdviceProvider
6440

6541
/**
66-
* Return the provider's name here to allow Clikt to display something meaningful when listing the advisors which
67-
* are enabled by default via their factories.
42+
* Parse the [config] map into an object.
6843
*/
69-
override fun toString() = type
44+
fun parseConfig(config: Map<String, String>): AdvisorConfiguration
7045
}

advisor/src/main/kotlin/Advisor.kt

+1-7
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import org.ossreviewtoolkit.model.Identifier
3434
import org.ossreviewtoolkit.model.OrtResult
3535
import org.ossreviewtoolkit.model.Package
3636
import org.ossreviewtoolkit.model.config.AdvisorConfiguration
37-
import org.ossreviewtoolkit.utils.common.Plugin
3837
import org.ossreviewtoolkit.utils.ort.Environment
3938

4039
/**
@@ -45,12 +44,7 @@ class Advisor(
4544
private val providerFactories: List<AdviceProviderFactory>,
4645
private val config: AdvisorConfiguration
4746
) {
48-
companion object : Logging {
49-
/**
50-
* All [advice provider factories][AdviceProviderFactory] available in the classpath, associated by their names.
51-
*/
52-
val ALL by lazy { Plugin.getAll<AdviceProviderFactory>() }
53-
}
47+
companion object : Logging
5448

5549
/**
5650
* Query the [advice providers][providerFactories] and add the result to the provided [ortResult]. Excluded packages

advisor/src/main/kotlin/advisors/GitHubDefects.kt

+26-7
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import kotlinx.coroutines.withContext
3333

3434
import org.apache.logging.log4j.kotlin.Logging
3535

36-
import org.ossreviewtoolkit.advisor.AbstractAdviceProviderFactory
3736
import org.ossreviewtoolkit.advisor.AdviceProvider
37+
import org.ossreviewtoolkit.advisor.AdviceProviderFactory
3838
import org.ossreviewtoolkit.clients.github.DateTime
3939
import org.ossreviewtoolkit.clients.github.GitHubService
4040
import org.ossreviewtoolkit.clients.github.Paging
@@ -82,15 +82,34 @@ import org.ossreviewtoolkit.utils.ort.showStackTrace
8282
*/
8383
class GitHubDefects(name: String, config: GitHubDefectsConfiguration) : AdviceProvider(name) {
8484
companion object : Logging {
85+
/**
86+
* The default list of label to filter that typically indicate that an issue is not a defect.
87+
*/
88+
val DEFAULT_LABEL_FILTER = listOf("!duplicate", "!enhancement", "!invalid", "!question", "*")
89+
8590
/**
8691
* The default number of parallel requests executed by this advisor implementation. This value is used if the
8792
* corresponding property in the configuration is unspecified. It is chosen rather arbitrarily.
8893
*/
8994
const val DEFAULT_PARALLEL_REQUESTS = 4
9095
}
9196

92-
class Factory : AbstractAdviceProviderFactory<GitHubDefects>("GitHubDefects") {
93-
override fun create(config: AdvisorConfiguration) = GitHubDefects(type, config.forProvider { gitHubDefects })
97+
class Factory : AdviceProviderFactory {
98+
override val type = "GitHubDefects"
99+
100+
override fun create(config: AdvisorConfiguration) =
101+
GitHubDefects(type, config.gitHubDefects ?: parseSpecificConfig(emptyMap()))
102+
103+
override fun parseConfig(config: Map<String, String>) =
104+
AdvisorConfiguration(gitHubDefects = parseSpecificConfig(config))
105+
106+
private fun parseSpecificConfig(config: Map<String, String>) = GitHubDefectsConfiguration(
107+
token = config["token"].orEmpty(),
108+
endpointUrl = config["endpointUrl"] ?: GitHubService.ENDPOINT,
109+
labelFilter = config["labelFilter"]?.split(',')?.map { it.trim() } ?: DEFAULT_LABEL_FILTER,
110+
maxNumberOfIssuesPerRepository = config["maxNumberOfIssuesPerRepository"]?.toIntOrNull() ?: Int.MAX_VALUE,
111+
parallelRequests = config["parallelRequests"]?.toIntOrNull() ?: DEFAULT_PARALLEL_REQUESTS,
112+
)
94113
}
95114

96115
/**
@@ -103,16 +122,16 @@ class GitHubDefects(name: String, config: GitHubDefectsConfiguration) : AdvicePr
103122
private val labelFilters = config.labelFilter.toLabelFilters()
104123

105124
/** The maximum number of defects to retrieve. */
106-
private val maxDefects = config.maxNumberOfIssuesPerRepository ?: Int.MAX_VALUE
125+
private val maxDefects = config.maxNumberOfIssuesPerRepository
107126

108127
/** The number of requests to be processed in parallel. */
109-
private val parallelRequests = config.parallelRequests ?: DEFAULT_PARALLEL_REQUESTS
128+
private val parallelRequests = config.parallelRequests
110129

111130
/** The service for accessing the GitHub GraphQL API. */
112131
private val service by lazy {
113132
GitHubService.create(
114-
token = config.token.orEmpty(),
115-
url = config.endpointUrl ?: GitHubService.ENDPOINT,
133+
token = config.token,
134+
url = config.endpointUrl,
116135
client = HttpClient(OkHttp)
117136
)
118137
}

advisor/src/main/kotlin/advisors/NexusIq.kt

+16-3
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import java.time.Instant
2626

2727
import org.apache.logging.log4j.kotlin.Logging
2828

29-
import org.ossreviewtoolkit.advisor.AbstractAdviceProviderFactory
3029
import org.ossreviewtoolkit.advisor.AdviceProvider
30+
import org.ossreviewtoolkit.advisor.AdviceProviderFactory
3131
import org.ossreviewtoolkit.clients.nexusiq.NexusIqService
3232
import org.ossreviewtoolkit.model.AdvisorCapability
3333
import org.ossreviewtoolkit.model.AdvisorDetails
@@ -63,8 +63,21 @@ private val READ_TIMEOUT = Duration.ofSeconds(60)
6363
class NexusIq(name: String, private val config: NexusIqConfiguration) : AdviceProvider(name) {
6464
companion object : Logging
6565

66-
class Factory : AbstractAdviceProviderFactory<NexusIq>("NexusIQ") {
67-
override fun create(config: AdvisorConfiguration) = NexusIq(type, config.forProvider { nexusIq })
66+
class Factory : AdviceProviderFactory {
67+
override val type = "NexusIQ"
68+
69+
override fun create(config: AdvisorConfiguration) =
70+
NexusIq(type, config.nexusIq ?: parseSpecificConfig(emptyMap()))
71+
72+
override fun parseConfig(config: Map<String, String>) =
73+
AdvisorConfiguration(nexusIq = parseSpecificConfig(config))
74+
75+
private fun parseSpecificConfig(config: Map<String, String>) = NexusIqConfiguration(
76+
serverUrl = config.getValue("serverUrl"),
77+
browseUrl = config["browseUrl"] ?: config.getValue("serverUrl"),
78+
username = config["username"],
79+
password = config["password"]
80+
)
6881
}
6982

7083
override val details: AdvisorDetails = AdvisorDetails(providerName, enumSetOf(AdvisorCapability.VULNERABILITIES))

advisor/src/main/kotlin/advisors/OssIndex.kt

+13-3
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ import java.time.Instant
2525

2626
import org.apache.logging.log4j.kotlin.Logging
2727

28-
import org.ossreviewtoolkit.advisor.AbstractAdviceProviderFactory
2928
import org.ossreviewtoolkit.advisor.AdviceProvider
29+
import org.ossreviewtoolkit.advisor.AdviceProviderFactory
3030
import org.ossreviewtoolkit.clients.ossindex.OssIndexService
3131
import org.ossreviewtoolkit.model.AdvisorCapability
3232
import org.ossreviewtoolkit.model.AdvisorDetails
@@ -54,8 +54,18 @@ private const val BULK_REQUEST_SIZE = 128
5454
class OssIndex(name: String, config: OssIndexConfiguration) : AdviceProvider(name) {
5555
companion object : Logging
5656

57-
class Factory : AbstractAdviceProviderFactory<OssIndex>("OssIndex") {
58-
override fun create(config: AdvisorConfiguration) = OssIndex(type, config.forProvider { ossIndex })
57+
class Factory : AdviceProviderFactory {
58+
override val type = "OssIndex"
59+
60+
override fun create(config: AdvisorConfiguration) =
61+
OssIndex(type, config.ossIndex ?: parseSpecificConfig(emptyMap()))
62+
63+
override fun parseConfig(config: Map<String, String>) =
64+
AdvisorConfiguration(ossIndex = parseSpecificConfig(config))
65+
66+
private fun parseSpecificConfig(config: Map<String, String>) = OssIndexConfiguration(
67+
serverUrl = config["serverUrl"]
68+
)
5969
}
6070

6171
override val details = AdvisorDetails(providerName, enumSetOf(AdvisorCapability.VULNERABILITIES))

advisor/src/main/kotlin/advisors/Osv.kt

+12-4
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import kotlinx.serialization.json.contentOrNull
2626

2727
import org.apache.logging.log4j.kotlin.Logging
2828

29-
import org.ossreviewtoolkit.advisor.AbstractAdviceProviderFactory
3029
import org.ossreviewtoolkit.advisor.AdviceProvider
30+
import org.ossreviewtoolkit.advisor.AdviceProviderFactory
3131
import org.ossreviewtoolkit.clients.osv.Ecosystem
3232
import org.ossreviewtoolkit.clients.osv.OsvService
3333
import org.ossreviewtoolkit.clients.osv.Severity
@@ -55,10 +55,18 @@ import us.springett.cvss.Cvss
5555
class Osv(name: String, config: OsvConfiguration) : AdviceProvider(name) {
5656
companion object : Logging
5757

58-
class Factory : AbstractAdviceProviderFactory<Osv>("OSV") {
58+
class Factory : AdviceProviderFactory {
59+
override val type = "OSV"
60+
5961
override fun create(config: AdvisorConfiguration) =
60-
// OSV does not require any dedicated configuration to be present.
61-
Osv(type, config.forProvider { osv })
62+
Osv(type, config.osv ?: parseSpecificConfig(emptyMap()))
63+
64+
override fun parseConfig(config: Map<String, String>) =
65+
AdvisorConfiguration(osv = parseSpecificConfig(config))
66+
67+
private fun parseSpecificConfig(config: Map<String, String>) = OsvConfiguration(
68+
serverUrl = config["serverUrl"]
69+
)
6270
}
6371

6472
override val details: AdvisorDetails = AdvisorDetails(providerName, enumSetOf(AdvisorCapability.VULNERABILITIES))

advisor/src/main/kotlin/advisors/VulnerableCode.kt

+14-3
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ package org.ossreviewtoolkit.advisor.advisors
2222
import java.net.URI
2323
import java.time.Instant
2424

25-
import org.ossreviewtoolkit.advisor.AbstractAdviceProviderFactory
2625
import org.ossreviewtoolkit.advisor.AdviceProvider
26+
import org.ossreviewtoolkit.advisor.AdviceProviderFactory
2727
import org.ossreviewtoolkit.clients.vulnerablecode.VulnerableCodeService
2828
import org.ossreviewtoolkit.clients.vulnerablecode.VulnerableCodeService.PackagesWrapper
2929
import org.ossreviewtoolkit.model.AdvisorCapability
@@ -49,8 +49,19 @@ private const val BULK_REQUEST_SIZE = 100
4949
* [VulnerableCode][https://github.com/nexB/vulnerablecode] instance.
5050
*/
5151
class VulnerableCode(name: String, config: VulnerableCodeConfiguration) : AdviceProvider(name) {
52-
class Factory : AbstractAdviceProviderFactory<VulnerableCode>("VulnerableCode") {
53-
override fun create(config: AdvisorConfiguration) = VulnerableCode(type, config.forProvider { vulnerableCode })
52+
class Factory : AdviceProviderFactory {
53+
override val type = "VulnerableCode"
54+
55+
override fun create(config: AdvisorConfiguration) =
56+
VulnerableCode(type, config.vulnerableCode ?: parseSpecificConfig(emptyMap()))
57+
58+
override fun parseConfig(config: Map<String, String>) =
59+
AdvisorConfiguration(vulnerableCode = parseSpecificConfig(config))
60+
61+
private fun parseSpecificConfig(config: Map<String, String>) = VulnerableCodeConfiguration(
62+
serverUrl = config["serverUrl"],
63+
apiKey = config["apiKey"]
64+
)
5465
}
5566

5667
/**

advisor/src/test/kotlin/AbstractAdviceProviderFactoryTest.kt

-112
This file was deleted.

0 commit comments

Comments
 (0)