Merge pull request #767 from corda/os-merge-d3446e2

O/S merge from d3446e2
This commit is contained in:
Shams Asari 2018-04-23 17:10:32 +01:00 committed by GitHub
commit fc3dde9f66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 655 additions and 522 deletions

View File

@ -44,13 +44,13 @@ import java.lang.reflect.Field
import java.math.BigDecimal import java.math.BigDecimal
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.HttpURLConnection.HTTP_OK import java.net.HttpURLConnection.HTTP_OK
import java.net.URI
import java.net.URL import java.net.URL
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.nio.charset.Charset import java.nio.file.CopyOption
import java.nio.charset.StandardCharsets.UTF_8 import java.nio.file.Files
import java.nio.file.* import java.nio.file.Path
import java.nio.file.attribute.FileAttribute import java.nio.file.Paths
import java.nio.file.attribute.FileTime
import java.security.KeyPair import java.security.KeyPair
import java.security.PrivateKey import java.security.PrivateKey
import java.security.PublicKey import java.security.PublicKey
@ -78,14 +78,6 @@ infix fun Temporal.until(endExclusive: Temporal): Duration = Duration.between(th
operator fun Duration.div(divider: Long): Duration = dividedBy(divider) operator fun Duration.div(divider: Long): Duration = dividedBy(divider)
operator fun Duration.times(multiplicand: Long): Duration = multipliedBy(multiplicand) operator fun Duration.times(multiplicand: Long): Duration = multipliedBy(multiplicand)
/**
* Allows you to write code like: Paths.get("someDir") / "subdir" / "filename" but using the Paths API to avoid platform
* separator problems.
*/
operator fun Path.div(other: String): Path = resolve(other)
operator fun String.div(other: String): Path = Paths.get(this) / other
/** /**
* Returns the single element matching the given [predicate], or `null` if the collection is empty, or throws exception * Returns the single element matching the given [predicate], or `null` if the collection is empty, or throws exception
* if more than one element was found. * if more than one element was found.
@ -130,43 +122,6 @@ fun <T> List<T>.indexOfOrThrow(item: T): Int {
return i return i
} }
fun Path.createDirectory(vararg attrs: FileAttribute<*>): Path = Files.createDirectory(this, *attrs)
fun Path.createDirectories(vararg attrs: FileAttribute<*>): Path = Files.createDirectories(this, *attrs)
fun Path.exists(vararg options: LinkOption): Boolean = Files.exists(this, *options)
fun Path.copyToDirectory(targetDir: Path, vararg options: CopyOption): Path {
require(targetDir.isDirectory()) { "$targetDir is not a directory" }
val targetFile = targetDir.resolve(fileName)
Files.copy(this, targetFile, *options)
return targetFile
}
fun Path.moveTo(target: Path, vararg options: CopyOption): Path = Files.move(this, target, *options)
fun Path.isRegularFile(vararg options: LinkOption): Boolean = Files.isRegularFile(this, *options)
fun Path.isDirectory(vararg options: LinkOption): Boolean = Files.isDirectory(this, *options)
inline val Path.size: Long get() = Files.size(this)
fun Path.lastModifiedTime(vararg options: LinkOption): FileTime = Files.getLastModifiedTime(this, *options)
inline fun <R> Path.list(block: (Stream<Path>) -> R): R = Files.list(this).use(block)
fun Path.deleteIfExists(): Boolean = Files.deleteIfExists(this)
fun Path.reader(charset: Charset = UTF_8): BufferedReader = Files.newBufferedReader(this, charset)
fun Path.writer(charset: Charset = UTF_8, vararg options: OpenOption): BufferedWriter = Files.newBufferedWriter(this, charset, *options)
fun Path.readAll(): ByteArray = Files.readAllBytes(this)
inline fun <R> Path.read(vararg options: OpenOption, block: (InputStream) -> R): R = Files.newInputStream(this, *options).use(block)
inline fun Path.write(createDirs: Boolean = false, vararg options: OpenOption = emptyArray(), block: (OutputStream) -> Unit) {
if (createDirs) {
normalize().parent?.createDirectories()
}
Files.newOutputStream(this, *options).use(block)
}
inline fun <R> Path.readLines(charset: Charset = UTF_8, block: (Stream<String>) -> R): R = Files.lines(this, charset).use(block)
fun Path.readAllLines(charset: Charset = UTF_8): List<String> = Files.readAllLines(this, charset)
fun Path.writeLines(lines: Iterable<CharSequence>, charset: Charset = UTF_8, vararg options: OpenOption): Path = Files.write(this, lines, charset, *options)
inline fun <reified T : Any> Path.readObject(): T = readAll().deserialize()
/** Calculate the hash of the contents of this file. */
val Path.hash: SecureHash get() = read { it.hash() }
fun InputStream.copyTo(target: Path, vararg options: CopyOption): Long = Files.copy(this, target, *options) fun InputStream.copyTo(target: Path, vararg options: CopyOption): Long = Files.copy(this, target, *options)
/** Same as [InputStream.readBytes] but also closes the stream. */ /** Same as [InputStream.readBytes] but also closes the stream. */
@ -361,6 +316,10 @@ fun TransactionBuilder.toLedgerTransaction(services: ServicesForResolution, seri
/** Convenience method to get the package name of a class literal. */ /** Convenience method to get the package name of a class literal. */
val KClass<*>.packageName: String get() = java.`package`.name val KClass<*>.packageName: String get() = java.`package`.name
fun URI.toPath(): Path = Paths.get(this)
fun URL.toPath(): Path = toURI().toPath()
fun URL.openHttpConnection(): HttpURLConnection = openConnection() as HttpURLConnection fun URL.openHttpConnection(): HttpURLConnection = openConnection() as HttpURLConnection
fun URL.post(serializedData: OpaqueBytes, vararg properties: Pair<String, String>): ByteArray { fun URL.post(serializedData: OpaqueBytes, vararg properties: Pair<String, String>): ByteArray {

View File

@ -0,0 +1,176 @@
package net.corda.core.internal
import net.corda.core.crypto.SecureHash
import net.corda.core.serialization.deserialize
import java.io.*
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets.UTF_8
import java.nio.file.*
import java.nio.file.attribute.BasicFileAttributes
import java.nio.file.attribute.FileAttribute
import java.nio.file.attribute.FileTime
import java.util.stream.Stream
import kotlin.streams.toList
/**
* Allows you to write code like: Paths.get("someDir") / "subdir" / "filename" but using the Paths API to avoid platform
* separator problems.
* @see Path.resolve
*/
operator fun Path.div(other: String): Path = resolve(other)
/**
* Allows you to write code like: "someDir" / "subdir" / "filename" but using the Paths API to avoid platform
* separator problems.
* @see Path.resolve
*/
operator fun String.div(other: String): Path = Paths.get(this) / other
/** @see Files.createFile */
fun Path.createFile(vararg attrs: FileAttribute<*>): Path = Files.createFile(this, *attrs)
/** @see Files.createDirectory */
fun Path.createDirectory(vararg attrs: FileAttribute<*>): Path = Files.createDirectory(this, *attrs)
/** @see Files.createDirectories */
fun Path.createDirectories(vararg attrs: FileAttribute<*>): Path = Files.createDirectories(this, *attrs)
/** @see Files.exists */
fun Path.exists(vararg options: LinkOption): Boolean = Files.exists(this, *options)
/** Copy the file into the target directory using [Files.copy]. */
fun Path.copyToDirectory(targetDir: Path, vararg options: CopyOption): Path {
require(targetDir.isDirectory()) { "$targetDir is not a directory" }
val targetFile = targetDir.resolve(fileName)
Files.copy(this, targetFile, *options)
return targetFile
}
/** @see Files.copy */
fun Path.copyTo(target: Path, vararg options: CopyOption): Path = Files.copy(this, target, *options)
/** @see Files.move */
fun Path.moveTo(target: Path, vararg options: CopyOption): Path = Files.move(this, target, *options)
/** See overload of [Files.copy] which takes in an [InputStream]. */
fun Path.copyTo(out: OutputStream): Long = Files.copy(this, out)
/** @see Files.isRegularFile */
fun Path.isRegularFile(vararg options: LinkOption): Boolean = Files.isRegularFile(this, *options)
/** @see Files.isReadable */
inline val Path.isReadable: Boolean get() = Files.isReadable(this)
/** @see Files.size */
inline val Path.size: Long get() = Files.size(this)
/** @see Files.getLastModifiedTime */
fun Path.lastModifiedTime(vararg options: LinkOption): FileTime = Files.getLastModifiedTime(this, *options)
/** @see Files.isDirectory */
fun Path.isDirectory(vararg options: LinkOption): Boolean = Files.isDirectory(this, *options)
/**
* Same as [Files.list] except it also closes the [Stream].
* @return the output of [block]
*/
inline fun <R> Path.list(block: (Stream<Path>) -> R): R = Files.list(this).use(block)
/** Same as [list] but materialises all the entiries into a list. */
fun Path.list(): List<Path> = list { it.toList() }
/** @see Files.walk */
inline fun <R> Path.walk(maxDepth: Int = Int.MAX_VALUE, vararg options: FileVisitOption, block: (Stream<Path>) -> R): R {
return Files.walk(this, maxDepth, *options).use(block)
}
/** @see Files.delete */
fun Path.delete(): Unit = Files.delete(this)
/** @see Files.deleteIfExists */
fun Path.deleteIfExists(): Boolean = Files.deleteIfExists(this)
/** Deletes this path (if it exists) and if it's a directory, all its child paths recursively. */
fun Path.deleteRecursively() {
if (!exists()) return
Files.walkFileTree(this, object : SimpleFileVisitor<Path>() {
override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
file.delete()
return FileVisitResult.CONTINUE
}
override fun postVisitDirectory(dir: Path, exception: IOException?): FileVisitResult {
dir.delete()
return FileVisitResult.CONTINUE
}
})
}
/** @see Files.newOutputStream */
fun Path.outputStream(vararg options: OpenOption): OutputStream = Files.newOutputStream(this, *options)
/** @see Files.newInputStream */
fun Path.inputStream(vararg options: OpenOption): InputStream = Files.newInputStream(this, *options)
/** @see Files.newBufferedReader */
fun Path.reader(charset: Charset = UTF_8): BufferedReader = Files.newBufferedReader(this, charset)
/** @see Files.newBufferedWriter */
fun Path.writer(charset: Charset = UTF_8, vararg options: OpenOption): BufferedWriter {
return Files.newBufferedWriter(this, charset, *options)
}
/** @see Files.readAllBytes */
fun Path.readAll(): ByteArray = Files.readAllBytes(this)
/** Read in this entire file as a string using the given encoding. */
fun Path.readText(charset: Charset = UTF_8): String = reader(charset).use(Reader::readText)
/** @see Files.write */
fun Path.write(bytes: ByteArray, vararg options: OpenOption): Path = Files.write(this, bytes, *options)
/** Write the given string to this file. */
fun Path.writeText(text: String, charset: Charset = UTF_8, vararg options: OpenOption) {
writer(charset, *options).use { it.write(text) }
}
/**
* Same as [inputStream] except it also closes the [InputStream].
* @return the output of [block]
*/
inline fun <R> Path.read(vararg options: OpenOption, block: (InputStream) -> R): R = inputStream(*options).use(block)
/**
* Same as [outputStream] except it also closes the [OutputStream].
* @param createDirs if true then the parent directory of this file is created. Defaults to false.
* @return the output of [block]
*/
inline fun Path.write(createDirs: Boolean = false, vararg options: OpenOption = emptyArray(), block: (OutputStream) -> Unit) {
if (createDirs) {
normalize().parent?.createDirectories()
}
outputStream(*options).use(block)
}
/**
* Same as [Files.lines] except it also closes the [Stream]
* @return the output of [block]
*/
inline fun <R> Path.readLines(charset: Charset = UTF_8, block: (Stream<String>) -> R): R {
return Files.lines(this, charset).use(block)
}
/** @see Files.readAllLines */
fun Path.readAllLines(charset: Charset = UTF_8): List<String> = Files.readAllLines(this, charset)
fun Path.writeLines(lines: Iterable<CharSequence>, charset: Charset = UTF_8, vararg options: OpenOption): Path {
return Files.write(this, lines, charset, *options)
}
/**
* Read in this file as an AMQP serialised blob of type [T].
* @see [deserialize]
*/
inline fun <reified T : Any> Path.readObject(): T = readAll().deserialize()
/** Calculate the hash of the contents of this file. */
inline val Path.hash: SecureHash get() = read { it.hash() }

View File

@ -12,11 +12,11 @@ package net.corda.core.internal.cordapp
import net.corda.core.cordapp.Cordapp import net.corda.core.cordapp.Cordapp
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.internal.toPath
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationCustomSerializer
import net.corda.core.serialization.SerializationWhitelist import net.corda.core.serialization.SerializationWhitelist
import net.corda.core.serialization.SerializeAsToken import net.corda.core.serialization.SerializeAsToken
import java.io.File
import java.net.URL import java.net.URL
data class CordappImpl( data class CordappImpl(
@ -30,7 +30,7 @@ data class CordappImpl(
override val serializationCustomSerializers: List<SerializationCustomSerializer<*, *>>, override val serializationCustomSerializers: List<SerializationCustomSerializer<*, *>>,
override val customSchemas: Set<MappedSchema>, override val customSchemas: Set<MappedSchema>,
override val jarPath: URL) : Cordapp { override val jarPath: URL) : Cordapp {
override val name: String = File(jarPath.toURI()).name.removeSuffix(".jar") override val name: String = jarPath.toPath().fileName.toString().removeSuffix(".jar")
/** /**
* An exhaustive list of all classes relevant to the node within this CorDapp * An exhaustive list of all classes relevant to the node within this CorDapp

View File

@ -12,13 +12,16 @@ package net.corda.core.internal
import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME import net.corda.testing.core.BOB_NAME
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.After import org.junit.After
import org.junit.AfterClass import org.junit.AfterClass
import org.junit.BeforeClass import org.junit.BeforeClass
import org.junit.Test import org.junit.Test
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import kotlin.streams.toList
import kotlin.test.assertEquals import kotlin.test.assertEquals
class AbstractAttachmentTest { class AbstractAttachmentTest {
@ -46,23 +49,23 @@ class AbstractAttachmentTest {
(dir / "_signable3").writeLines(listOf("signable3")) (dir / "_signable3").writeLines(listOf("signable3"))
} }
private fun load(name: String) = object : AbstractAttachment({ (dir / name).readAll() }) { private fun load(name: String) = object : AbstractAttachment((dir / name)::readAll) {
override val id get() = throw UnsupportedOperationException() override val id get() = throw UnsupportedOperationException()
} }
@AfterClass @AfterClass
@JvmStatic @JvmStatic
fun afterClass() { fun afterClass() {
dir.toFile().deleteRecursively() dir.deleteRecursively()
} }
} }
@After @After
fun tearDown() { fun tearDown() {
dir.toFile().listFiles().forEach { dir.list {
if (!it.name.startsWith("_")) it.deleteRecursively() it.filter { !it.fileName.toString().startsWith("_") }.forEach(Path::deleteRecursively)
} }
assertEquals(5, dir.toFile().listFiles().size) assertThat(dir.list()).hasSize(5)
} }
@Test @Test

View File

@ -0,0 +1,62 @@
package net.corda.core.internal
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
class PathUtilsTest {
@Rule
@JvmField
val tempFolder = TemporaryFolder()
@Test
fun `deleteRecursively - non-existent path`() {
val path = tempFolder.root.toPath() / "non-existent"
path.deleteRecursively()
assertThat(path).doesNotExist()
}
@Test
fun `deleteRecursively - file`() {
val file = (tempFolder.root.toPath() / "file").createFile()
file.deleteRecursively()
assertThat(file).doesNotExist()
}
@Test
fun `deleteRecursively - empty folder`() {
val emptyDir = (tempFolder.root.toPath() / "empty").createDirectories()
emptyDir.deleteRecursively()
assertThat(emptyDir).doesNotExist()
}
@Test
fun `deleteRecursively - dir with single file`() {
val dir = (tempFolder.root.toPath() / "dir").createDirectories()
(dir / "file").createFile()
dir.deleteRecursively()
assertThat(dir).doesNotExist()
}
@Test
fun `deleteRecursively - nested single file`() {
val dir = (tempFolder.root.toPath() / "dir").createDirectories()
val dir2 = (dir / "dir2").createDirectories()
(dir2 / "file").createFile()
dir.deleteRecursively()
assertThat(dir).doesNotExist()
}
@Test
fun `deleteRecursively - complex`() {
val dir = (tempFolder.root.toPath() / "dir").createDirectories()
(dir / "file1").createFile()
val dir2 = (dir / "dir2").createDirectories()
(dir2 / "file2").createFile()
(dir2 / "file3").createFile()
(dir2 / "dir3").createDirectories()
dir.deleteRecursively()
assertThat(dir).doesNotExist()
}
}

View File

@ -10,8 +10,8 @@
package net.corda.docs package net.corda.docs
import net.corda.core.internal.toPath
import net.corda.node.services.config.ConfigHelper import net.corda.node.services.config.ConfigHelper
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.parseAsNodeConfiguration import net.corda.node.services.config.parseAsNodeConfiguration
import org.junit.Test import org.junit.Test
import java.nio.file.Path import java.nio.file.Path
@ -25,7 +25,7 @@ class ExampleConfigTest {
configFilenames.forEach { configFilenames.forEach {
println("Checking $it") println("Checking $it")
val configFileResource = ExampleConfigTest::class.java.classLoader.getResource(it) val configFileResource = ExampleConfigTest::class.java.classLoader.getResource(it)
val config = loadConfig(Paths.get(configFileResource.toURI())) val config = loadConfig(configFileResource.toPath())
// Force the config fields as they are resolved lazily // Force the config fields as they are resolved lazily
config.javaClass.kotlin.declaredMemberProperties.forEach { member -> config.javaClass.kotlin.declaredMemberProperties.forEach { member ->
if (member.visibility == KVisibility.PUBLIC) { if (member.visibility == KVisibility.PUBLIC) {
@ -37,7 +37,7 @@ class ExampleConfigTest {
@Test @Test
fun `example node_confs parses fine`() { fun `example node_confs parses fine`() {
readAndCheckConfigurations<NodeConfiguration>( readAndCheckConfigurations(
"example-node.conf", "example-node.conf",
"example-out-of-process-verifier-node.conf" "example-out-of-process-verifier-node.conf"
) { ) {

View File

@ -13,6 +13,8 @@ package net.corda.behave
import java.time.Duration import java.time.Duration
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
// TODO Most of these are available in corda core
val Int.millisecond: Duration val Int.millisecond: Duration
get() = Duration.ofMillis(this.toLong()) get() = Duration.ofMillis(this.toLong())

View File

@ -10,15 +10,12 @@
package net.corda.behave.file package net.corda.behave.file
import java.io.File import java.nio.file.Path
import java.nio.file.Paths
val currentDirectory: File val currentDirectory: Path
get() = File(System.getProperty("user.dir")) get() = Paths.get(System.getProperty("user.dir"))
// location of Corda distributions and Drivers dependencies // location of Corda distributions and Drivers dependencies
val stagingRoot: File val stagingRoot: Path
get() = if (System.getProperty("STAGING_ROOT") != null) get() = System.getProperty("STAGING_ROOT")?.let { Paths.get(it) } ?: currentDirectory
File(System.getProperty("STAGING_ROOT"))
else currentDirectory
operator fun File.div(relative: String): File = this.resolve(relative)

View File

@ -10,10 +10,13 @@
package net.corda.behave.file package net.corda.behave.file
import java.io.File import net.corda.core.internal.list
import net.corda.core.internal.readText
import java.nio.file.Path
import kotlin.streams.toList
class LogSource( class LogSource(
private val directory: File, private val directory: Path,
filePattern: String? = ".*\\.log", filePattern: String? = ".*\\.log",
private val filePatternUsedForExclusion: Boolean = false private val filePatternUsedForExclusion: Boolean = false
) { ) {
@ -21,7 +24,7 @@ class LogSource(
private val fileRegex = Regex(filePattern ?: ".*") private val fileRegex = Regex(filePattern ?: ".*")
data class MatchedLogContent( data class MatchedLogContent(
val filename: File, val filename: Path,
val contents: String val contents: String
) )
@ -31,10 +34,12 @@ class LogSource(
} else { } else {
null null
} }
val logFiles = directory.listFiles({ file -> val logFiles = directory.list {
(!filePatternUsedForExclusion && file.name.matches(fileRegex)) || it.filter {
(filePatternUsedForExclusion && !file.name.matches(fileRegex)) (!filePatternUsedForExclusion && it.fileName.toString().matches(fileRegex)) ||
}) (filePatternUsedForExclusion && !it.fileName.toString().matches(fileRegex))
}.toList()
}
val result = mutableListOf<MatchedLogContent>() val result = mutableListOf<MatchedLogContent>()
for (file in logFiles) { for (file in logFiles) {
val contents = file.readText() val contents = file.readText()

View File

@ -13,5 +13,7 @@ package net.corda.behave.logging
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
// TODO Already available in corda core
inline fun <reified T> getLogger(): Logger = inline fun <reified T> getLogger(): Logger =
LoggerFactory.getLogger(T::class.java) LoggerFactory.getLogger(T::class.java)

View File

@ -13,7 +13,6 @@ package net.corda.behave.network
import net.corda.behave.database.DatabaseType import net.corda.behave.database.DatabaseType
import net.corda.behave.file.LogSource import net.corda.behave.file.LogSource
import net.corda.behave.file.currentDirectory import net.corda.behave.file.currentDirectory
import net.corda.behave.file.div
import net.corda.behave.file.stagingRoot import net.corda.behave.file.stagingRoot
import net.corda.behave.logging.getLogger import net.corda.behave.logging.getLogger
import net.corda.behave.minutes import net.corda.behave.minutes
@ -22,19 +21,20 @@ import net.corda.behave.node.Node
import net.corda.behave.node.configuration.NotaryType import net.corda.behave.node.configuration.NotaryType
import net.corda.behave.process.JarCommand import net.corda.behave.process.JarCommand
import net.corda.core.CordaException import net.corda.core.CordaException
import net.corda.core.internal.*
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
import java.io.Closeable import java.io.Closeable
import java.io.File import java.nio.file.Path
import java.time.Duration import java.time.Duration
import java.time.Instant import java.time.Instant
import java.time.ZoneId import java.time.ZoneOffset.UTC
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class Network private constructor( class Network private constructor(
private val nodes: Map<String, Node>, private val nodes: Map<String, Node>,
private val targetDirectory: File, private val targetDirectory: Path,
private val timeout: Duration = 2.minutes private val timeout: Duration = 2.minutes
) : Closeable, Iterable<Node> { ) : Closeable, Iterable<Node> {
@ -47,7 +47,7 @@ class Network private constructor(
private var hasError = false private var hasError = false
init { init {
FileUtils.forceMkdir(targetDirectory) targetDirectory.createDirectories()
} }
class Builder internal constructor( class Builder internal constructor(
@ -58,10 +58,10 @@ class Network private constructor(
private val startTime = DateTimeFormatter private val startTime = DateTimeFormatter
.ofPattern("yyyyMMdd-HHmmss") .ofPattern("yyyyMMdd-HHmmss")
.withZone(ZoneId.of("UTC")) .withZone(UTC)
.format(Instant.now()) .format(Instant.now())
private val directory = currentDirectory / "build/runs/$startTime" private val directory = currentDirectory / "build" / "runs" / startTime
fun addNode( fun addNode(
name: String, name: String,
@ -102,12 +102,11 @@ class Network private constructor(
} }
fun copyDatabaseDrivers() { fun copyDatabaseDrivers() {
val driverDirectory = targetDirectory / "libs" val driverDirectory = (targetDirectory / "libs").createDirectories()
log.info("Copying database drivers from $stagingRoot/deps/drivers to $driverDirectory") log.info("Copying database drivers from $stagingRoot/deps/drivers to $driverDirectory")
FileUtils.forceMkdir(driverDirectory)
FileUtils.copyDirectory( FileUtils.copyDirectory(
stagingRoot / "deps/drivers", (stagingRoot / "deps" / "drivers").toFile(),
driverDirectory driverDirectory.toFile()
) )
} }
@ -160,7 +159,7 @@ class Network private constructor(
error("Failed to bootstrap network") { error("Failed to bootstrap network") {
val matches = LogSource(targetDirectory) val matches = LogSource(targetDirectory)
.find(".*[Ee]xception.*") .find(".*[Ee]xception.*")
.groupBy { it.filename.absolutePath } .groupBy { it.filename.toAbsolutePath() }
for (match in matches) { for (match in matches) {
log.info("Log(${match.key}):\n${match.value.joinToString("\n") { it.contents }}") log.info("Log(${match.key}):\n${match.value.joinToString("\n") { it.contents }}")
} }
@ -174,30 +173,17 @@ class Network private constructor(
try { try {
if (!hasError || CLEANUP_ON_ERROR) { if (!hasError || CLEANUP_ON_ERROR) {
log.info("Cleaning up runtime ...") log.info("Cleaning up runtime ...")
FileUtils.deleteDirectory(targetDirectory) targetDirectory.deleteRecursively()
} else { } else {
log.info("Deleting temporary files, but retaining logs and config ...") log.info("Deleting temporary files, but retaining logs and config ...")
for (node in nodes.values.map { it.config.name }) { for (node in nodes.values) {
val nodeFolder = targetDirectory / node val nodeDir = targetDirectory / node.config.name
FileUtils.deleteDirectory(nodeFolder / "additional-node-infos") nodeDir.list { paths -> paths
FileUtils.deleteDirectory(nodeFolder / "artemis") .filter { it.fileName.toString() !in setOf("logs", "node.conf") }
FileUtils.deleteDirectory(nodeFolder / "certificates") .forEach(Path::deleteRecursively)
FileUtils.deleteDirectory(nodeFolder / "cordapps")
FileUtils.deleteDirectory(nodeFolder / "shell-commands")
FileUtils.deleteDirectory(nodeFolder / "sshkey")
FileUtils.deleteQuietly(nodeFolder / "corda.jar")
FileUtils.deleteQuietly(nodeFolder / "network-parameters")
FileUtils.deleteQuietly(nodeFolder / "persistence.mv.db")
FileUtils.deleteQuietly(nodeFolder / "process-id")
for (nodeInfo in nodeFolder.listFiles({
file -> file.name.matches(Regex("nodeInfo-.*"))
})) {
FileUtils.deleteQuietly(nodeInfo)
} }
} }
FileUtils.deleteDirectory(targetDirectory / "libs") listOf("libs", ".cache").forEach { (targetDirectory / it).deleteRecursively() }
FileUtils.deleteDirectory(targetDirectory / ".cache")
} }
log.info("Network was shut down successfully") log.info("Network was shut down successfully")
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -10,13 +10,15 @@
package net.corda.behave.node package net.corda.behave.node
import net.corda.behave.file.div
import net.corda.behave.file.stagingRoot import net.corda.behave.file.stagingRoot
import net.corda.behave.logging.getLogger import net.corda.behave.logging.getLogger
import net.corda.behave.service.Service import net.corda.behave.service.Service
import org.apache.commons.io.FileUtils import net.corda.core.internal.copyTo
import java.io.File import net.corda.core.internal.createDirectories
import net.corda.core.internal.div
import net.corda.core.internal.exists
import java.net.URL import java.net.URL
import java.nio.file.Path
/** /**
* Corda distribution. * Corda distribution.
@ -31,7 +33,7 @@ class Distribution private constructor(
/** /**
* The path of the distribution fat JAR on disk, if available. * The path of the distribution fat JAR on disk, if available.
*/ */
file: File? = null, file: Path? = null,
/** /**
* The URL of the distribution fat JAR, if available. * The URL of the distribution fat JAR, if available.
@ -47,43 +49,39 @@ class Distribution private constructor(
/** /**
* The path to the distribution fat JAR. * The path to the distribution fat JAR.
*/ */
val path: File = file ?: nodePrefix / "$version" val path: Path = file ?: nodePrefix / version
/** /**
* The path to the distribution fat JAR. * The path to the distribution fat JAR.
*/ */
val cordaJar: File = path / "corda.jar" val cordaJar: Path = path / "corda.jar"
/** /**
* The path to available Cordapps for this distribution. * The path to available Cordapps for this distribution.
*/ */
val cordappDirectory: File = path / "apps" val cordappDirectory: Path = path / "apps"
/** /**
* The path to network bootstrapping tool. * The path to network bootstrapping tool.
*/ */
val networkBootstrapper: File = path / "network-bootstrapper.jar" val networkBootstrapper: Path = path / "network-bootstrapper.jar"
/** /**
* Ensure that the distribution is available on disk. * Ensure that the distribution is available on disk.
*/ */
fun ensureAvailable() { fun ensureAvailable() {
if (!cordaJar.exists()) { if (cordaJar.exists()) return
if (url != null) { val url = checkNotNull(url) { "File not found $cordaJar" }
try { try {
FileUtils.forceMkdirParent(cordaJar) cordaJar.parent.createDirectories()
FileUtils.copyURLToFile(url, cordaJar) url.openStream().use { it.copyTo(cordaJar) }
} catch (e: Exception) { } catch (e: Exception) {
if (e.message!!.contains("HTTP response code: 401")) { if ("HTTP response code: 401" in e.message!!) {
log.warn("CORDA_ARTIFACTORY_USERNAME ${System.getenv("CORDA_ARTIFACTORY_USERNAME")}") log.warn("CORDA_ARTIFACTORY_USERNAME ${System.getenv("CORDA_ARTIFACTORY_USERNAME")}")
log.warn("CORDA_ARTIFACTORY_PASSWORD ${System.getenv("CORDA_ARTIFACTORY_PASSWORD")}") log.warn("CORDA_ARTIFACTORY_PASSWORD ${System.getenv("CORDA_ARTIFACTORY_PASSWORD")}")
throw Exception("Incorrect Artifactory permission. Please set CORDA_ARTIFACTORY_USERNAME and CORDA_ARTIFACTORY_PASSWORD environment variables correctly.") throw Exception("Incorrect Artifactory permission. Please set CORDA_ARTIFACTORY_USERNAME and CORDA_ARTIFACTORY_PASSWORD environment variables correctly.")
}
else throw Exception("Invalid Corda version $version", e)
}
} else {
throw Exception("File not found $cordaJar")
} }
throw e
} }
} }
@ -119,7 +117,7 @@ class Distribution private constructor(
* @param version The version of the Corda distribution. * @param version The version of the Corda distribution.
* @param jarFile The path to the Corda fat JAR. * @param jarFile The path to the Corda fat JAR.
*/ */
fun fromJarFile(version: String, jarFile: File? = null): Distribution { fun fromJarFile(version: String, jarFile: Path? = null): Distribution {
val distribution = Distribution(version, file = jarFile) val distribution = Distribution(version, file = jarFile)
distributions.add(distribution) distributions.add(distribution)
return distribution return distribution

View File

@ -14,7 +14,6 @@ import net.corda.behave.database.DatabaseConnection
import net.corda.behave.database.DatabaseType import net.corda.behave.database.DatabaseType
import net.corda.behave.file.LogSource import net.corda.behave.file.LogSource
import net.corda.behave.file.currentDirectory import net.corda.behave.file.currentDirectory
import net.corda.behave.file.div
import net.corda.behave.file.stagingRoot import net.corda.behave.file.stagingRoot
import net.corda.behave.logging.getLogger import net.corda.behave.logging.getLogger
import net.corda.behave.monitoring.PatternWatch import net.corda.behave.monitoring.PatternWatch
@ -27,11 +26,13 @@ import net.corda.behave.ssh.MonitoringSSHClient
import net.corda.behave.ssh.SSHClient import net.corda.behave.ssh.SSHClient
import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCClient
import net.corda.client.rpc.CordaRPCClientConfiguration import net.corda.client.rpc.CordaRPCClientConfiguration
import net.corda.core.internal.div
import net.corda.core.internal.exists
import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.CordaRPCOps
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
import java.io.File
import java.net.InetAddress import java.net.InetAddress
import java.nio.file.Path
import java.time.Duration import java.time.Duration
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
@ -40,7 +41,7 @@ import java.util.concurrent.CountDownLatch
*/ */
class Node( class Node(
val config: Configuration, val config: Configuration,
private val rootDirectory: File = currentDirectory, private val rootDirectory: Path = currentDirectory,
private val settings: ServiceSettings = ServiceSettings() private val settings: ServiceSettings = ServiceSettings()
) { ) {
@ -229,10 +230,10 @@ class Node(
private fun installApps() { private fun installApps() {
val version = config.distribution.version val version = config.distribution.version
val appDirectory = stagingRoot / "deps/corda/$version/apps" val appDirectory = stagingRoot / "deps" / "corda" / version / "apps"
if (appDirectory.exists()) { if (appDirectory.exists()) {
val targetAppDirectory = runtimeDirectory / "cordapps" val targetAppDirectory = runtimeDirectory / "cordapps"
FileUtils.copyDirectory(appDirectory, targetAppDirectory) FileUtils.copyDirectory(appDirectory.toFile(), targetAppDirectory.toFile())
} }
} }
@ -257,7 +258,7 @@ class Node(
private var includeFinance = false private var includeFinance = false
private var directory: File? = null private var directory: Path? = null
private var timeout = Duration.ofSeconds(60) private var timeout = Duration.ofSeconds(60)
@ -307,7 +308,7 @@ class Node(
return this return this
} }
fun withDirectory(newDirectory: File): Builder { fun withDirectory(newDirectory: Path): Builder {
directory = newDirectory directory = newDirectory
return this return this
} }

View File

@ -12,10 +12,10 @@ package net.corda.behave.node.configuration
import net.corda.behave.database.DatabaseType import net.corda.behave.database.DatabaseType
import net.corda.behave.logging.getLogger import net.corda.behave.logging.getLogger
import net.corda.behave.node.* import net.corda.behave.node.Distribution
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import org.apache.commons.io.FileUtils import net.corda.core.internal.writeText
import java.io.File import java.nio.file.Path
class Configuration( class Configuration(
val name: String, val name: String,
@ -53,8 +53,8 @@ class Configuration(
private val extraConfig = (configElements.toList() + listOf(users, nodeInterface)) private val extraConfig = (configElements.toList() + listOf(users, nodeInterface))
.joinToString(separator = "\n") { it.generate(this) } .joinToString(separator = "\n") { it.generate(this) }
fun writeToFile(file: File) { fun writeToFile(file: Path) {
FileUtils.writeStringToFile(file, this.generate(), "UTF-8") file.writeText(this.generate())
log.info(this.generate()) log.info(this.generate())
} }
@ -64,7 +64,7 @@ class Configuration(
companion object { companion object {
private val log = getLogger<Configuration>() private val log = getLogger<Configuration>()
val DEFAULT_PASSWORD = "S0meS3cretW0rd" const val DEFAULT_PASSWORD = "S0meS3cretW0rd"
} }
} }

View File

@ -17,14 +17,14 @@ import net.corda.behave.process.output.OutputListener
import rx.Observable import rx.Observable
import rx.Subscriber import rx.Subscriber
import java.io.Closeable import java.io.Closeable
import java.io.File
import java.io.IOException import java.io.IOException
import java.nio.file.Path
import java.time.Duration import java.time.Duration
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
open class Command( open class Command(
private val command: List<String>, private val command: List<String>,
private val directory: File = currentDirectory, private val directory: Path = currentDirectory,
private val timeout: Duration = 2.minutes private val timeout: Duration = 2.minutes
): Closeable { ): Closeable {
@ -59,7 +59,7 @@ open class Command(
try { try {
log.info("Command: $command") log.info("Command: $command")
val processBuilder = ProcessBuilder(command) val processBuilder = ProcessBuilder(command)
.directory(directory) .directory(directory.toFile())
.redirectErrorStream(true) .redirectErrorStream(true)
processBuilder.environment().putAll(System.getenv()) processBuilder.environment().putAll(System.getenv())
process = processBuilder.start() process = processBuilder.start()

View File

@ -11,12 +11,13 @@
package net.corda.behave.process package net.corda.behave.process
import java.io.File import java.io.File
import java.nio.file.Path
import java.time.Duration import java.time.Duration
class JarCommand( class JarCommand(
val jarFile: File, jarFile: Path,
arguments: Array<String>, arguments: Array<String>,
directory: File, directory: Path,
timeout: Duration, timeout: Duration,
enableRemoteDebugging: Boolean = false enableRemoteDebugging: Boolean = false
) : Command( ) : Command(

View File

@ -10,11 +10,10 @@
package net.corda.behave.scenarios.helpers package net.corda.behave.scenarios.helpers
import net.corda.behave.file.div
import net.corda.behave.minutes import net.corda.behave.minutes
import net.corda.behave.process.JarCommand import net.corda.behave.process.JarCommand
import net.corda.behave.scenarios.ScenarioState import net.corda.behave.scenarios.ScenarioState
import java.io.File import net.corda.core.internal.div
class Startup(state: ScenarioState) : Substeps(state) { class Startup(state: ScenarioState) : Substeps(state) {
@ -113,7 +112,7 @@ class Startup(state: ScenarioState) : Substeps(state) {
// assumption is there is a Main() method declared in the manifest of the JAR // assumption is there is a Main() method declared in the manifest of the JAR
// eg. Main-Class: net.corda.notaryhealthcheck.MainKt // eg. Main-Class: net.corda.notaryhealthcheck.MainKt
val cordappDirectory = node(nodeName).config.distribution.cordappDirectory val cordappDirectory = node(nodeName).config.distribution.cordappDirectory
val cordappJar : File = cordappDirectory / "$cordapp.jar" val cordappJar = cordappDirectory / "$cordapp.jar"
// Execute // Execute
val command = JarCommand(cordappJar, args as Array<String>, cordappDirectory, 1.minutes) val command = JarCommand(cordappJar, args as Array<String>, cordappDirectory, 1.minutes)
command.start() command.start()

View File

@ -36,7 +36,6 @@ import net.corda.nodeapi.internal.serialization.SerializationFactoryImpl
import net.corda.nodeapi.internal.serialization.amqp.AMQPServerSerializationScheme import net.corda.nodeapi.internal.serialization.amqp.AMQPServerSerializationScheme
import net.corda.nodeapi.internal.serialization.kryo.AbstractKryoSerializationScheme import net.corda.nodeapi.internal.serialization.kryo.AbstractKryoSerializationScheme
import net.corda.nodeapi.internal.serialization.kryo.kryoMagic import net.corda.nodeapi.internal.serialization.kryo.kryoMagic
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import java.nio.file.StandardCopyOption.REPLACE_EXISTING import java.nio.file.StandardCopyOption.REPLACE_EXISTING
@ -115,13 +114,13 @@ class NetworkBootstrapper {
val cordappsDir = (nodeDir / "cordapps").createDirectories() val cordappsDir = (nodeDir / "cordapps").createDirectories()
cordappJars.forEach { it.copyToDirectory(cordappsDir) } cordappJars.forEach { it.copyToDirectory(cordappsDir) }
} }
Files.delete(cordaJar) cordaJar.delete()
} }
private fun extractCordaJarTo(directory: Path): Path { private fun extractCordaJarTo(directory: Path): Path {
val cordaJarPath = directory / "corda.jar" val cordaJarPath = directory / "corda.jar"
if (!cordaJarPath.exists()) { if (!cordaJarPath.exists()) {
Thread.currentThread().contextClassLoader.getResourceAsStream("corda.jar").copyTo(cordaJarPath) Thread.currentThread().contextClassLoader.getResourceAsStream("corda.jar").use { it.copyTo(cordaJarPath) }
} }
return cordaJarPath return cordaJarPath
} }

View File

@ -11,10 +11,7 @@
package net.corda.nodeapi.internal.network package net.corda.nodeapi.internal.network
import net.corda.cordform.CordformNode import net.corda.cordform.CordformNode
import net.corda.core.internal.ThreadBox import net.corda.core.internal.*
import net.corda.core.internal.createDirectories
import net.corda.core.internal.isRegularFile
import net.corda.core.internal.list
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import rx.Observable import rx.Observable
import rx.Scheduler import rx.Scheduler
@ -25,7 +22,6 @@ import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.StandardCopyOption.COPY_ATTRIBUTES import java.nio.file.StandardCopyOption.COPY_ATTRIBUTES
import java.nio.file.StandardCopyOption.REPLACE_EXISTING import java.nio.file.StandardCopyOption.REPLACE_EXISTING
import java.nio.file.attribute.BasicFileAttributes
import java.nio.file.attribute.FileTime import java.nio.file.attribute.FileTime
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -110,10 +106,10 @@ class NodeInfoFilesCopier(scheduler: Scheduler = Schedulers.io()) : AutoCloseabl
private fun poll() { private fun poll() {
nodeDataMapBox.locked { nodeDataMapBox.locked {
for (nodeData in values) { for (nodeData in values) {
nodeData.nodeDir.list { paths -> nodeData.nodeDir.list { paths -> paths
paths.filter { it.isRegularFile() } .filter { it.isRegularFile() }
.filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) } .filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) }
.forEach { path -> processPath(nodeData, path) } .forEach { processPath(nodeData, it) }
} }
} }
} }
@ -123,7 +119,7 @@ class NodeInfoFilesCopier(scheduler: Scheduler = Schedulers.io()) : AutoCloseabl
// be copied. // be copied.
private fun processPath(nodeData: NodeData, path: Path) { private fun processPath(nodeData: NodeData, path: Path) {
nodeDataMapBox.alreadyLocked { nodeDataMapBox.alreadyLocked {
val newTimestamp = Files.readAttributes(path, BasicFileAttributes::class.java).lastModifiedTime() val newTimestamp = path.lastModifiedTime()
val previousTimestamp = nodeData.previouslySeenFiles.put(path, newTimestamp) ?: FileTime.fromMillis(-1) val previousTimestamp = nodeData.previouslySeenFiles.put(path, newTimestamp) ?: FileTime.fromMillis(-1)
if (newTimestamp > previousTimestamp) { if (newTimestamp > previousTimestamp) {
for (destination in this.values.filter { it.nodeDir != nodeData.nodeDir }.map { it.additionalNodeInfoDirectory }) { for (destination in this.values.filter { it.nodeDir != nodeData.nodeDir }.map { it.additionalNodeInfoDirectory }) {
@ -143,18 +139,18 @@ class NodeInfoFilesCopier(scheduler: Scheduler = Schedulers.io()) : AutoCloseabl
} }
try { try {
// First copy the file to a temporary file within the appropriate directory. // First copy the file to a temporary file within the appropriate directory.
Files.copy(source, tempDestination, COPY_ATTRIBUTES, REPLACE_EXISTING) source.copyTo(tempDestination, COPY_ATTRIBUTES, REPLACE_EXISTING)
} catch (exception: IOException) { } catch (exception: IOException) {
log.warn("Couldn't copy $source to $tempDestination.", exception) log.warn("Couldn't copy $source to $tempDestination.", exception)
Files.delete(tempDestination) tempDestination.delete()
throw exception throw exception
} }
try { try {
// Then rename it to the desired name. This way the file 'appears' on the filesystem as an atomic operation. // Then rename it to the desired name. This way the file 'appears' on the filesystem as an atomic operation.
Files.move(tempDestination, destination, REPLACE_EXISTING) tempDestination.moveTo(destination, REPLACE_EXISTING)
} catch (exception: IOException) { } catch (exception: IOException) {
log.warn("Couldn't move $tempDestination to $destination.", exception) log.warn("Couldn't move $tempDestination to $destination.", exception)
Files.delete(tempDestination) tempDestination.delete()
throw exception throw exception
} }
} }

View File

@ -16,6 +16,7 @@ import com.esotericsoftware.kryo.io.Output
import com.esotericsoftware.kryo.serializers.FieldSerializer import com.esotericsoftware.kryo.serializers.FieldSerializer
import com.esotericsoftware.kryo.util.DefaultClassResolver import com.esotericsoftware.kryo.util.DefaultClassResolver
import com.esotericsoftware.kryo.util.Util import com.esotericsoftware.kryo.util.Util
import net.corda.core.internal.writer
import net.corda.core.serialization.ClassWhitelist import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializationContext import net.corda.core.serialization.SerializationContext
@ -26,10 +27,9 @@ import net.corda.nodeapi.internal.serialization.kryo.ThrowableSerializer
import java.io.PrintWriter import java.io.PrintWriter
import java.lang.reflect.Modifier import java.lang.reflect.Modifier
import java.lang.reflect.Modifier.isAbstract import java.lang.reflect.Modifier.isAbstract
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets.UTF_8
import java.nio.file.Files
import java.nio.file.Paths import java.nio.file.Paths
import java.nio.file.StandardOpenOption import java.nio.file.StandardOpenOption.*
import java.util.* import java.util.*
/** /**
@ -216,7 +216,7 @@ class LoggingWhitelist(val delegate: ClassWhitelist, val global: Boolean = true)
val fileName = System.getenv("WHITELIST_FILE") val fileName = System.getenv("WHITELIST_FILE")
if (fileName != null && fileName.isNotEmpty()) { if (fileName != null && fileName.isNotEmpty()) {
try { try {
return PrintWriter(Files.newBufferedWriter(Paths.get(fileName), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND, StandardOpenOption.WRITE), true) return PrintWriter(Paths.get(fileName).writer(UTF_8, CREATE, APPEND, WRITE), true)
} catch (ioEx: Exception) { } catch (ioEx: Exception) {
log.error("Could not open/create whitelist journal file for append: $fileName", ioEx) log.error("Could not open/create whitelist journal file for append: $fileName", ioEx)
} }

View File

@ -11,18 +11,20 @@
package net.corda.nodeapi.internal.network package net.corda.nodeapi.internal.network
import net.corda.cordform.CordformNode import net.corda.cordform.CordformNode
import net.corda.core.internal.div
import net.corda.core.internal.list
import net.corda.core.internal.write
import net.corda.nodeapi.eventually import net.corda.nodeapi.eventually
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.TemporaryFolder import org.junit.rules.TemporaryFolder
import rx.schedulers.TestScheduler import rx.schedulers.TestScheduler
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.time.Duration import java.time.Duration
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.streams.toList import kotlin.streams.toList
import kotlin.test.assertEquals
class NodeInfoFilesCopierTest { class NodeInfoFilesCopierTest {
companion object { companion object {
@ -31,9 +33,9 @@ class NodeInfoFilesCopierTest {
private const val NODE_2_PATH = "node2" private const val NODE_2_PATH = "node2"
private val content = "blah".toByteArray(Charsets.UTF_8) private val content = "blah".toByteArray(Charsets.UTF_8)
private val GOOD_NODE_INFO_NAME = "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}test" private const val GOOD_NODE_INFO_NAME = "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}test"
private val GOOD_NODE_INFO_NAME_2 = "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}anotherNode" private const val GOOD_NODE_INFO_NAME_2 = "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}anotherNode"
private val BAD_NODE_INFO_NAME = "something" private const val BAD_NODE_INFO_NAME = "something"
} }
@Rule @Rule
@ -65,8 +67,8 @@ class NodeInfoFilesCopierTest {
advanceTime() advanceTime()
// Create 2 files, a nodeInfo and another file in node1 folder. // Create 2 files, a nodeInfo and another file in node1 folder.
Files.write(node1RootPath.resolve(GOOD_NODE_INFO_NAME), content) (node1RootPath / GOOD_NODE_INFO_NAME).write(content)
Files.write(node1RootPath.resolve(BAD_NODE_INFO_NAME), content) (node1RootPath / BAD_NODE_INFO_NAME).write(content)
// Configure the second node. // Configure the second node.
nodeInfoFilesCopier.addConfig(node2RootPath) nodeInfoFilesCopier.addConfig(node2RootPath)
@ -86,8 +88,8 @@ class NodeInfoFilesCopierTest {
advanceTime() advanceTime()
// Create 2 files, one of which to be copied, in a node root path. // Create 2 files, one of which to be copied, in a node root path.
Files.write(node2RootPath.resolve(GOOD_NODE_INFO_NAME), content) (node2RootPath / GOOD_NODE_INFO_NAME).write(content)
Files.write(node2RootPath.resolve(BAD_NODE_INFO_NAME), content) (node2RootPath / BAD_NODE_INFO_NAME).write(content)
advanceTime() advanceTime()
eventually<AssertionError, Unit>(Duration.ofMinutes(1)) { eventually<AssertionError, Unit>(Duration.ofMinutes(1)) {
@ -104,14 +106,14 @@ class NodeInfoFilesCopierTest {
advanceTime() advanceTime()
// Create a file, in node 2 root path. // Create a file, in node 2 root path.
Files.write(node2RootPath.resolve(GOOD_NODE_INFO_NAME), content) (node2RootPath / GOOD_NODE_INFO_NAME).write(content)
advanceTime() advanceTime()
// Remove node 2 // Remove node 2
nodeInfoFilesCopier.removeConfig(node2RootPath) nodeInfoFilesCopier.removeConfig(node2RootPath)
// Create another file in node 2 directory. // Create another file in node 2 directory.
Files.write(node2RootPath.resolve(GOOD_NODE_INFO_NAME_2), content) (node2RootPath / GOOD_NODE_INFO_NAME).write(content)
advanceTime() advanceTime()
eventually<AssertionError, Unit>(Duration.ofMinutes(1)) { eventually<AssertionError, Unit>(Duration.ofMinutes(1)) {
@ -130,11 +132,11 @@ class NodeInfoFilesCopierTest {
nodeInfoFilesCopier.reset() nodeInfoFilesCopier.reset()
advanceTime() advanceTime()
Files.write(node2RootPath.resolve(GOOD_NODE_INFO_NAME_2), content) (node2RootPath / GOOD_NODE_INFO_NAME_2).write(content)
// Give some time to the filesystem to report the change. // Give some time to the filesystem to report the change.
Thread.sleep(100) Thread.sleep(100)
assertEquals(0, Files.list(node1AdditionalNodeInfoPath).toList().size) assertThat(node1AdditionalNodeInfoPath.list()).isEmpty()
} }
private fun advanceTime() { private fun advanceTime() {
@ -142,8 +144,8 @@ class NodeInfoFilesCopierTest {
} }
private fun checkDirectoryContainsSingleFile(path: Path, filename: String) { private fun checkDirectoryContainsSingleFile(path: Path, filename: String) {
assertEquals(1, Files.list(path).toList().size) val files = path.list()
val onlyFileName = Files.list(path).toList().first().fileName.toString() assertThat(files).hasSize(1)
assertEquals(filename, onlyFileName) assertThat(files[0].fileName.toString()).isEqualTo(filename)
} }
} }

View File

@ -14,8 +14,8 @@ import net.corda.core.serialization.*
import net.corda.testing.common.internal.ProjectStructure.projectRootDir import net.corda.testing.common.internal.ProjectStructure.projectRootDir
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import org.junit.Test import org.junit.Test
import java.io.File
import java.io.NotSerializableException import java.io.NotSerializableException
import java.net.URI
import java.util.* import java.util.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -23,11 +23,11 @@ import kotlin.test.assertTrue
class EnumEvolvabilityTests { class EnumEvolvabilityTests {
@Suppress("UNUSED") @Suppress("UNUSED")
var localPath = projectRootDir.toUri().resolve( var localPath: URI = projectRootDir.toUri().resolve(
"node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp") "node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp")
companion object { companion object {
val VERBOSE = false const val VERBOSE = false
} }
enum class NotAnnotated { enum class NotAnnotated {
@ -442,8 +442,7 @@ class EnumEvolvabilityTests {
//File(URI("$localPath/$resource")).writeBytes( //File(URI("$localPath/$resource")).writeBytes(
// SerializationOutput(sf).serialize(WrapsUnknown(WithUnknownTest.D)).bytes) // SerializationOutput(sf).serialize(WrapsUnknown(WithUnknownTest.D)).bytes)
val path = EvolvabilityTests::class.java.getResource(resource) val sb1 = EvolvabilityTests::class.java.getResource(resource).readBytes()
val sb1 = File(path.toURI()).readBytes()
val envelope = DeserializationInput(sf).deserializeAndReturnEnvelope(SerializedBytes<WrapsUnknown>(sb1)).envelope val envelope = DeserializationInput(sf).deserializeAndReturnEnvelope(SerializedBytes<WrapsUnknown>(sb1)).envelope

View File

@ -10,25 +10,25 @@
package net.corda.nodeapi.internal.serialization.amqp package net.corda.nodeapi.internal.serialization.amqp
import net.corda.core.internal.packageName import net.corda.core.internal.toPath
import net.corda.core.serialization.CordaSerializationTransformEnumDefault import net.corda.core.serialization.CordaSerializationTransformEnumDefault
import net.corda.core.serialization.CordaSerializationTransformEnumDefaults import net.corda.core.serialization.CordaSerializationTransformEnumDefaults
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import net.corda.testing.common.internal.ProjectStructure.projectRootDir import net.corda.testing.common.internal.ProjectStructure.projectRootDir
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test import org.junit.Test
import java.io.File
import java.io.NotSerializableException import java.io.NotSerializableException
import java.net.URI
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertNotNull import kotlin.test.assertNotNull
import kotlin.test.assertTrue
// NOTE: To recreate the test files used by these tests uncomment the original test classes and comment // NOTE: To recreate the test files used by these tests uncomment the original test classes and comment
// the new ones out, then change each test to write out the serialized bytes rather than read // the new ones out, then change each test to write out the serialized bytes rather than read
// the file. // the file.
class EnumEvolveTests { class EnumEvolveTests {
@Suppress("UNUSED") @Suppress("UNUSED")
var localPath = projectRootDir.toUri().resolve( var localPath: URI = projectRootDir.toUri().resolve(
"node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp") "node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp")
// Version of the class as it was serialised // Version of the class as it was serialised
@ -50,9 +50,9 @@ class EnumEvolveTests {
// File(URI("$localPath/$resource")).writeBytes( // File(URI("$localPath/$resource")).writeBytes(
// SerializationOutput(sf).serialize(C(DeserializeNewerSetToUnknown.D)).bytes) // SerializationOutput(sf).serialize(C(DeserializeNewerSetToUnknown.D)).bytes)
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
val obj = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path.toURI()).readBytes())) val obj = DeserializationInput(sf).deserialize(SerializedBytes<C>(url.readBytes()))
assertEquals(DeserializeNewerSetToUnknown.C, obj.e) assertEquals(DeserializeNewerSetToUnknown.C, obj.e)
} }
@ -80,17 +80,17 @@ class EnumEvolveTests {
// File(URI("$localPath/$resource.D")).writeBytes(so.serialize(C(DeserializeNewerSetToUnknown2.D)).bytes) // File(URI("$localPath/$resource.D")).writeBytes(so.serialize(C(DeserializeNewerSetToUnknown2.D)).bytes)
// File(URI("$localPath/$resource.E")).writeBytes(so.serialize(C(DeserializeNewerSetToUnknown2.E)).bytes) // File(URI("$localPath/$resource.E")).writeBytes(so.serialize(C(DeserializeNewerSetToUnknown2.E)).bytes)
val path1 = EvolvabilityTests::class.java.getResource("$resource.C") val url1 = EvolvabilityTests::class.java.getResource("$resource.C")
val path2 = EvolvabilityTests::class.java.getResource("$resource.D") val url2 = EvolvabilityTests::class.java.getResource("$resource.D")
val path3 = EvolvabilityTests::class.java.getResource("$resource.E") val url3 = EvolvabilityTests::class.java.getResource("$resource.E")
// C will just work // C will just work
val obj1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path1.toURI()).readBytes())) val obj1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(url1.readBytes()))
// D will transform directly to C // D will transform directly to C
val obj2 = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path2.toURI()).readBytes())) val obj2 = DeserializationInput(sf).deserialize(SerializedBytes<C>(url2.readBytes()))
// E will have to transform from E -> D -> C to work, so this should exercise that part // E will have to transform from E -> D -> C to work, so this should exercise that part
// of the evolution code // of the evolution code
val obj3 = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path3.toURI()).readBytes())) val obj3 = DeserializationInput(sf).deserialize(SerializedBytes<C>(url3.readBytes()))
assertEquals(DeserializeNewerSetToUnknown2.C, obj1.e) assertEquals(DeserializeNewerSetToUnknown2.C, obj1.e)
assertEquals(DeserializeNewerSetToUnknown2.C, obj2.e) assertEquals(DeserializeNewerSetToUnknown2.C, obj2.e)
@ -118,10 +118,10 @@ class EnumEvolveTests {
// val so = SerializationOutput(sf) // val so = SerializationOutput(sf)
// File(URI("$localPath/$resource")).writeBytes(so.serialize(C(DeserializeNewerWithNoRule.D)).bytes) // File(URI("$localPath/$resource")).writeBytes(so.serialize(C(DeserializeNewerWithNoRule.D)).bytes)
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
Assertions.assertThatThrownBy { assertThatThrownBy {
DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path.toURI()).readBytes())) DeserializationInput(sf).deserialize(SerializedBytes<C>(url.readBytes()))
}.isInstanceOf(NotSerializableException::class.java) }.isInstanceOf(NotSerializableException::class.java)
} }
@ -184,9 +184,9 @@ class EnumEvolveTests {
val path1_B = EvolvabilityTests::class.java.getResource("$resource.1.B") val path1_B = EvolvabilityTests::class.java.getResource("$resource.1.B")
val path1_C = EvolvabilityTests::class.java.getResource("$resource.1.C") val path1_C = EvolvabilityTests::class.java.getResource("$resource.1.C")
val obj1_AA = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path1_AA.toURI()).readBytes())) val obj1_AA = DeserializationInput(sf).deserialize(SerializedBytes<C>(path1_AA.readBytes()))
val obj1_B = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path1_B.toURI()).readBytes())) val obj1_B = DeserializationInput(sf).deserialize(SerializedBytes<C>(path1_B.readBytes()))
val obj1_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path1_C.toURI()).readBytes())) val obj1_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(path1_C.readBytes()))
assertEquals(DeserializeWithRename.A, obj1_AA.e) assertEquals(DeserializeWithRename.A, obj1_AA.e)
assertEquals(DeserializeWithRename.B, obj1_B.e) assertEquals(DeserializeWithRename.B, obj1_B.e)
@ -199,9 +199,9 @@ class EnumEvolveTests {
val path2_BB = EvolvabilityTests::class.java.getResource("$resource.2.BB") val path2_BB = EvolvabilityTests::class.java.getResource("$resource.2.BB")
val path2_C = EvolvabilityTests::class.java.getResource("$resource.2.C") val path2_C = EvolvabilityTests::class.java.getResource("$resource.2.C")
val obj2_AA = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path2_AA.toURI()).readBytes())) val obj2_AA = DeserializationInput(sf).deserialize(SerializedBytes<C>(path2_AA.readBytes()))
val obj2_BB = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path2_BB.toURI()).readBytes())) val obj2_BB = DeserializationInput(sf).deserialize(SerializedBytes<C>(path2_BB.readBytes()))
val obj2_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path2_C.toURI()).readBytes())) val obj2_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(path2_C.readBytes()))
assertEquals(DeserializeWithRename.A, obj2_AA.e) assertEquals(DeserializeWithRename.A, obj2_AA.e)
assertEquals(DeserializeWithRename.B, obj2_BB.e) assertEquals(DeserializeWithRename.B, obj2_BB.e)
@ -214,9 +214,9 @@ class EnumEvolveTests {
val path3_XX = EvolvabilityTests::class.java.getResource("$resource.3.XX") val path3_XX = EvolvabilityTests::class.java.getResource("$resource.3.XX")
val path3_C = EvolvabilityTests::class.java.getResource("$resource.3.C") val path3_C = EvolvabilityTests::class.java.getResource("$resource.3.C")
val obj3_AA = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path3_AA.toURI()).readBytes())) val obj3_AA = DeserializationInput(sf).deserialize(SerializedBytes<C>(path3_AA.readBytes()))
val obj3_XX = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path3_XX.toURI()).readBytes())) val obj3_XX = DeserializationInput(sf).deserialize(SerializedBytes<C>(path3_XX.readBytes()))
val obj3_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path3_C.toURI()).readBytes())) val obj3_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(path3_C.readBytes()))
assertEquals(DeserializeWithRename.A, obj3_AA.e) assertEquals(DeserializeWithRename.A, obj3_AA.e)
assertEquals(DeserializeWithRename.B, obj3_XX.e) assertEquals(DeserializeWithRename.B, obj3_XX.e)
@ -359,11 +359,11 @@ class EnumEvolveTests {
Pair("$resource.5.G", MultiOperations.C)) Pair("$resource.5.G", MultiOperations.C))
fun load(l: List<Pair<String, MultiOperations>>) = l.map { fun load(l: List<Pair<String, MultiOperations>>) = l.map {
assertNotNull (EvolvabilityTests::class.java.getResource(it.first)) assertNotNull(EvolvabilityTests::class.java.getResource(it.first))
assertTrue (File(EvolvabilityTests::class.java.getResource(it.first).toURI()).exists()) assertThat(EvolvabilityTests::class.java.getResource(it.first).toPath()).exists()
Pair(DeserializationInput(sf).deserialize(SerializedBytes<C>( Pair(DeserializationInput(sf).deserialize(SerializedBytes<C>(
File(EvolvabilityTests::class.java.getResource(it.first).toURI()).readBytes())), it.second) EvolvabilityTests::class.java.getResource(it.first).readBytes())), it.second)
} }
load(stage1Resources).forEach { assertEquals(it.second, it.first.e) } load(stage1Resources).forEach { assertEquals(it.second, it.first.e) }
@ -382,7 +382,7 @@ class EnumEvolveTests {
data class C(val e: BadNewValue) data class C(val e: BadNewValue)
Assertions.assertThatThrownBy { assertThatThrownBy {
SerializationOutput(sf).serialize(C(BadNewValue.A)) SerializationOutput(sf).serialize(C(BadNewValue.A))
}.isInstanceOf(NotSerializableException::class.java) }.isInstanceOf(NotSerializableException::class.java)
} }
@ -399,7 +399,7 @@ class EnumEvolveTests {
data class C(val e: OutOfOrder) data class C(val e: OutOfOrder)
Assertions.assertThatThrownBy { assertThatThrownBy {
SerializationOutput(sf).serialize(C(OutOfOrder.A)) SerializationOutput(sf).serialize(C(OutOfOrder.A))
}.isInstanceOf(NotSerializableException::class.java) }.isInstanceOf(NotSerializableException::class.java)
} }
@ -423,9 +423,9 @@ class EnumEvolveTests {
// File(URI("$localPath/$resource")).writeBytes( // File(URI("$localPath/$resource")).writeBytes(
// SerializationOutput(sf).serialize(C(ChangedOrdinality.A)).bytes) // SerializationOutput(sf).serialize(C(ChangedOrdinality.A)).bytes)
Assertions.assertThatThrownBy { assertThatThrownBy {
DeserializationInput(sf).deserialize(SerializedBytes<C>( DeserializationInput(sf).deserialize(SerializedBytes<C>(
File(EvolvabilityTests::class.java.getResource(resource).toURI()).readBytes())) EvolvabilityTests::class.java.getResource(resource).readBytes()))
}.isInstanceOf(NotSerializableException::class.java) }.isInstanceOf(NotSerializableException::class.java)
} }
} }

View File

@ -15,7 +15,6 @@ import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions
import org.junit.Test import org.junit.Test
import java.io.File
import java.io.NotSerializableException import java.io.NotSerializableException
import java.time.DayOfWeek import java.time.DayOfWeek
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -161,8 +160,7 @@ class EnumTests {
@Test(expected = NotSerializableException::class) @Test(expected = NotSerializableException::class)
fun changedEnum1() { fun changedEnum1() {
val path = EnumTests::class.java.getResource("EnumTests.changedEnum1") val url = EnumTests::class.java.getResource("EnumTests.changedEnum1")
val f = File(path.toURI())
data class C(val a: OldBras) data class C(val a: OldBras)
@ -173,7 +171,7 @@ class EnumTests {
// f.writeBytes(sc.bytes) // f.writeBytes(sc.bytes)
// println(path) // println(path)
val sc2 = f.readBytes() val sc2 = url.readBytes()
// we expect this to throw // we expect this to throw
DeserializationInput(sf1).deserialize(SerializedBytes<C>(sc2)) DeserializationInput(sf1).deserialize(SerializedBytes<C>(sc2))
@ -181,8 +179,7 @@ class EnumTests {
@Test(expected = NotSerializableException::class) @Test(expected = NotSerializableException::class)
fun changedEnum2() { fun changedEnum2() {
val path = EnumTests::class.java.getResource("EnumTests.changedEnum2") val url = EnumTests::class.java.getResource("EnumTests.changedEnum2")
val f = File(path.toURI())
data class C(val a: OldBras2) data class C(val a: OldBras2)
@ -196,7 +193,7 @@ class EnumTests {
// f.writeBytes(sc.bytes) // f.writeBytes(sc.bytes)
// println(path) // println(path)
val sc2 = f.readBytes() val sc2 = url.readBytes()
// we expect this to throw // we expect this to throw
DeserializationInput(sf1).deserialize(SerializedBytes<C>(sc2)) DeserializationInput(sf1).deserialize(SerializedBytes<C>(sc2))

View File

@ -40,7 +40,7 @@ import kotlin.test.assertEquals
class EvolvabilityTests { class EvolvabilityTests {
// When regenerating the test files this needs to be set to the file system location of the resource files // When regenerating the test files this needs to be set to the file system location of the resource files
@Suppress("UNUSED") @Suppress("UNUSED")
var localPath = projectRootDir.toUri().resolve( var localPath: URI = projectRootDir.toUri().resolve(
"node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp") "node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp")
@Test @Test
@ -59,10 +59,8 @@ class EvolvabilityTests {
// new version of the class, in this case the order of the parameters has been swapped // new version of the class, in this case the order of the parameters has been swapped
data class C(val b: Int, val a: Int) data class C(val b: Int, val a: Int)
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
val f = File(path.toURI()) val sc2 = url.readBytes()
val sc2 = f.readBytes()
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2)) val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
assertEquals(A, deserializedC.a) assertEquals(A, deserializedC.a)
@ -84,9 +82,8 @@ class EvolvabilityTests {
// new version of the class, in this case the order of the parameters has been swapped // new version of the class, in this case the order of the parameters has been swapped
data class C(val b: String, val a: Int) data class C(val b: String, val a: Int)
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
val f = File(path.toURI()) val sc2 = url.readBytes()
val sc2 = f.readBytes()
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2)) val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
assertEquals(A, deserializedC.a) assertEquals(A, deserializedC.a)
@ -105,9 +102,8 @@ class EvolvabilityTests {
data class C(val a: Int, val b: Int?) data class C(val a: Int, val b: Int?)
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
val f = File(path.toURI()) val sc2 = url.readBytes()
val sc2 = f.readBytes()
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2)) val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
assertEquals(A, deserializedC.a) assertEquals(A, deserializedC.a)
@ -117,8 +113,7 @@ class EvolvabilityTests {
@Test(expected = NotSerializableException::class) @Test(expected = NotSerializableException::class)
fun addAdditionalParam() { fun addAdditionalParam() {
val sf = testDefaultFactory() val sf = testDefaultFactory()
val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.addAdditionalParam") val url = EvolvabilityTests::class.java.getResource("EvolvabilityTests.addAdditionalParam")
val f = File(path.toURI())
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
val A = 1 val A = 1
@ -132,7 +127,7 @@ class EvolvabilityTests {
// new version of the class, in this case a new parameter has been added (b) // new version of the class, in this case a new parameter has been added (b)
data class C(val a: Int, val b: Int) data class C(val a: Int, val b: Int)
val sc2 = f.readBytes() val sc2 = url.readBytes()
// Expected to throw as we can't construct the new type as it contains a newly // Expected to throw as we can't construct the new type as it contains a newly
// added parameter that isn't optional, i.e. not nullable and there isn't // added parameter that isn't optional, i.e. not nullable and there isn't
@ -156,9 +151,8 @@ class EvolvabilityTests {
data class CC(val b: String, val d: Int) data class CC(val b: String, val d: Int)
val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.removeParameters") val url = EvolvabilityTests::class.java.getResource("EvolvabilityTests.removeParameters")
val f = File(path.toURI()) val sc2 = url.readBytes()
val sc2 = f.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2)) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
assertEquals(B, deserializedCC.b) assertEquals(B, deserializedCC.b)
@ -183,9 +177,8 @@ class EvolvabilityTests {
data class CC(val a: Int, val e: Boolean?, val d: Int) data class CC(val a: Int, val e: Boolean?, val d: Int)
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
val f = File(path.toURI()) val sc2 = url.readBytes()
val sc2 = f.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2)) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
assertEquals(A, deserializedCC.a) assertEquals(A, deserializedCC.a)
@ -209,9 +202,8 @@ class EvolvabilityTests {
constructor (a: Int) : this(a, "hello") constructor (a: Int) : this(a, "hello")
} }
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
val f = File(path.toURI()) val sc2 = url.readBytes()
val sc2 = f.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2)) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
assertEquals(A, deserializedCC.a) assertEquals(A, deserializedCC.a)
@ -222,9 +214,8 @@ class EvolvabilityTests {
@Suppress("UNUSED") @Suppress("UNUSED")
fun addMandatoryFieldWithAltConstructorUnAnnotated() { fun addMandatoryFieldWithAltConstructorUnAnnotated() {
val sf = testDefaultFactory() val sf = testDefaultFactory()
val path = EvolvabilityTests::class.java.getResource( val url = EvolvabilityTests::class.java.getResource(
"EvolvabilityTests.addMandatoryFieldWithAltConstructorUnAnnotated") "EvolvabilityTests.addMandatoryFieldWithAltConstructorUnAnnotated")
val f = File(path.toURI())
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
val A = 1 val A = 1
@ -242,7 +233,7 @@ class EvolvabilityTests {
// we expect this to throw as we should not find any constructors // we expect this to throw as we should not find any constructors
// capable of dealing with this // capable of dealing with this
DeserializationInput(sf).deserialize(SerializedBytes<CC>(f.readBytes())) DeserializationInput(sf).deserialize(SerializedBytes<CC>(url.readBytes()))
} }
@Test @Test
@ -265,9 +256,8 @@ class EvolvabilityTests {
constructor (c: String, a: Int, b: Int) : this(a, b, c, "wibble") constructor (c: String, a: Int, b: Int) : this(a, b, c, "wibble")
} }
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
val f = File(path.toURI()) val sc2 = url.readBytes()
val sc2 = f.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2)) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
assertEquals(A, deserializedCC.a) assertEquals(A, deserializedCC.a)
@ -298,9 +288,8 @@ class EvolvabilityTests {
constructor (c: String, a: Int) : this(a, c, "wibble") constructor (c: String, a: Int) : this(a, c, "wibble")
} }
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
val f = File(path.toURI()) val sc2 = url.readBytes()
val sc2 = f.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2)) val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
assertEquals(A, deserializedCC.a) assertEquals(A, deserializedCC.a)
@ -345,11 +334,11 @@ class EvolvabilityTests {
constructor (a: Int, b: Int, c: Int, d: Int) : this(-1, c, b, a, d) constructor (a: Int, b: Int, c: Int, d: Int) : this(-1, c, b, a, d)
} }
val path1 = EvolvabilityTests::class.java.getResource(resource1) val url1 = EvolvabilityTests::class.java.getResource(resource1)
val path2 = EvolvabilityTests::class.java.getResource(resource2) val url2 = EvolvabilityTests::class.java.getResource(resource2)
val path3 = EvolvabilityTests::class.java.getResource(resource3) val url3 = EvolvabilityTests::class.java.getResource(resource3)
val sb1 = File(path1.toURI()).readBytes() val sb1 = url1.readBytes()
val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1)) val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1))
assertEquals(a, db1.a) assertEquals(a, db1.a)
@ -358,7 +347,7 @@ class EvolvabilityTests {
assertEquals(-1, db1.d) assertEquals(-1, db1.d)
assertEquals(-1, db1.e) assertEquals(-1, db1.e)
val sb2 = File(path2.toURI()).readBytes() val sb2 = url2.readBytes()
val db2 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb2)) val db2 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb2))
assertEquals(a, db2.a) assertEquals(a, db2.a)
@ -367,7 +356,7 @@ class EvolvabilityTests {
assertEquals(-1, db2.d) assertEquals(-1, db2.d)
assertEquals(-1, db2.e) assertEquals(-1, db2.e)
val sb3 = File(path3.toURI()).readBytes() val sb3 = url3.readBytes()
val db3 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb3)) val db3 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb3))
assertEquals(a, db3.a) assertEquals(a, db3.a)
@ -394,9 +383,8 @@ class EvolvabilityTests {
data class Outer(val a: Int, val b: Inner) data class Outer(val a: Int, val b: Inner)
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
val f = File(path.toURI()) val sc2 = url.readBytes()
val sc2 = f.readBytes()
val outer = DeserializationInput(sf).deserialize(SerializedBytes<Outer>(sc2)) val outer = DeserializationInput(sf).deserialize(SerializedBytes<Outer>(sc2))
assertEquals(oa, outer.a) assertEquals(oa, outer.a)
@ -449,11 +437,11 @@ class EvolvabilityTests {
constructor (b: Int, c: Int, d: Int, e: Int, f: Int) : this(b, c, d, e, f, -1) constructor (b: Int, c: Int, d: Int, e: Int, f: Int) : this(b, c, d, e, f, -1)
} }
val path1 = EvolvabilityTests::class.java.getResource(resource1) val url1 = EvolvabilityTests::class.java.getResource(resource1)
val path2 = EvolvabilityTests::class.java.getResource(resource2) val url2 = EvolvabilityTests::class.java.getResource(resource2)
val path3 = EvolvabilityTests::class.java.getResource(resource3) val url3 = EvolvabilityTests::class.java.getResource(resource3)
val sb1 = File(path1.toURI()).readBytes() val sb1 = url1.readBytes()
val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1)) val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1))
assertEquals(b, db1.b) assertEquals(b, db1.b)
@ -463,7 +451,7 @@ class EvolvabilityTests {
assertEquals(-1, db1.f) assertEquals(-1, db1.f)
assertEquals(-1, db1.g) assertEquals(-1, db1.g)
val sb2 = File(path2.toURI()).readBytes() val sb2 = url2.readBytes()
val db2 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb2)) val db2 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb2))
assertEquals(b, db2.b) assertEquals(b, db2.b)
@ -473,7 +461,7 @@ class EvolvabilityTests {
assertEquals(-1, db2.f) assertEquals(-1, db2.f)
assertEquals(-1, db1.g) assertEquals(-1, db1.g)
val sb3 = File(path3.toURI()).readBytes() val sb3 = url3.readBytes()
val db3 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb3)) val db3 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb3))
assertEquals(b, db3.b) assertEquals(b, db3.b)
@ -511,9 +499,8 @@ class EvolvabilityTests {
// //
val resource = "networkParams.r3corda.6a6b6f256" val resource = "networkParams.r3corda.6a6b6f256"
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
val f = File(path.toURI()) val sc2 = url.readBytes()
val sc2 = f.readBytes()
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<SignedData<NetworkParameters>>(sc2)) val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<SignedData<NetworkParameters>>(sc2))
val networkParams = DeserializationInput(sf).deserialize(deserializedC.raw) val networkParams = DeserializationInput(sf).deserialize(deserializedC.raw)
@ -548,7 +535,7 @@ class EvolvabilityTests {
val signed = SignedData(serialized, sig) val signed = SignedData(serialized, sig)
val signedAndSerialized = testOutput.serialize(signed) val signedAndSerialized = testOutput.serialize(signed)
File(URI("$localPath/$resource")).writeBytes( signedAndSerialized.bytes) File(URI("$localPath/$resource")).writeBytes(signedAndSerialized.bytes)
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@ -581,10 +568,9 @@ class EvolvabilityTests {
constructor() : this(0, 0, 0, 0) constructor() : this(0, 0, 0, 0)
} }
val path = EvolvabilityTests::class.java.getResource(resource) val url = EvolvabilityTests::class.java.getResource(resource)
val f = File(path.toURI())
val sc2 = f.readBytes() val sc2 = url.readBytes()
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2)) val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
assertEquals(1, deserializedC.a) assertEquals(1, deserializedC.a)

View File

@ -277,7 +277,7 @@ class GenericsTests {
assertEquals("wibble", assertEquals("wibble",
DeserializationInput(sf).deserialize(SerializedBytes<ForceWildcard<*>>( DeserializationInput(sf).deserialize(SerializedBytes<ForceWildcard<*>>(
File(GenericsTests::class.java.getResource(resource).toURI()).readBytes())).t) GenericsTests::class.java.getResource(resource).readBytes())).t)
} }
data class StateAndString(val state: TransactionState<*>, val ref: String) data class StateAndString(val state: TransactionState<*>, val ref: String)

View File

@ -14,9 +14,8 @@ import net.corda.core.serialization.ClassWhitelist
import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.SerializedBytes
import net.corda.nodeapi.internal.serialization.AllWhitelist import net.corda.nodeapi.internal.serialization.AllWhitelist
import net.corda.nodeapi.internal.serialization.carpenter.ClassCarpenter import net.corda.nodeapi.internal.serialization.carpenter.ClassCarpenter
import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test import org.junit.Test
import java.io.File
import java.io.NotSerializableException import java.io.NotSerializableException
import java.lang.reflect.Type import java.lang.reflect.Type
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@ -83,8 +82,7 @@ class StaticInitialisationOfSerializedObjectTest {
fun deserializeTest() { fun deserializeTest() {
data class D(val c: C2) data class D(val c: C2)
val path = EvolvabilityTests::class.java.getResource("StaticInitialisationOfSerializedObjectTest.deserializeTest") val url = EvolvabilityTests::class.java.getResource("StaticInitialisationOfSerializedObjectTest.deserializeTest")
val f = File(path.toURI())
// Original version of the class for the serialised version of this class // Original version of the class for the serialised version of this class
// //
@ -100,9 +98,9 @@ class StaticInitialisationOfSerializedObjectTest {
} }
val sf2 = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) val sf2 = SerializerFactory(WL(), ClassLoader.getSystemClassLoader())
val bytes = f.readBytes() val bytes = url.readBytes()
Assertions.assertThatThrownBy { assertThatThrownBy {
DeserializationInput(sf2).deserialize(SerializedBytes<D>(bytes)) DeserializationInput(sf2).deserialize(SerializedBytes<D>(bytes))
}.isInstanceOf(NotSerializableException::class.java) }.isInstanceOf(NotSerializableException::class.java)
} }
@ -119,8 +117,7 @@ class StaticInitialisationOfSerializedObjectTest {
fun deserializeTest2() { fun deserializeTest2() {
data class D(val c: C2) data class D(val c: C2)
val path = EvolvabilityTests::class.java.getResource("StaticInitialisationOfSerializedObjectTest.deserializeTest2") val url = EvolvabilityTests::class.java.getResource("StaticInitialisationOfSerializedObjectTest.deserializeTest2")
val f = File(path.toURI())
// Original version of the class for the serialised version of this class // Original version of the class for the serialised version of this class
// //
@ -142,12 +139,12 @@ class StaticInitialisationOfSerializedObjectTest {
} }
val sf2 = TestSerializerFactory(WL1(), WL2()) val sf2 = TestSerializerFactory(WL1(), WL2())
val bytes = f.readBytes() val bytes = url.readBytes()
// Deserializing should throw because C is not on the whitelist NOT because // Deserializing should throw because C is not on the whitelist NOT because
// we ever went anywhere near statically constructing it prior to not actually // we ever went anywhere near statically constructing it prior to not actually
// creating an instance of it // creating an instance of it
Assertions.assertThatThrownBy { assertThatThrownBy {
DeserializationInput(sf2).deserialize(SerializedBytes<D>(bytes)) DeserializationInput(sf2).deserialize(SerializedBytes<D>(bytes))
}.isInstanceOf(NotSerializableException::class.java) }.isInstanceOf(NotSerializableException::class.java)
} }

View File

@ -15,6 +15,8 @@ import net.corda.client.rpc.CordaRPCClient
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC import net.corda.core.flows.StartableByRPC
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.list
import net.corda.core.internal.readLines
import net.corda.core.messaging.startFlow import net.corda.core.messaging.startFlow
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.NodeStartup import net.corda.node.internal.NodeStartup
@ -35,7 +37,6 @@ import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.ClassRule import org.junit.ClassRule
import org.junit.Test import org.junit.Test
import java.io.* import java.io.*
import java.nio.file.Files
import kotlin.test.assertEquals import kotlin.test.assertEquals
class BootTests : IntegrationTest() { class BootTests : IntegrationTest() {
@ -63,13 +64,13 @@ class BootTests : IntegrationTest() {
driver(DriverParameters(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { driver(DriverParameters(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) {
val alice = startNode(providedName = ALICE_NAME).get() val alice = startNode(providedName = ALICE_NAME).get()
val logFolder = alice.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME val logFolder = alice.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME
val logFile = logFolder.toFile().listFiles { _, name -> name.endsWith(".log") }.single() val logFile = logFolder.list { it.filter { it.fileName.toString().endsWith(".log") }.findAny().get() }
// Start second Alice, should fail // Start second Alice, should fail
assertThatThrownBy { assertThatThrownBy {
startNode(providedName = ALICE_NAME).getOrThrow() startNode(providedName = ALICE_NAME).getOrThrow()
} }
// We count the number of nodes that wrote into the logfile by counting "Logs can be found in" // We count the number of nodes that wrote into the logfile by counting "Logs can be found in"
val numberOfNodesThatLogged = Files.lines(logFile.toPath()).filter { NodeStartup.LOGS_CAN_BE_FOUND_IN_STRING in it }.count() val numberOfNodesThatLogged = logFile.readLines { it.filter { NodeStartup.LOGS_CAN_BE_FOUND_IN_STRING in it }.count() }
assertEquals(1, numberOfNodesThatLogged) assertEquals(1, numberOfNodesThatLogged)
} }
} }

View File

@ -14,57 +14,56 @@ import com.typesafe.config.Config
import com.typesafe.config.ConfigException import com.typesafe.config.ConfigException
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigRenderOptions import com.typesafe.config.ConfigRenderOptions
import net.corda.core.internal.div
import net.corda.core.internal.writeText
import net.corda.node.internal.cordapp.CordappConfigFileProvider import net.corda.node.internal.cordapp.CordappConfigFileProvider
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.Test import org.junit.Test
import java.io.File import java.nio.file.Paths
import java.nio.file.Files
import java.nio.file.Path
class CordappConfigFileProviderTests { class CordappConfigFileProviderTests {
private companion object { private companion object {
val cordappConfDir = File("build/tmp/cordapps/config") val cordappConfDir = Paths.get("build") / "tmp" / "cordapps" / "config"
val cordappName = "test" const val cordappName = "test"
val cordappConfFile = File(cordappConfDir, cordappName + ".conf").toPath() val cordappConfFile = cordappConfDir / "$cordappName.conf"
val validConfig = ConfigFactory.parseString("key=value") val validConfig: Config = ConfigFactory.parseString("key=value")
val alternateValidConfig = ConfigFactory.parseString("key=alternateValue") val alternateValidConfig: Config = ConfigFactory.parseString("key=alternateValue")
val invalidConfig = "Invalid" const val invalidConfig = "Invalid"
} }
val provider = CordappConfigFileProvider(cordappConfDir) private val provider = CordappConfigFileProvider(cordappConfDir)
@Test @Test
fun `test that config can be loaded`() { fun `test that config can be loaded`() {
writeConfig(validConfig, cordappConfFile) writeConfig(validConfig)
assertThat(provider.getConfigByName(cordappName)).isEqualTo(validConfig) assertThat(provider.getConfigByName(cordappName)).isEqualTo(validConfig)
} }
@Test @Test
fun `config is idempotent if the underlying file is not changed`() { fun `config is idempotent if the underlying file is not changed`() {
writeConfig(validConfig, cordappConfFile) writeConfig(validConfig)
assertThat(provider.getConfigByName(cordappName)).isEqualTo(validConfig) assertThat(provider.getConfigByName(cordappName)).isEqualTo(validConfig)
assertThat(provider.getConfigByName(cordappName)).isEqualTo(validConfig) assertThat(provider.getConfigByName(cordappName)).isEqualTo(validConfig)
} }
@Test @Test
fun `config is not idempotent if the underlying file is changed`() { fun `config is not idempotent if the underlying file is changed`() {
writeConfig(validConfig, cordappConfFile) writeConfig(validConfig)
assertThat(provider.getConfigByName(cordappName)).isEqualTo(validConfig) assertThat(provider.getConfigByName(cordappName)).isEqualTo(validConfig)
writeConfig(alternateValidConfig, cordappConfFile) writeConfig(alternateValidConfig)
assertThat(provider.getConfigByName(cordappName)).isEqualTo(alternateValidConfig) assertThat(provider.getConfigByName(cordappName)).isEqualTo(alternateValidConfig)
} }
@Test(expected = ConfigException.Parse::class) @Test(expected = ConfigException.Parse::class)
fun `an invalid config throws an exception`() { fun `an invalid config throws an exception`() {
Files.write(cordappConfFile, invalidConfig.toByteArray()) cordappConfFile.writeText(invalidConfig)
provider.getConfigByName(cordappName) provider.getConfigByName(cordappName)
} }
/** /**
* Writes the config to the path provided - will (and must) overwrite any existing config * Writes the config to the path provided - will (and must) overwrite any existing config
*/ */
private fun writeConfig(config: Config, to: Path) = Files.write(cordappConfFile, config.root().render(ConfigRenderOptions.concise()).toByteArray()) private fun writeConfig(config: Config) = cordappConfFile.writeText(config.root().render(ConfigRenderOptions.concise()))
} }

View File

@ -18,6 +18,7 @@ import net.corda.core.flows.FlowLogic
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.concurrent.transpose import net.corda.core.internal.concurrent.transpose
import net.corda.core.internal.copyTo
import net.corda.core.internal.createDirectories import net.corda.core.internal.createDirectories
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.toLedgerTransaction import net.corda.core.internal.toLedgerTransaction
@ -44,7 +45,6 @@ import org.junit.ClassRule
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import java.net.URLClassLoader import java.net.URLClassLoader
import java.nio.file.Files
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
class AttachmentLoadingTests : IntegrationTest() { class AttachmentLoadingTests : IntegrationTest() {
@ -65,7 +65,7 @@ class AttachmentLoadingTests : IntegrationTest() {
private val logger = contextLogger() private val logger = contextLogger()
val isolatedJAR = AttachmentLoadingTests::class.java.getResource("isolated.jar")!! val isolatedJAR = AttachmentLoadingTests::class.java.getResource("isolated.jar")!!
val ISOLATED_CONTRACT_ID = "net.corda.finance.contracts.isolated.AnotherDummyContract" const val ISOLATED_CONTRACT_ID = "net.corda.finance.contracts.isolated.AnotherDummyContract"
val bankAName = CordaX500Name("BankA", "Zurich", "CH") val bankAName = CordaX500Name("BankA", "Zurich", "CH")
val bankBName = CordaX500Name("BankB", "Zurich", "CH") val bankBName = CordaX500Name("BankB", "Zurich", "CH")
@ -85,11 +85,7 @@ class AttachmentLoadingTests : IntegrationTest() {
// Copy the app jar to the first node. The second won't have it. // Copy the app jar to the first node. The second won't have it.
val path = (baseDirectory(nodeName) / "cordapps").createDirectories() / "isolated.jar" val path = (baseDirectory(nodeName) / "cordapps").createDirectories() / "isolated.jar"
logger.info("Installing isolated jar to $path") logger.info("Installing isolated jar to $path")
isolatedJAR.openStream().buffered().use { input -> isolatedJAR.openStream().use { it.copyTo(path) }
Files.newOutputStream(path).buffered().use { output ->
input.copyTo(output)
}
}
} }
} }

View File

@ -39,7 +39,6 @@ import org.junit.*
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import java.net.URL import java.net.URL
import java.time.Instant import java.time.Instant
import kotlin.streams.toList
class NetworkMapTest : IntegrationTest() { class NetworkMapTest : IntegrationTest() {
companion object { companion object {
@ -216,7 +215,7 @@ class NetworkMapTest : IntegrationTest() {
// Make sure the nodes aren't getting the node infos from their additional directories // Make sure the nodes aren't getting the node infos from their additional directories
val nodeInfosDir = baseDirectory / CordformNode.NODE_INFO_DIRECTORY val nodeInfosDir = baseDirectory / CordformNode.NODE_INFO_DIRECTORY
if (nodeInfosDir.exists()) { if (nodeInfosDir.exists()) {
assertThat(nodeInfosDir.list { it.toList() }).isEmpty() assertThat(nodeInfosDir.list()).isEmpty()
} }
assertThat(rpc.networkMapSnapshot()).containsOnly(*nodes) assertThat(rpc.networkMapSnapshot()).containsOnly(*nodes)
} }

View File

@ -15,6 +15,7 @@ import com.google.common.jimfs.Jimfs
import net.corda.cordform.CordformNode import net.corda.cordform.CordformNode
import net.corda.core.internal.createDirectories import net.corda.core.internal.createDirectories
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.size
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.node.services.KeyManagementService import net.corda.core.node.services.KeyManagementService
import net.corda.nodeapi.internal.NodeInfoAndSigned import net.corda.nodeapi.internal.NodeInfoAndSigned
@ -25,7 +26,6 @@ import net.corda.testing.internal.createNodeInfoAndSigned
import net.corda.testing.node.internal.MockKeyManagementService import net.corda.testing.node.internal.MockKeyManagementService
import net.corda.testing.node.makeTestIdentityService import net.corda.testing.node.makeTestIdentityService
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.contentOf
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -75,9 +75,9 @@ class NodeInfoWatcherTest {
assertEquals(1, nodeInfoFiles.size) assertEquals(1, nodeInfoFiles.size)
val fileName = nodeInfoFiles.first() val fileName = nodeInfoFiles.first()
assertTrue(fileName.startsWith(NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX)) assertTrue(fileName.startsWith(NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX))
val file = (tempFolder.root.path / fileName).toFile() val file = (tempFolder.root.path / fileName)
// Just check that something is written, another tests verifies that the written value can be read back. // Just check that something is written, another tests verifies that the written value can be read back.
assertThat(contentOf(file)).isNotEmpty() assertThat(file.size).isGreaterThan(0)
} }
@Test @Test

View File

@ -103,7 +103,7 @@ class MQSecurityAsNodeTest : P2PMQSecurityTest() {
val legalName = CordaX500Name("MegaCorp", "London", "GB") val legalName = CordaX500Name("MegaCorp", "London", "GB")
certificatesDirectory.createDirectories() certificatesDirectory.createDirectories()
if (!trustStoreFile.exists()) { if (!trustStoreFile.exists()) {
javaClass.classLoader.getResourceAsStream("certificates/cordatruststore.jks").copyTo(trustStoreFile) javaClass.classLoader.getResourceAsStream("certificates/cordatruststore.jks").use { it.copyTo(trustStoreFile) }
} }
val clientKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) val clientKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)

View File

@ -12,33 +12,34 @@ package net.corda.node.internal.cordapp
import com.typesafe.config.Config import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import net.corda.core.utilities.loggerFor import net.corda.core.internal.createDirectories
import java.io.File import net.corda.core.internal.div
import net.corda.core.internal.exists
import net.corda.core.internal.isDirectory
import net.corda.core.utilities.contextLogger
import java.nio.file.Path
import java.nio.file.Paths
class CordappConfigFileProvider(val configDir: File = DEFAULT_CORDAPP_CONFIG_DIR) : CordappConfigProvider { class CordappConfigFileProvider(private val configDir: Path = DEFAULT_CORDAPP_CONFIG_DIR) : CordappConfigProvider {
companion object { companion object {
val DEFAULT_CORDAPP_CONFIG_DIR = File("cordapps/config") val DEFAULT_CORDAPP_CONFIG_DIR = Paths.get("cordapps") / "config"
val CONFIG_EXT = ".conf" const val CONFIG_EXT = ".conf"
val logger = loggerFor<CordappConfigFileProvider>() val logger = contextLogger()
} }
init { init {
configDir.mkdirs() configDir.createDirectories()
} }
override fun getConfigByName(name: String): Config { override fun getConfigByName(name: String): Config {
val configFile = File(configDir, name + CONFIG_EXT) val configFile = configDir / "$name$CONFIG_EXT"
return if (configFile.exists()) { return if (configFile.exists()) {
if (configFile.isDirectory) { check(!configFile.isDirectory()) { "${configFile.toAbsolutePath()} is a directory, expected a config file" }
throw IllegalStateException("File at ${configFile.absolutePath} is a directory, expected a config file") logger.info("Found config for cordapp $name in ${configFile.toAbsolutePath()}")
} else { ConfigFactory.parseFile(configFile.toFile())
logger.info("Found config for cordapp $name in ${configFile.absolutePath}")
ConfigFactory.parseFile(configFile)
}
} else { } else {
logger.info("No config found for cordapp $name in ${configFile.absolutePath}") logger.info("No config found for cordapp $name in ${configFile.toAbsolutePath()}")
ConfigFactory.empty() ConfigFactory.empty()
} }
} }
}
}

View File

@ -30,15 +30,13 @@ import net.corda.node.services.config.NodeConfiguration
import net.corda.nodeapi.internal.coreContractClasses import net.corda.nodeapi.internal.coreContractClasses
import net.corda.nodeapi.internal.serialization.DefaultWhitelist import net.corda.nodeapi.internal.serialization.DefaultWhitelist
import org.apache.commons.collections4.map.LRUMap import org.apache.commons.collections4.map.LRUMap
import java.io.File
import java.io.FileOutputStream
import java.lang.reflect.Modifier import java.lang.reflect.Modifier
import java.net.JarURLConnection import java.net.JarURLConnection
import java.net.URI import java.net.URI
import java.net.URL import java.net.URL
import java.net.URLClassLoader import java.net.URLClassLoader
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.attribute.FileTime import java.nio.file.attribute.FileTime
import java.time.Instant import java.time.Instant
import java.util.* import java.util.*
@ -88,8 +86,7 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
* Create a dev mode CordappLoader for test environments that creates and loads cordapps from the classpath * Create a dev mode CordappLoader for test environments that creates and loads cordapps from the classpath
* and cordapps directory. This is intended mostly for use by the driver. * and cordapps directory. This is intended mostly for use by the driver.
* *
* @param baseDir See [createDefault.baseDir] * @param testPackages See [createWithTestPackages]
* @param testPackages See [createWithTestPackages.testPackages]
*/ */
@VisibleForTesting @VisibleForTesting
fun createDefaultWithTestPackages(configuration: NodeConfiguration, testPackages: List<String>): CordappLoader { fun createDefaultWithTestPackages(configuration: NodeConfiguration, testPackages: List<String>): CordappLoader {
@ -139,31 +136,26 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
} }
/** Takes a package of classes and creates a JAR from them - only use in tests. */ /** Takes a package of classes and creates a JAR from them - only use in tests. */
private fun createDevCordappJar(scanPackage: String, path: URL, jarPackageName: String): URI { private fun createDevCordappJar(scanPackage: String, url: URL, jarPackageName: String): URI {
if (!generatedCordapps.contains(path)) { return generatedCordapps.computeIfAbsent(url) {
val cordappDir = File("build/tmp/generated-test-cordapps") val cordappDir = (Paths.get("build") / "tmp" / "generated-test-cordapps").createDirectories()
cordappDir.mkdirs() val cordappJAR = cordappDir / "$scanPackage-${UUID.randomUUID()}.jar"
val cordappJAR = File(cordappDir, "$scanPackage-${UUID.randomUUID()}.jar")
logger.info("Generating a test-only cordapp of classes discovered in $scanPackage at $cordappJAR") logger.info("Generating a test-only cordapp of classes discovered in $scanPackage at $cordappJAR")
FileOutputStream(cordappJAR).use { JarOutputStream(cordappJAR.outputStream()).use { jos ->
JarOutputStream(it).use { jos -> val scanDir = url.toPath()
val scanDir = File(path.toURI()) scanDir.walk { it.forEach {
scanDir.walkTopDown().forEach { val entryPath = "$jarPackageName/${scanDir.relativize(it).toString().replace('\\', '/')}"
val entryPath = jarPackageName + "/" + scanDir.toPath().relativize(it.toPath()).toString().replace('\\', '/') val time = FileTime.from(Instant.EPOCH)
val time = FileTime.from(Instant.EPOCH) val entry = ZipEntry(entryPath).setCreationTime(time).setLastAccessTime(time).setLastModifiedTime(time)
val entry = ZipEntry(entryPath).setCreationTime(time).setLastAccessTime(time).setLastModifiedTime(time) jos.putNextEntry(entry)
jos.putNextEntry(entry) if (it.isRegularFile()) {
if (it.isFile) { it.copyTo(jos)
Files.copy(it.toPath(), jos)
}
jos.closeEntry()
} }
} jos.closeEntry()
} }
} }
generatedCordapps[path] = cordappJAR.toURI() cordappJAR.toUri()
} }
return generatedCordapps[path]!!
} }
private fun getCordappsInDirectory(cordappsDir: Path): List<RestrictedURL> { private fun getCordappsInDirectory(cordappsDir: Path): List<RestrictedURL> {

View File

@ -20,10 +20,7 @@ import net.corda.core.concurrent.CordaFuture
import net.corda.core.context.InvocationContext import net.corda.core.context.InvocationContext
import net.corda.core.flows.* import net.corda.core.flows.*
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.FlowIORequest import net.corda.core.internal.*
import net.corda.core.internal.FlowStateMachine
import net.corda.core.internal.isRegularFile
import net.corda.core.internal.uncheckedCast
import net.corda.core.serialization.SerializationContext import net.corda.core.serialization.SerializationContext
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.Try import net.corda.core.utilities.Try
@ -41,7 +38,6 @@ import net.corda.nodeapi.internal.persistence.contextTransaction
import net.corda.nodeapi.internal.persistence.contextTransactionOrNull import net.corda.nodeapi.internal.persistence.contextTransactionOrNull
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.nio.file.Paths
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.reflect.KProperty1 import kotlin.reflect.KProperty1
@ -309,7 +305,7 @@ val Class<out FlowLogic<*>>.flowVersionAndInitiatingClass: Pair<Int, Class<out F
val Class<out FlowLogic<*>>.appName: String val Class<out FlowLogic<*>>.appName: String
get() { get() {
val jarFile = Paths.get(protectionDomain.codeSource.location.toURI()) val jarFile = protectionDomain.codeSource.location.toPath()
return if (jarFile.isRegularFile() && jarFile.toString().endsWith(".jar")) { return if (jarFile.isRegularFile() && jarFile.toString().endsWith(".jar")) {
jarFile.fileName.toString().removeSuffix(".jar") jarFile.fileName.toString().removeSuffix(".jar")
} else { } else {

View File

@ -11,10 +11,10 @@
package net.corda.node.services.transactions package net.corda.node.services.transactions
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.writer
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.debug import net.corda.core.utilities.debug
import java.io.FileWriter
import java.io.PrintWriter import java.io.PrintWriter
import java.net.InetAddress import java.net.InetAddress
import java.net.Socket import java.net.Socket
@ -58,7 +58,7 @@ class BFTSMaRtConfig(private val replicaAddresses: List<NetworkHostAndPort>, deb
private fun configWriter(name: String, block: PrintWriter.() -> Unit) { private fun configWriter(name: String, block: PrintWriter.() -> Unit) {
// Default charset, consistent with loaders: // Default charset, consistent with loaders:
FileWriter((path / name).toFile()).use { (path / name).writer().use {
PrintWriter(it).use { PrintWriter(it).use {
it.run(block) it.run(block)
} }

View File

@ -10,6 +10,7 @@
package net.corda.node.services.transactions package net.corda.node.services.transactions
import net.corda.core.internal.deleteRecursively
import net.corda.core.internal.uncheckedCast import net.corda.core.internal.uncheckedCast
import net.corda.nodeapi.internal.addShutdownHook import net.corda.nodeapi.internal.addShutdownHook
import java.io.Closeable import java.io.Closeable
@ -19,7 +20,7 @@ import java.util.concurrent.atomic.AtomicInteger
private class DeleteOnExitPath(internal val path: Path) { private class DeleteOnExitPath(internal val path: Path) {
private val shutdownHook = addShutdownHook { dispose() } private val shutdownHook = addShutdownHook { dispose() }
internal fun dispose() { internal fun dispose() {
path.toFile().deleteRecursively() path.deleteRecursively()
shutdownHook.cancel() shutdownHook.cancel()
} }
} }

View File

@ -120,7 +120,7 @@ class RaftUniquenessProvider(
get() = _clientFuture.get() get() = _clientFuture.get()
fun start() { fun start() {
log.info("Creating Copycat server, log stored in: ${storagePath.toFile()}") log.info("Creating Copycat server, log stored in: ${storagePath.toAbsolutePath()}")
val stateMachineFactory = { val stateMachineFactory = {
RaftTransactionCommitLog(db, clock, RaftUniquenessProvider.Companion::createMap) RaftTransactionCommitLog(db, clock, RaftUniquenessProvider.Companion::createMap)
} }

View File

@ -13,6 +13,8 @@ package net.corda.node.utilities
import com.ea.agentloader.AgentLoader import com.ea.agentloader.AgentLoader
import net.corda.core.internal.exists import net.corda.core.internal.exists
import net.corda.core.internal.isRegularFile import net.corda.core.internal.isRegularFile
import net.corda.core.internal.toPath
import java.net.URL
import java.net.URLClassLoader import java.net.URLClassLoader
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
@ -53,7 +55,7 @@ object JVMAgentRegistry {
} else { } else {
(this::class.java.classLoader as? URLClassLoader) (this::class.java.classLoader as? URLClassLoader)
?.urLs ?.urLs
?.map { Paths.get(it.toURI()) } ?.map(URL::toPath)
?.firstOrNull { it.fileName.toString() == jarFileName } ?.firstOrNull { it.fileName.toString() == jarFileName }
} }
} }

View File

@ -11,6 +11,7 @@
package net.corda.node package net.corda.node
import joptsimple.OptionException import joptsimple.OptionException
import net.corda.core.internal.delete
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.nodeapi.internal.crypto.X509KeyStore import net.corda.nodeapi.internal.crypto.X509KeyStore
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
@ -18,7 +19,6 @@ import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.BeforeClass import org.junit.BeforeClass
import org.junit.Test import org.junit.Test
import org.slf4j.event.Level import org.slf4j.event.Level
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -150,7 +150,7 @@ class ArgsParserTest {
assertEquals(truststorePath.toAbsolutePath(), cmdLineOptions.nodeRegistrationOption?.networkRootTrustStorePath) assertEquals(truststorePath.toAbsolutePath(), cmdLineOptions.nodeRegistrationOption?.networkRootTrustStorePath)
assertEquals("password-test", cmdLineOptions.nodeRegistrationOption?.networkRootTrustStorePassword) assertEquals("password-test", cmdLineOptions.nodeRegistrationOption?.networkRootTrustStorePassword)
} finally { } finally {
Files.delete(truststorePath) truststorePath.delete()
} }
} }

View File

@ -13,9 +13,10 @@ package net.corda.node.internal
import com.nhaarman.mockito_kotlin.doReturn import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.whenever import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.delete
import net.corda.core.internal.list
import net.corda.core.internal.readObject import net.corda.core.internal.readObject
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.serialization.deserialize
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.VersionInfo import net.corda.node.VersionInfo
import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.NodeConfiguration
@ -28,7 +29,7 @@ import net.corda.testing.node.MockServices.Companion.makeTestDataSourcePropertie
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.TemporaryFolder import org.junit.rules.TemporaryFolder
import java.nio.file.Files import java.nio.file.Path
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertNull import kotlin.test.assertNull
@ -42,14 +43,21 @@ class NodeTest {
@JvmField @JvmField
val testSerialization = SerializationEnvironmentRule() val testSerialization = SerializationEnvironmentRule()
private fun nodeInfoFile() = temporaryFolder.root.listFiles().singleOrNull { it.name.startsWith(NODE_INFO_FILE_NAME_PREFIX) } private fun nodeInfoFile(): Path? {
return temporaryFolder.root.toPath().list { paths ->
paths.filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) }.findAny().orElse(null)
}
}
private fun AbstractNode.generateNodeInfo(): NodeInfo { private fun AbstractNode.generateNodeInfo(): NodeInfo {
assertNull(nodeInfoFile()) assertNull(nodeInfoFile())
generateAndSaveNodeInfo() generateAndSaveNodeInfo()
val path = nodeInfoFile()!!.toPath() val path = nodeInfoFile()!!
val nodeInfo = path.readObject<SignedNodeInfo>().raw.deserialize() try {
Files.delete(path) return path.readObject<SignedNodeInfo>().verified()
return nodeInfo } finally {
path.delete()
}
} }
@Test @Test

View File

@ -38,8 +38,8 @@ import com.opengamma.strata.report.ReportCalculationResults
import com.opengamma.strata.report.trade.TradeReport import com.opengamma.strata.report.trade.TradeReport
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.exists import net.corda.core.internal.exists
import net.corda.core.internal.toPath
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths
import java.time.LocalDate import java.time.LocalDate
/** /**
@ -69,7 +69,7 @@ class SwapPricingCcpExample {
*/ */
private val resourcesUri = run { private val resourcesUri = run {
// Find src/main/resources by walking up the directory tree starting at a classpath root: // Find src/main/resources by walking up the directory tree starting at a classpath root:
var module = Paths.get(javaClass.getResource("/").toURI()) var module = javaClass.getResource("/").toPath()
val relative = "src" / "main" / "resources" val relative = "src" / "main" / "resources"
var path: Path var path: Path
while (true) { while (true) {

View File

@ -10,11 +10,12 @@
package net.corda.testing.node.internal package net.corda.testing.node.internal
import org.apache.commons.io.FileUtils import net.corda.core.internal.readText
import net.corda.core.internal.writeText
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.TemporaryFolder import org.junit.rules.TemporaryFolder
import java.io.File import java.nio.file.Paths
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@ -31,8 +32,7 @@ class ProcessUtilitiesTests {
@JvmStatic @JvmStatic
fun main(args: Array<String>) { fun main(args: Array<String>) {
val fileNameToCreate = args[0] Paths.get(args[0]).writeText(tmpString)
FileUtils.write(File(fileNameToCreate), tmpString)
} }
} }
@ -41,6 +41,6 @@ class ProcessUtilitiesTests {
val tmpFile = tempFolder.newFile("${ProcessUtilitiesTests::class.java.simpleName}.txt") val tmpFile = tempFolder.newFile("${ProcessUtilitiesTests::class.java.simpleName}.txt")
val startedProcess = ProcessUtilities.startJavaProcess<ProcessUtilitiesTests>(listOf(tmpFile.absolutePath)) val startedProcess = ProcessUtilities.startJavaProcess<ProcessUtilitiesTests>(listOf(tmpFile.absolutePath))
assertTrue { startedProcess.waitFor(20, TimeUnit.SECONDS) } assertTrue { startedProcess.waitFor(20, TimeUnit.SECONDS) }
assertEquals(tmpString, FileUtils.readFileToString(tmpFile)) assertEquals(tmpString, tmpFile.toPath().readText())
} }
} }

View File

@ -73,8 +73,6 @@ import java.net.ConnectException
import java.net.URL import java.net.URL
import java.net.URLClassLoader import java.net.URLClassLoader
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.StandardCopyOption
import java.security.cert.X509Certificate import java.security.cert.X509Certificate
import java.time.Duration import java.time.Duration
import java.time.Instant import java.time.Instant
@ -136,7 +134,7 @@ class DriverDSLImpl(
val urls = (cl as URLClassLoader).urLs val urls = (cl as URLClassLoader).urLs
val jarPattern = jarNamePattern.toRegex() val jarPattern = jarNamePattern.toRegex()
val jarFileUrl = urls.first { jarPattern.matches(it.path) } val jarFileUrl = urls.first { jarPattern.matches(it.path) }
Paths.get(jarFileUrl.toURI()).toString() jarFileUrl.toPath().toString()
} catch (e: Exception) { } catch (e: Exception) {
log.warn("Unable to locate JAR `$jarNamePattern` on classpath: ${e.message}", e) log.warn("Unable to locate JAR `$jarNamePattern` on classpath: ${e.message}", e)
throw e throw e
@ -1094,16 +1092,11 @@ fun getTimestampAsDirectoryName(): String {
fun writeConfig(path: Path, filename: String, config: Config) { fun writeConfig(path: Path, filename: String, config: Config) {
val configString = config.root().render(ConfigRenderOptions.defaults()) val configString = config.root().render(ConfigRenderOptions.defaults())
configString.byteInputStream().copyTo(path / filename, StandardCopyOption.REPLACE_EXISTING) (path / filename).writeText(configString)
} }
private fun Config.toNodeOnly(): Config { private fun Config.toNodeOnly(): Config {
return if (hasPath("webAddress")) withoutPath("webAddress").withoutPath("useHTTPS") else this
return if (hasPath("webAddress")) {
withoutPath("webAddress").withoutPath("useHTTPS")
} else {
this
}
} }
private operator fun Config.plus(property: Pair<String, Any>) = withValue(property.first, ConfigValueFactory.fromAnyRef(property.second)) private operator fun Config.plus(property: Pair<String, Any>) = withValue(property.first, ConfigValueFactory.fromAnyRef(property.second))

View File

@ -12,6 +12,7 @@ package net.corda.testing.node.internal.demorun
import net.corda.cordform.CordformDefinition import net.corda.cordform.CordformDefinition
import net.corda.cordform.CordformNode import net.corda.cordform.CordformNode
import net.corda.core.internal.deleteRecursively
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.getOrThrow
import net.corda.testing.driver.JmxPolicy import net.corda.testing.driver.JmxPolicy
@ -39,7 +40,7 @@ class CordformNodeRunner(val cordformDefinition: CordformDefinition) {
fun clean() { fun clean() {
System.err.println("Deleting: ${cordformDefinition.nodesDirectory}") System.err.println("Deleting: ${cordformDefinition.nodesDirectory}")
cordformDefinition.nodesDirectory.toFile().deleteRecursively() cordformDefinition.nodesDirectory.deleteRecursively()
} }
/** /**

View File

@ -13,17 +13,13 @@ package net.corda.smoketesting
import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCClient
import net.corda.client.rpc.CordaRPCConnection import net.corda.client.rpc.CordaRPCConnection
import net.corda.client.rpc.internal.KryoClientSerializationScheme import net.corda.client.rpc.internal.KryoClientSerializationScheme
import net.corda.core.internal.copyTo import net.corda.core.internal.*
import net.corda.core.internal.copyToDirectory
import net.corda.core.internal.createDirectories
import net.corda.core.internal.div
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.nodeapi.internal.network.NetworkParametersCopier import net.corda.nodeapi.internal.network.NetworkParametersCopier
import net.corda.testing.common.internal.asContextEnv import net.corda.testing.common.internal.asContextEnv
import net.corda.testing.common.internal.testNetworkParameters import net.corda.testing.common.internal.testNetworkParameters
import java.io.File import java.io.File
import java.net.URL
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import java.time.Instant import java.time.Instant
@ -57,20 +53,21 @@ class NodeProcess(
} }
log.info("Deleting Artemis directories, because they're large!") log.info("Deleting Artemis directories, because they're large!")
(nodeDir / "artemis").toFile().deleteRecursively() (nodeDir / "artemis").deleteRecursively()
} }
// TODO All use of this factory have duplicate code which is either bundling the calling module or a 3rd party module // TODO All use of this factory have duplicate code which is either bundling the calling module or a 3rd party module
// as a CorDapp for the nodes. // as a CorDapp for the nodes.
class Factory( class Factory(
private val buildDirectory: Path = Paths.get("build"), private val buildDirectory: Path = Paths.get("build"),
private val cordaJarUrl: URL? = this::class.java.getResource("/corda.jar"),
private val extraJvmArgs: Array<out String> = emptyArray(), private val extraJvmArgs: Array<out String> = emptyArray(),
private val redirectConsoleTo: File? = null private val redirectConsoleTo: File? = null
) { ) {
val cordaJar: Path by lazy { val cordaJar: Path by lazy {
require(cordaJarUrl != null, { "corda.jar could not be found in classpath" }) val cordaJarUrl = requireNotNull(this::class.java.getResource("/corda.jar")) {
Paths.get(cordaJarUrl!!.toURI()) "corda.jar could not be found in classpath"
}
cordaJarUrl.toPath()
} }
private companion object { private companion object {
@ -102,7 +99,7 @@ class NodeProcess(
val nodeDir = baseDirectory(config).createDirectories() val nodeDir = baseDirectory(config).createDirectories()
log.info("Node directory: {}", nodeDir) log.info("Node directory: {}", nodeDir)
config.toText().byteInputStream().copyTo(nodeDir / "node.conf") (nodeDir / "node.conf").writeText(config.toText())
defaultNetworkParameters.install(nodeDir) defaultNetworkParameters.install(nodeDir)
val process = startNode(nodeDir) val process = startNode(nodeDir)

View File

@ -12,12 +12,12 @@ package net.corda.testing.common.internal
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.isDirectory import net.corda.core.internal.isDirectory
import net.corda.core.internal.toPath
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths
object ProjectStructure { object ProjectStructure {
val projectRootDir: Path = run { val projectRootDir: Path = run {
var dir = Paths.get(javaClass.getResource("/").toURI()) var dir = javaClass.getResource("/").toPath()
while (!(dir / ".git").isDirectory()) { while (!(dir / ".git").isDirectory()) {
dir = dir.parent dir = dir.parent
} }

View File

@ -11,6 +11,8 @@
package net.corda.testing.common.internal package net.corda.testing.common.internal
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.createFile
import net.corda.core.internal.deleteIfExists
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.nodeapi.internal.config.SSLConfiguration import net.corda.nodeapi.internal.config.SSLConfiguration
import net.corda.nodeapi.internal.crypto.* import net.corda.nodeapi.internal.crypto.*
@ -123,20 +125,19 @@ data class UnsafeKeyStore(private val delegate: KeyStore, val password: String)
fun save(path: Path) = delegate.save(path, password) fun save(path: Path) = delegate.save(path, password)
fun toTemporaryFile(fileName: String, fileExtension: String? = delegate.type.toLowerCase(), directory: Path): TemporaryFile { fun toTemporaryFile(fileName: String, fileExtension: String? = delegate.type.toLowerCase(), directory: Path): TemporaryFile {
return TemporaryFile("$fileName.$fileExtension", directory).also { save(it.path) } return TemporaryFile("$fileName.$fileExtension", directory).also { save(it.file) }
} }
} }
class TemporaryFile(fileName: String, val directory: Path) : AutoCloseable { class TemporaryFile(fileName: String, val directory: Path) : AutoCloseable {
private val file = (directory / fileName).toFile() val file: Path = (directory / fileName).createFile().toAbsolutePath()
init { init {
file.createNewFile() file.toFile().deleteOnExit()
file.deleteOnExit()
} }
val path: Path = file.toPath().toAbsolutePath() override fun close() {
file.deleteIfExists()
override fun close() = FileUtils.forceDelete(file) }
} }
data class UnsafeCertificate(val value: X509Certificate, val privateKey: PrivateKey?) { data class UnsafeCertificate(val value: X509Certificate, val privateKey: PrivateKey?) {
@ -205,8 +206,8 @@ fun withKeyStores(server: KeyStores, client: KeyStores, action: (brokerSslOption
action(serverSslConfiguration.value, clientSslConfiguration.value) action(serverSslConfiguration.value, clientSslConfiguration.value)
} }
} }
FileUtils.deleteQuietly(clientDir.toFile()) clientDir.deleteIfExists()
FileUtils.deleteQuietly(serverDir.toFile()) serverDir.deleteIfExists()
} }
fun withCertificates(factoryDefaults: UnsafeCertificatesFactory.Defaults = UnsafeCertificatesFactory.defaults(), action: (server: KeyStores, client: KeyStores, createSelfSigned: (name: CordaX500Name) -> UnsafeCertificate, createSignedBy: (name: CordaX500Name, issuer: UnsafeCertificate) -> UnsafeCertificate) -> Unit) { fun withCertificates(factoryDefaults: UnsafeCertificatesFactory.Defaults = UnsafeCertificatesFactory.defaults(), action: (server: KeyStores, client: KeyStores, createSelfSigned: (name: CordaX500Name) -> UnsafeCertificate, createSignedBy: (name: CordaX500Name, issuer: UnsafeCertificate) -> UnsafeCertificate) -> Unit) {

View File

@ -10,6 +10,7 @@
package net.corda.demobench.explorer package net.corda.demobench.explorer
import net.corda.core.internal.copyTo
import net.corda.core.internal.createDirectories import net.corda.core.internal.createDirectories
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.list import net.corda.core.internal.list
@ -103,13 +104,13 @@ class Explorer internal constructor(private val explorerController: ExplorerCont
Files.createSymbolicLink(destPath, path) Files.createSymbolicLink(destPath, path)
} catch (e: UnsupportedOperationException) { } catch (e: UnsupportedOperationException) {
// OS doesn't support symbolic links? // OS doesn't support symbolic links?
Files.copy(path, destPath, REPLACE_EXISTING) path.copyTo(destPath, REPLACE_EXISTING)
} catch (e: java.nio.file.FileAlreadyExistsException) { } catch (e: java.nio.file.FileAlreadyExistsException) {
// OK, don't care ... // OK, don't care ...
} catch (e: IOException) { } catch (e: IOException) {
// Windows 10 might not allow this user to create a symlink // Windows 10 might not allow this user to create a symlink
log.warn("Failed to create symlink '{}' for '{}': {}", destPath, path, e.message) log.warn("Failed to create symlink '{}' for '{}': {}", destPath, path, e.message)
Files.copy(path, destPath, REPLACE_EXISTING) path.copyTo(destPath, REPLACE_EXISTING)
} }
} }
} }

View File

@ -11,6 +11,7 @@
package net.corda.demobench.model package net.corda.demobench.model
import com.typesafe.config.Config import com.typesafe.config.Config
import net.corda.core.internal.deleteRecursively
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.internal.config.parseAs import net.corda.nodeapi.internal.config.parseAs
@ -47,6 +48,6 @@ class InstallConfig internal constructor(val baseDir: Path, private val config:
val key = config.key val key = config.key
override val cordappsDir: Path = baseDir / "cordapps" override val cordappsDir: Path = baseDir / "cordapps"
fun deleteBaseDir(): Boolean = baseDir.toFile().deleteRecursively() fun deleteBaseDir(): Unit = baseDir.deleteRecursively()
fun installTo(installDir: Path) = config.copy(baseDir = installDir) fun installTo(installDir: Path) = config.copy(baseDir = installDir)
} }

View File

@ -13,9 +13,10 @@ package net.corda.demobench.model
import javafx.scene.control.Alert import javafx.scene.control.Alert
import javafx.scene.control.Alert.AlertType.ERROR import javafx.scene.control.Alert.AlertType.ERROR
import javafx.stage.Stage import javafx.stage.Stage
import net.corda.core.internal.exists
import tornadofx.*
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import tornadofx.*
class JVMConfig : Controller() { class JVMConfig : Controller() {
@ -45,17 +46,17 @@ class JVMConfig : Controller() {
typealias atRuntime = (Path, String) -> Unit typealias atRuntime = (Path, String) -> Unit
fun checkExists(path: Path, header: String) { fun checkExists(path: Path, header: String) {
if (!path.toFile().exists()) { if (path.exists()) return
val alert = Alert(ERROR)
alert.isResizable = true
alert.headerText = header
alert.contentText = "'$path' does not exist.\n" +
"Please install all of DemoBench's runtime dependencies or run the installer. " +
"See the documentation for more details."
val stage = alert.dialogPane.scene.window as Stage val alert = Alert(ERROR)
stage.isAlwaysOnTop = true alert.isResizable = true
alert.headerText = header
alert.contentText = "'$path' does not exist.\n" +
"Please install all of DemoBench's runtime dependencies or run the installer. " +
"See the documentation for more details."
alert.show() val stage = alert.dialogPane.scene.window as Stage
} stage.isAlwaysOnTop = true
alert.show()
} }

View File

@ -13,10 +13,7 @@ package net.corda.demobench.model
import javafx.beans.binding.IntegerExpression import javafx.beans.binding.IntegerExpression
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.internal.copyToDirectory import net.corda.core.internal.*
import net.corda.core.internal.createDirectories
import net.corda.core.internal.div
import net.corda.core.internal.noneOrSingle
import net.corda.core.node.NetworkParameters import net.corda.core.node.NetworkParameters
import net.corda.core.node.NotaryInfo import net.corda.core.node.NotaryInfo
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
@ -27,7 +24,6 @@ import net.corda.nodeapi.internal.network.NetworkParametersCopier
import tornadofx.* import tornadofx.*
import java.io.IOException import java.io.IOException
import java.lang.management.ManagementFactory import java.lang.management.ManagementFactory
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.time.Instant import java.time.Instant
@ -131,11 +127,11 @@ class NodeController(check: atRuntime = ::checkExists) : Controller() {
// Write this node's configuration file into its working directory. // Write this node's configuration file into its working directory.
val confFile = config.nodeDir / "node.conf" val confFile = config.nodeDir / "node.conf"
Files.write(confFile, config.nodeConfig.toNodeConfText().toByteArray()) confFile.writeText(config.nodeConfig.toNodeConfText())
// Write this node's configuration file into its working directory. // Write this node's configuration file into its working directory.
val webConfFile = config.nodeDir / "web-server.conf" val webConfFile = config.nodeDir / "web-server.conf"
Files.write(webConfFile, config.nodeConfig.toWebServerConfText().toByteArray()) webConfFile.writeText(config.nodeConfig.toWebServerConfText())
// Execute the Corda node // Execute the Corda node
val cordaEnv = System.getenv().toMutableMap().apply { val cordaEnv = System.getenv().toMutableMap().apply {
@ -210,9 +206,7 @@ class NodeController(check: atRuntime = ::checkExists) : Controller() {
log.info("Installed: $plugin") log.info("Installed: $plugin")
} }
if (!config.deleteBaseDir()) { config.deleteBaseDir()
log.warning("Failed to remove '${config.baseDir}'")
}
return installed return installed
} }

View File

@ -10,19 +10,16 @@
package net.corda.demobench.plugin package net.corda.demobench.plugin
import net.corda.core.internal.copyToDirectory import net.corda.core.internal.*
import net.corda.core.internal.createDirectories
import net.corda.core.internal.exists
import net.corda.demobench.model.HasCordapps import net.corda.demobench.model.HasCordapps
import net.corda.demobench.model.JVMConfig import net.corda.demobench.model.JVMConfig
import net.corda.demobench.model.NodeConfig import net.corda.demobench.model.NodeConfig
import net.corda.demobench.model.NodeConfigWrapper import net.corda.demobench.model.NodeConfigWrapper
import tornadofx.* import tornadofx.*
import java.io.IOException import java.io.IOException
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.StandardCopyOption import java.nio.file.StandardCopyOption
import java.util.stream.Stream import kotlin.streams.toList
class CordappController : Controller() { class CordappController : Controller() {
@ -54,18 +51,16 @@ class CordappController : Controller() {
* Generates a stream of a node's non-built-in cordapps. * Generates a stream of a node's non-built-in cordapps.
*/ */
@Throws(IOException::class) @Throws(IOException::class)
fun useCordappsFor(config: HasCordapps): Stream<Path> = walkCordapps(config.cordappsDir) fun useCordappsFor(config: HasCordapps): List<Path> {
.filter { !bankOfCorda.endsWith(it.fileName) } if (!config.cordappsDir.isDirectory()) return emptyList()
.filter { !finance.endsWith(it.fileName) } return config.cordappsDir.walk(1) { paths -> paths
.filter(Path::isCordapp)
private fun walkCordapps(cordappsDir: Path): Stream<Path> { .filter { !bankOfCorda.endsWith(it.fileName) }
return if (Files.isDirectory(cordappsDir)) .filter { !finance.endsWith(it.fileName) }
Files.walk(cordappsDir, 1).filter(Path::isCordapp) .toList()
else }
Stream.empty()
} }
} }
fun Path.isCordapp(): Boolean = Files.isReadable(this) && this.fileName.toString().endsWith(".jar") fun Path.isCordapp(): Boolean = this.isReadable && this.fileName.toString().endsWith(".jar")
fun Path.inCordappsDir(): Boolean = (this.parent != null) && this.parent.endsWith("cordapps/") fun Path.inCordappsDir(): Boolean = (this.parent != null) && this.parent.endsWith("cordapps/")

View File

@ -14,8 +14,7 @@ import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import javafx.stage.FileChooser import javafx.stage.FileChooser
import javafx.stage.FileChooser.ExtensionFilter import javafx.stage.FileChooser.ExtensionFilter
import net.corda.core.internal.createDirectories import net.corda.core.internal.*
import net.corda.core.internal.div
import net.corda.demobench.model.* import net.corda.demobench.model.*
import net.corda.demobench.plugin.CordappController import net.corda.demobench.plugin.CordappController
import net.corda.demobench.plugin.inCordappsDir import net.corda.demobench.plugin.inCordappsDir
@ -24,7 +23,6 @@ import tornadofx.*
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.net.URI import java.net.URI
import java.nio.charset.StandardCharsets.UTF_8
import java.nio.file.FileSystems import java.nio.file.FileSystems
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
@ -68,13 +66,13 @@ class ProfileController : Controller() {
configs.forEach { config -> configs.forEach { config ->
// Write the configuration file. // Write the configuration file.
val nodeDir = fs.getPath(config.key).createDirectories() val nodeDir = fs.getPath(config.key).createDirectories()
val file = Files.write(nodeDir / "node.conf", config.nodeConfig.serialiseAsString().toByteArray(UTF_8)) val file = (nodeDir / "node.conf").writeText(config.nodeConfig.serialiseAsString())
log.info("Wrote: $file") log.info("Wrote: $file")
// Write all of the non-built-in cordapps. // Write all of the non-built-in cordapps.
val cordappDir = Files.createDirectory(nodeDir.resolve(NodeConfig.cordappDirName)) val cordappDir = (nodeDir / NodeConfig.cordappDirName).createDirectory()
cordappController.useCordappsFor(config).forEach { cordappController.useCordappsFor(config).forEach {
val cordapp = Files.copy(it, cordappDir.resolve(it.fileName.toString())) val cordapp = it.copyToDirectory(cordappDir)
log.info("Wrote: $cordapp") log.info("Wrote: $cordapp")
} }
} }
@ -132,8 +130,8 @@ class ProfileController : Controller() {
val config = nodeIndex[cordapp.getName(0).toString()] ?: return@forEach val config = nodeIndex[cordapp.getName(0).toString()] ?: return@forEach
try { try {
val cordappDir = Files.createDirectories(config.cordappsDir) val cordappDir = config.cordappsDir.createDirectories()
Files.copy(cordapp, cordappDir.resolve(cordapp.fileName.toString())) cordapp.copyToDirectory(cordappDir)
log.info("Loaded: $cordapp") log.info("Loaded: $cordapp")
} catch (e: Exception) { } catch (e: Exception) {
log.log(Level.SEVERE, "Failed to extract '$cordapp': ${e.message}", e) log.log(Level.SEVERE, "Failed to extract '$cordapp': ${e.message}", e)
@ -146,8 +144,5 @@ class ProfileController : Controller() {
return configs return configs
} }
private fun parse(path: Path): Config = Files.newBufferedReader(path).use { private fun parse(path: Path): Config = path.reader().use { ConfigFactory.parseReader(it) }
return ConfigFactory.parseReader(it)
}
} }

View File

@ -13,6 +13,7 @@ package net.corda.demobench.web
import com.google.common.util.concurrent.RateLimiter import com.google.common.util.concurrent.RateLimiter
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.internal.concurrent.openFuture import net.corda.core.internal.concurrent.openFuture
import net.corda.core.internal.isDirectory
import net.corda.core.internal.until import net.corda.core.internal.until
import net.corda.core.utilities.contextLogger import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.minutes import net.corda.core.utilities.minutes
@ -36,17 +37,17 @@ class WebServer internal constructor(private val webServerController: WebServerC
@Throws(IOException::class) @Throws(IOException::class)
fun open(config: NodeConfigWrapper): CordaFuture<URI> { fun open(config: NodeConfigWrapper): CordaFuture<URI> {
val nodeDir = config.nodeDir.toFile() val nodeDir = config.nodeDir
if (!nodeDir.isDirectory) { if (!nodeDir.isDirectory()) {
log.warn("Working directory '{}' does not exist.", nodeDir.absolutePath) log.warn("Working directory '{}' does not exist.", nodeDir.toAbsolutePath())
return openFuture() return openFuture()
} }
val legalName = config.nodeConfig.myLegalName val legalName = config.nodeConfig.myLegalName
try { try {
val p = webServerController.process() val p = webServerController.process()
.directory(nodeDir) .directory(nodeDir.toFile())
.start() .start()
process = p process = p

View File

@ -11,30 +11,28 @@
package net.corda.demobench.model package net.corda.demobench.model
import com.jediterm.terminal.ui.UIUtil import com.jediterm.terminal.ui.UIUtil
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test import org.junit.Test
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue
class JVMConfigTest { class JVMConfigTest {
private val jvm = JVMConfig() private val jvm = JVMConfig()
@Test @Test
fun `test Java path`() { fun `test Java path`() {
assertTrue(Files.isExecutable(jvm.javaPath.onFileSystem())) assertThat(jvm.javaPath.onFileSystem()).isExecutable()
} }
@Test @Test
fun `test application directory`() { fun `test application directory`() {
assertTrue(Files.isDirectory(jvm.applicationDir)) assertThat(jvm.applicationDir).isDirectory()
} }
@Test @Test
fun `test user home`() { fun `test user home`() {
assertTrue(Files.isDirectory(jvm.userHome)) assertThat(jvm.userHome).isDirectory()
} }
@Test @Test
@ -51,8 +49,5 @@ class JVMConfigTest {
assertEquals(listOf(java.toString(), "-jar", "testapp.jar", "arg1", "arg2", "arg3"), process.command()) assertEquals(listOf(java.toString(), "-jar", "testapp.jar", "arg1", "arg2", "arg3"), process.command())
} }
private fun Path.onFileSystem(): Path private fun Path.onFileSystem(): Path = if (UIUtil.isWindows) parent.resolve(Paths.get("$fileName.exe")) else this
= if (UIUtil.isWindows) this.parent.resolve(Paths.get(this.fileName.toString() + ".exe"))
else this
} }

View File

@ -14,12 +14,8 @@ import javafx.beans.InvalidationListener
import javafx.beans.Observable import javafx.beans.Observable
import javafx.beans.property.ObjectProperty import javafx.beans.property.ObjectProperty
import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleObjectProperty
import net.corda.core.internal.createDirectories import net.corda.core.internal.*
import net.corda.core.internal.div
import net.corda.core.internal.exists
import net.corda.core.internal.uncheckedCast
import tornadofx.* import tornadofx.*
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import java.util.* import java.util.*
@ -56,12 +52,12 @@ class SettingsModel(path: Path = Paths.get("conf")) : Component(), Observable {
// Load config from properties file. // Load config from properties file.
fun load() = config.apply { fun load() = config.apply {
clear() clear()
if (Files.exists(path)) Files.newInputStream(path).use { load(it) } if (path.exists()) path.read { load(it) }
listeners.forEach { it.invalidated(this@SettingsModel) } listeners.forEach { it.invalidated(this@SettingsModel) }
} }
// Save all changes in memory to properties file. // Save all changes in memory to properties file.
fun commit() = Files.newOutputStream(path).use { config.store(it, "") } fun commit() = path.write { config.store(it, "") }
private operator fun <T> Properties.getValue(receiver: Any, metadata: KProperty<*>): T { private operator fun <T> Properties.getValue(receiver: Any, metadata: KProperty<*>): T {
return when (metadata.returnType.javaType) { return when (metadata.returnType.javaType) {

View File

@ -11,10 +11,10 @@
package net.corda.explorer.model package net.corda.explorer.model
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.exists
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.TemporaryFolder import org.junit.rules.TemporaryFolder
import java.nio.file.Files
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
@ -36,9 +36,9 @@ class SettingsModelTest {
setting.portProperty.value = "100" setting.portProperty.value = "100"
assertEquals("host", setting.hostProperty.value) assertEquals("host", setting.hostProperty.value)
assertEquals("100", setting.portProperty.value) assertEquals("100", setting.portProperty.value)
assertFalse(Files.exists(config)) assertFalse(config.exists())
setting.commit() setting.commit()
assertTrue(Files.exists(config)) assertTrue(config.exists())
setting.hostProperty.value = "host2" setting.hostProperty.value = "host2"
setting.portProperty.value = "200" setting.portProperty.value = "200"
assertEquals("host2", setting.hostProperty.value) assertEquals("host2", setting.hostProperty.value)

View File

@ -118,7 +118,7 @@ object InteractiveShell {
config["crash.auth"] = "corda" config["crash.auth"] = "corda"
configuration.sshHostKeyDirectory?.apply { configuration.sshHostKeyDirectory?.apply {
val sshKeysDir = configuration.sshHostKeyDirectory val sshKeysDir = configuration.sshHostKeyDirectory
sshKeysDir.toFile().mkdirs() sshKeysDir.createDirectories()
config["crash.ssh.keypath"] = (sshKeysDir / "hostkey.pem").toString() config["crash.ssh.keypath"] = (sshKeysDir / "hostkey.pem").toString()
config["crash.ssh.keygen"] = "true" config["crash.ssh.keygen"] = "true"
} }

View File

@ -9,11 +9,11 @@ import com.fasterxml.jackson.databind.SerializerProvider
import com.google.common.io.Closeables import com.google.common.io.Closeables
import net.corda.core.contracts.UniqueIdentifier import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.internal.copyTo import net.corda.core.internal.copyTo
import net.corda.core.internal.inputStream
import org.crsh.command.InvocationContext import org.crsh.command.InvocationContext
import rx.Observable import rx.Observable
import java.io.BufferedInputStream import java.io.BufferedInputStream
import java.io.InputStream import java.io.InputStream
import java.nio.file.Files
import java.nio.file.Paths import java.nio.file.Paths
import java.util.* import java.util.*
@ -85,7 +85,7 @@ object InputStreamDeserializer : JsonDeserializer<InputStream>() {
private val streams = Collections.synchronizedSet(HashSet<InputStream>()) private val streams = Collections.synchronizedSet(HashSet<InputStream>())
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): InputStream { override fun deserialize(p: JsonParser, ctxt: DeserializationContext): InputStream {
val stream = object : BufferedInputStream(Files.newInputStream(Paths.get(p.text))) { val stream = object : BufferedInputStream(Paths.get(p.text).inputStream()) {
override fun close() { override fun close() {
super.close() super.close()
streams.remove(this) streams.remove(this)

View File

@ -10,20 +10,19 @@
package net.corda.tools.shell package net.corda.tools.shell
import net.corda.core.internal.toPath
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test import org.junit.Test
import org.slf4j.event.Level import org.slf4j.event.Level
import java.nio.file.Paths import java.nio.file.Paths
import kotlin.test.assertEquals import kotlin.test.assertEquals
import java.io.File
class StandaloneShellArgsParserTest { class StandaloneShellArgsParserTest {
private val CONFIG_FILE = StandaloneShellArgsParserTest::class.java.getResource("/config.conf").toPath()
private val CONFIG_FILE = File(StandaloneShellArgsParserTest::class.java.getResource("/config.conf").toURI())
@Test @Test
fun args_to_cmd_options() { fun args_to_cmd_options() {
val args = arrayOf("--config-file", "/x/y/z/config.conf", val args = arrayOf("--config-file", "/x/y/z/config.conf",
"--commands-directory", "/x/y/commands", "--commands-directory", "/x/y/commands",
"--cordpass-directory", "/x/y/cordapps", "--cordpass-directory", "/x/y/cordapps",
@ -42,7 +41,8 @@ class StandaloneShellArgsParserTest {
"--truststore-type", "dummy", "--truststore-type", "dummy",
"--keystore-type", "JKS") "--keystore-type", "JKS")
val expectedOptions = CommandLineOptions(configFile = "/x/y/z/config.conf", val expectedOptions = CommandLineOptions(
configFile = "/x/y/z/config.conf",
commandsDirectory = Paths.get("/x/y/commands").normalize().toAbsolutePath(), commandsDirectory = Paths.get("/x/y/commands").normalize().toAbsolutePath(),
cordappsDirectory = Paths.get("/x/y/cordapps").normalize().toAbsolutePath(), cordappsDirectory = Paths.get("/x/y/cordapps").normalize().toAbsolutePath(),
host = "alocalhost", host = "alocalhost",
@ -62,7 +62,7 @@ class StandaloneShellArgsParserTest {
val options = CommandLineOptionParser().parse(*args) val options = CommandLineOptionParser().parse(*args)
assertEquals(expectedOptions, options) assertThat(options).isEqualTo(expectedOptions)
} }
@Test @Test
@ -137,7 +137,7 @@ class StandaloneShellArgsParserTest {
@Test @Test
fun cmd_options_to_config_from_file() { fun cmd_options_to_config_from_file() {
val options = CommandLineOptions(configFile = CONFIG_FILE.absolutePath, val options = CommandLineOptions(configFile = CONFIG_FILE.toString(),
commandsDirectory = null, commandsDirectory = null,
cordappsDirectory = null, cordappsDirectory = null,
host = null, host = null,
@ -176,7 +176,7 @@ class StandaloneShellArgsParserTest {
@Test @Test
fun cmd_options_override_config_from_file() { fun cmd_options_override_config_from_file() {
val options = CommandLineOptions(configFile = CONFIG_FILE.absolutePath, val options = CommandLineOptions(configFile = CONFIG_FILE.toString(),
commandsDirectory = null, commandsDirectory = null,
cordappsDirectory = null, cordappsDirectory = null,
host = null, host = null,