mirror of
https://github.com/corda/corda.git
synced 2024-12-21 13:57:54 +00:00
Safe parsing of min platform version and target version from CorDapp MANIFEST files (#4031)
Also includes some cleanup
This commit is contained in:
parent
064c72dfb1
commit
85d2a85e85
@ -42,8 +42,7 @@ data class CordappImpl(
|
||||
// TODO Why a seperate Info class and not just have the fields directly in CordappImpl?
|
||||
data class Info(val shortName: String, val vendor: String, val version: String, val minimumPlatformVersion: Int, val targetPlatformVersion: Int) {
|
||||
companion object {
|
||||
private const val UNKNOWN_VALUE = "Unknown"
|
||||
|
||||
const val UNKNOWN_VALUE = "Unknown"
|
||||
val UNKNOWN = Info(UNKNOWN_VALUE, UNKNOWN_VALUE, UNKNOWN_VALUE, 1, 1)
|
||||
}
|
||||
|
||||
|
@ -112,10 +112,12 @@ class JarScanningCordappLoader private constructor(private val cordappJarPaths:
|
||||
)
|
||||
|
||||
private fun loadCordapps(): List<CordappImpl> {
|
||||
val cordapps = cordappJarPaths.map { scanCordapp(it).toCordapp(it) }
|
||||
val cordapps = cordappJarPaths
|
||||
.map { scanCordapp(it).toCordapp(it) }
|
||||
.filter {
|
||||
if (it.info.minimumPlatformVersion > versionInfo.platformVersion) {
|
||||
logger.warn("Not loading CorDapp ${it.info.shortName} (${it.info.vendor}) as it requires minimum platform version ${it.info.minimumPlatformVersion} (This node is running version ${versionInfo.platformVersion}).")
|
||||
logger.warn("Not loading CorDapp ${it.info.shortName} (${it.info.vendor}) as it requires minimum " +
|
||||
"platform version ${it.info.minimumPlatformVersion} (This node is running version ${versionInfo.platformVersion}).")
|
||||
false
|
||||
} else {
|
||||
true
|
||||
@ -126,7 +128,7 @@ class JarScanningCordappLoader private constructor(private val cordappJarPaths:
|
||||
}
|
||||
|
||||
private fun RestrictedScanResult.toCordapp(url: RestrictedURL): CordappImpl {
|
||||
val info = url.url.openStream().let(::JarInputStream).use { it.manifest }.toCordappInfo(CordappImpl.jarName(url.url))
|
||||
val info = url.url.openStream().let(::JarInputStream).use { it.manifest?.toCordappInfo(CordappImpl.jarName(url.url)) ?: CordappImpl.Info.UNKNOWN }
|
||||
return CordappImpl(
|
||||
findContractClassNames(this),
|
||||
findInitiatedFlows(this),
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.corda.node.internal.cordapp
|
||||
|
||||
import net.corda.core.internal.cordapp.CordappImpl
|
||||
import net.corda.core.internal.cordapp.CordappImpl.Info.Companion.UNKNOWN_VALUE
|
||||
import java.util.jar.Attributes
|
||||
import java.util.jar.Manifest
|
||||
|
||||
@ -23,23 +24,23 @@ fun createTestManifest(name: String, title: String, version: String, vendor: Str
|
||||
return manifest
|
||||
}
|
||||
|
||||
operator fun Manifest.set(key: String, value: String) {
|
||||
mainAttributes.putValue(key, value)
|
||||
operator fun Manifest.set(key: String, value: String): String? {
|
||||
return mainAttributes.putValue(key, value)
|
||||
}
|
||||
|
||||
fun Manifest?.toCordappInfo(defaultShortName: String): CordappImpl.Info {
|
||||
var info = CordappImpl.Info.UNKNOWN
|
||||
(this?.mainAttributes?.getValue("Name") ?: defaultShortName).let { shortName ->
|
||||
info = info.copy(shortName = shortName)
|
||||
}
|
||||
this?.mainAttributes?.getValue("Implementation-Vendor")?.let { vendor ->
|
||||
info = info.copy(vendor = vendor)
|
||||
}
|
||||
this?.mainAttributes?.getValue("Implementation-Version")?.let { version ->
|
||||
info = info.copy(version = version)
|
||||
}
|
||||
val minPlatformVersion = this?.mainAttributes?.getValue("Min-Platform-Version")?.toInt() ?: 1
|
||||
val targetPlatformVersion = this?.mainAttributes?.getValue("Target-Platform-Version")?.toInt() ?: minPlatformVersion
|
||||
info = info.copy(minimumPlatformVersion = minPlatformVersion, targetPlatformVersion = targetPlatformVersion)
|
||||
return info
|
||||
}
|
||||
operator fun Manifest.get(key: String): String? = mainAttributes.getValue(key)
|
||||
|
||||
fun Manifest.toCordappInfo(defaultShortName: String): CordappImpl.Info {
|
||||
val shortName = this["Name"] ?: defaultShortName
|
||||
val vendor = this["Implementation-Vendor"] ?: UNKNOWN_VALUE
|
||||
val version = this["Implementation-Version"] ?: UNKNOWN_VALUE
|
||||
val minPlatformVersion = this["Min-Platform-Version"]?.toIntOrNull() ?: 1
|
||||
val targetPlatformVersion = this["Target-Platform-Version"]?.toIntOrNull() ?: minPlatformVersion
|
||||
return CordappImpl.Info(
|
||||
shortName = shortName,
|
||||
vendor = vendor,
|
||||
version = version,
|
||||
minimumPlatformVersion = minPlatformVersion,
|
||||
targetPlatformVersion = targetPlatformVersion
|
||||
)
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.flows.*
|
||||
import net.corda.node.VersionInfo
|
||||
import net.corda.node.cordapp.CordappLoader
|
||||
import net.corda.nodeapi.internal.PLATFORM_VERSION
|
||||
import net.corda.testing.node.internal.cordappsForPackages
|
||||
import net.corda.testing.node.internal.getTimestampAsDirectoryName
|
||||
import net.corda.testing.node.internal.packageInDirectory
|
||||
@ -45,7 +44,7 @@ class JarScanningCordappLoaderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test that classes that aren't in cordapps aren't loaded`() {
|
||||
fun `classes that aren't in cordapps aren't loaded`() {
|
||||
// Basedir will not be a corda node directory so the dummy flow shouldn't be recognised as a part of a cordapp
|
||||
val loader = JarScanningCordappLoader.fromDirectories(listOf(Paths.get(".")))
|
||||
assertThat(loader.cordapps).containsOnly(loader.coreCordapp)
|
||||
@ -56,10 +55,9 @@ class JarScanningCordappLoaderTest {
|
||||
val isolatedJAR = JarScanningCordappLoaderTest::class.java.getResource("isolated.jar")!!
|
||||
val loader = JarScanningCordappLoader.fromJarUrls(listOf(isolatedJAR))
|
||||
|
||||
val actual = loader.cordapps.toTypedArray()
|
||||
assertThat(actual).hasSize(2)
|
||||
assertThat(loader.cordapps).hasSize(2)
|
||||
|
||||
val actualCordapp = actual.single { it != loader.coreCordapp }
|
||||
val actualCordapp = loader.cordapps.single { it != loader.coreCordapp }
|
||||
assertThat(actualCordapp.contractClassNames).isEqualTo(listOf(isolatedContractId))
|
||||
assertThat(actualCordapp.initiatedFlows.single().name).isEqualTo("net.corda.finance.contracts.isolated.IsolatedDummyFlow\$Acceptor")
|
||||
assertThat(actualCordapp.rpcFlows).isEmpty()
|
||||
@ -113,7 +111,7 @@ class JarScanningCordappLoaderTest {
|
||||
fun `cordapp classloader sets target and min version to 1 if not specified`() {
|
||||
val jar = JarScanningCordappLoaderTest::class.java.getResource("versions/no-min-or-target-version.jar")!!
|
||||
val loader = JarScanningCordappLoader.fromJarUrls(listOf(jar), VersionInfo.UNKNOWN)
|
||||
loader.cordapps.filter { !it.info.shortName.equals("corda-core") }.forEach {
|
||||
loader.cordapps.filter { it.info.shortName != "corda-core" }.forEach {
|
||||
assertThat(it.info.targetPlatformVersion).isEqualTo(1)
|
||||
assertThat(it.info.minimumPlatformVersion).isEqualTo(1)
|
||||
}
|
||||
@ -126,7 +124,7 @@ class JarScanningCordappLoaderTest {
|
||||
val jar = JarScanningCordappLoaderTest::class.java.getResource("versions/min-2-target-3.jar")!!
|
||||
val loader = JarScanningCordappLoader.fromJarUrls(listOf(jar), VersionInfo.UNKNOWN)
|
||||
// exclude the core cordapp
|
||||
val cordapp = loader.cordapps.filter { it.cordappClasses.contains("net.corda.core.internal.cordapp.CordappImpl")}.single()
|
||||
val cordapp = loader.cordapps.single { it.cordappClasses.contains("net.corda.core.internal.cordapp.CordappImpl") }
|
||||
assertThat(cordapp.info.targetPlatformVersion).isEqualTo(3)
|
||||
assertThat(cordapp.info.minimumPlatformVersion).isEqualTo(2)
|
||||
}
|
||||
@ -137,17 +135,17 @@ class JarScanningCordappLoaderTest {
|
||||
val jar = JarScanningCordappLoaderTest::class.java.getResource("versions/min-2-no-target.jar")!!
|
||||
val loader = JarScanningCordappLoader.fromJarUrls(listOf(jar), VersionInfo.UNKNOWN)
|
||||
// exclude the core cordapp
|
||||
val cordapp = loader.cordapps.filter { it.cordappClasses.contains("net.corda.core.internal.cordapp.CordappImpl")}.single()
|
||||
val cordapp = loader.cordapps.single { it.cordappClasses.contains("net.corda.core.internal.cordapp.CordappImpl") }
|
||||
assertThat(cordapp.info.targetPlatformVersion).isEqualTo(2)
|
||||
assertThat(cordapp.info.minimumPlatformVersion).isEqualTo(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cordapp classloader does not load apps when their min platform version is greater than the platform version`() {
|
||||
val jar = JarScanningCordappLoaderTest::class.java.getResource("versions/min-2-target-3.jar")!!
|
||||
fun `cordapp classloader does not load apps when their min platform version is greater than the node platform version`() {
|
||||
val jar = JarScanningCordappLoaderTest::class.java.getResource("versions/min-2-no-target.jar")!!
|
||||
val loader = JarScanningCordappLoader.fromJarUrls(listOf(jar), VersionInfo.UNKNOWN.copy(platformVersion = 1))
|
||||
// exclude the core cordapp
|
||||
assertThat(loader.cordapps.size).isEqualTo(1)
|
||||
assertThat(loader.cordapps).hasSize(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -155,7 +153,7 @@ class JarScanningCordappLoaderTest {
|
||||
val jar = JarScanningCordappLoaderTest::class.java.getResource("versions/min-2-target-3.jar")!!
|
||||
val loader = JarScanningCordappLoader.fromJarUrls(listOf(jar), VersionInfo.UNKNOWN.copy(platformVersion = 1000))
|
||||
// exclude the core cordapp
|
||||
assertThat(loader.cordapps.size).isEqualTo(2)
|
||||
assertThat(loader.cordapps).hasSize(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -163,11 +161,10 @@ class JarScanningCordappLoaderTest {
|
||||
val jar = JarScanningCordappLoaderTest::class.java.getResource("versions/min-2-target-3.jar")!!
|
||||
val loader = JarScanningCordappLoader.fromJarUrls(listOf(jar), VersionInfo.UNKNOWN.copy(platformVersion = 2))
|
||||
// exclude the core cordapp
|
||||
assertThat(loader.cordapps.size).isEqualTo(2)
|
||||
assertThat(loader.cordapps).hasSize(2)
|
||||
}
|
||||
|
||||
private fun cordappLoaderForPackages(packages: Iterable<String>, versionInfo: VersionInfo = VersionInfo.UNKNOWN): CordappLoader {
|
||||
|
||||
private fun cordappLoaderForPackages(packages: Iterable<String>): CordappLoader {
|
||||
val cordapps = cordappsForPackages(packages)
|
||||
return testDirectory().let { directory ->
|
||||
cordapps.packageInDirectory(directory)
|
||||
@ -176,7 +173,6 @@ class JarScanningCordappLoaderTest {
|
||||
}
|
||||
|
||||
private fun testDirectory(): Path {
|
||||
|
||||
return Paths.get("build", getTimestampAsDirectoryName())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user