diff --git a/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt b/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt index 9943a9f750..4325f0f9ba 100644 --- a/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt +++ b/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt @@ -44,13 +44,13 @@ import java.lang.reflect.Field import java.math.BigDecimal import java.net.HttpURLConnection import java.net.HttpURLConnection.HTTP_OK +import java.net.URI import java.net.URL import java.nio.ByteBuffer -import java.nio.charset.Charset -import java.nio.charset.StandardCharsets.UTF_8 -import java.nio.file.* -import java.nio.file.attribute.FileAttribute -import java.nio.file.attribute.FileTime +import java.nio.file.CopyOption +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths import java.security.KeyPair import java.security.PrivateKey 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.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 * if more than one element was found. @@ -130,43 +122,6 @@ fun List.indexOfOrThrow(item: T): Int { 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 Path.list(block: (Stream) -> 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 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 Path.readLines(charset: Charset = UTF_8, block: (Stream) -> R): R = Files.lines(this, charset).use(block) -fun Path.readAllLines(charset: Charset = UTF_8): List = Files.readAllLines(this, charset) -fun Path.writeLines(lines: Iterable, charset: Charset = UTF_8, vararg options: OpenOption): Path = Files.write(this, lines, charset, *options) - -inline fun 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) /** 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. */ 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.post(serializedData: OpaqueBytes, vararg properties: Pair): ByteArray { diff --git a/core/src/main/kotlin/net/corda/core/internal/PathUtils.kt b/core/src/main/kotlin/net/corda/core/internal/PathUtils.kt new file mode 100644 index 0000000000..2b60d96ff1 --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/internal/PathUtils.kt @@ -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 Path.list(block: (Stream) -> R): R = Files.list(this).use(block) + +/** Same as [list] but materialises all the entiries into a list. */ +fun Path.list(): List = list { it.toList() } + +/** @see Files.walk */ +inline fun Path.walk(maxDepth: Int = Int.MAX_VALUE, vararg options: FileVisitOption, block: (Stream) -> 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() { + 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 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 Path.readLines(charset: Charset = UTF_8, block: (Stream) -> R): R { + return Files.lines(this, charset).use(block) +} + +/** @see Files.readAllLines */ +fun Path.readAllLines(charset: Charset = UTF_8): List = Files.readAllLines(this, charset) + +fun Path.writeLines(lines: Iterable, 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 Path.readObject(): T = readAll().deserialize() + +/** Calculate the hash of the contents of this file. */ +inline val Path.hash: SecureHash get() = read { it.hash() } diff --git a/core/src/main/kotlin/net/corda/core/internal/cordapp/CordappImpl.kt b/core/src/main/kotlin/net/corda/core/internal/cordapp/CordappImpl.kt index 6ced80419e..a6360147a9 100644 --- a/core/src/main/kotlin/net/corda/core/internal/cordapp/CordappImpl.kt +++ b/core/src/main/kotlin/net/corda/core/internal/cordapp/CordappImpl.kt @@ -12,11 +12,11 @@ package net.corda.core.internal.cordapp import net.corda.core.cordapp.Cordapp import net.corda.core.flows.FlowLogic +import net.corda.core.internal.toPath import net.corda.core.schemas.MappedSchema import net.corda.core.serialization.SerializationCustomSerializer import net.corda.core.serialization.SerializationWhitelist import net.corda.core.serialization.SerializeAsToken -import java.io.File import java.net.URL data class CordappImpl( @@ -30,7 +30,7 @@ data class CordappImpl( override val serializationCustomSerializers: List>, override val customSchemas: Set, 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 diff --git a/core/src/test/kotlin/net/corda/core/internal/AbstractAttachmentTest.kt b/core/src/test/kotlin/net/corda/core/internal/AbstractAttachmentTest.kt index c83cb94899..84cdec6a5a 100644 --- a/core/src/test/kotlin/net/corda/core/internal/AbstractAttachmentTest.kt +++ b/core/src/test/kotlin/net/corda/core/internal/AbstractAttachmentTest.kt @@ -12,13 +12,16 @@ package net.corda.core.internal import net.corda.testing.core.ALICE_NAME import net.corda.testing.core.BOB_NAME +import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy import org.junit.After import org.junit.AfterClass import org.junit.BeforeClass import org.junit.Test import java.nio.file.Files +import java.nio.file.Path import java.nio.file.Paths +import kotlin.streams.toList import kotlin.test.assertEquals class AbstractAttachmentTest { @@ -46,23 +49,23 @@ class AbstractAttachmentTest { (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() } @AfterClass @JvmStatic fun afterClass() { - dir.toFile().deleteRecursively() + dir.deleteRecursively() } } @After fun tearDown() { - dir.toFile().listFiles().forEach { - if (!it.name.startsWith("_")) it.deleteRecursively() + dir.list { + it.filter { !it.fileName.toString().startsWith("_") }.forEach(Path::deleteRecursively) } - assertEquals(5, dir.toFile().listFiles().size) + assertThat(dir.list()).hasSize(5) } @Test diff --git a/core/src/test/kotlin/net/corda/core/internal/PathUtilsTest.kt b/core/src/test/kotlin/net/corda/core/internal/PathUtilsTest.kt new file mode 100644 index 0000000000..419739b7ac --- /dev/null +++ b/core/src/test/kotlin/net/corda/core/internal/PathUtilsTest.kt @@ -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() + } +} \ No newline at end of file diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/ExampleConfigTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/ExampleConfigTest.kt index 7c2f9f4a7a..216f00b20b 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/ExampleConfigTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/ExampleConfigTest.kt @@ -10,8 +10,8 @@ package net.corda.docs +import net.corda.core.internal.toPath import net.corda.node.services.config.ConfigHelper -import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.parseAsNodeConfiguration import org.junit.Test import java.nio.file.Path @@ -25,7 +25,7 @@ class ExampleConfigTest { configFilenames.forEach { println("Checking $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 config.javaClass.kotlin.declaredMemberProperties.forEach { member -> if (member.visibility == KVisibility.PUBLIC) { @@ -37,7 +37,7 @@ class ExampleConfigTest { @Test fun `example node_confs parses fine`() { - readAndCheckConfigurations( + readAndCheckConfigurations( "example-node.conf", "example-out-of-process-verifier-node.conf" ) { diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/Utilities.kt b/experimental/behave/src/main/kotlin/net/corda/behave/Utilities.kt index 612e0f64ce..1f689d5a96 100644 --- a/experimental/behave/src/main/kotlin/net/corda/behave/Utilities.kt +++ b/experimental/behave/src/main/kotlin/net/corda/behave/Utilities.kt @@ -13,6 +13,8 @@ package net.corda.behave import java.time.Duration import java.util.concurrent.CountDownLatch +// TODO Most of these are available in corda core + val Int.millisecond: Duration get() = Duration.ofMillis(this.toLong()) diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/file/FileUtilities.kt b/experimental/behave/src/main/kotlin/net/corda/behave/file/FileUtilities.kt index fb8e753eb2..81229690a4 100644 --- a/experimental/behave/src/main/kotlin/net/corda/behave/file/FileUtilities.kt +++ b/experimental/behave/src/main/kotlin/net/corda/behave/file/FileUtilities.kt @@ -10,15 +10,12 @@ package net.corda.behave.file -import java.io.File +import java.nio.file.Path +import java.nio.file.Paths -val currentDirectory: File - get() = File(System.getProperty("user.dir")) +val currentDirectory: Path + get() = Paths.get(System.getProperty("user.dir")) // location of Corda distributions and Drivers dependencies -val stagingRoot: File - get() = if (System.getProperty("STAGING_ROOT") != null) - File(System.getProperty("STAGING_ROOT")) - else currentDirectory - -operator fun File.div(relative: String): File = this.resolve(relative) +val stagingRoot: Path + get() = System.getProperty("STAGING_ROOT")?.let { Paths.get(it) } ?: currentDirectory diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/file/LogSource.kt b/experimental/behave/src/main/kotlin/net/corda/behave/file/LogSource.kt index 7f5e1f7cb0..9629984759 100644 --- a/experimental/behave/src/main/kotlin/net/corda/behave/file/LogSource.kt +++ b/experimental/behave/src/main/kotlin/net/corda/behave/file/LogSource.kt @@ -10,10 +10,13 @@ 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( - private val directory: File, + private val directory: Path, filePattern: String? = ".*\\.log", private val filePatternUsedForExclusion: Boolean = false ) { @@ -21,7 +24,7 @@ class LogSource( private val fileRegex = Regex(filePattern ?: ".*") data class MatchedLogContent( - val filename: File, + val filename: Path, val contents: String ) @@ -31,10 +34,12 @@ class LogSource( } else { null } - val logFiles = directory.listFiles({ file -> - (!filePatternUsedForExclusion && file.name.matches(fileRegex)) || - (filePatternUsedForExclusion && !file.name.matches(fileRegex)) - }) + val logFiles = directory.list { + it.filter { + (!filePatternUsedForExclusion && it.fileName.toString().matches(fileRegex)) || + (filePatternUsedForExclusion && !it.fileName.toString().matches(fileRegex)) + }.toList() + } val result = mutableListOf() for (file in logFiles) { val contents = file.readText() diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/logging/LogUtilities.kt b/experimental/behave/src/main/kotlin/net/corda/behave/logging/LogUtilities.kt index f922c805e2..0dc04f92e7 100644 --- a/experimental/behave/src/main/kotlin/net/corda/behave/logging/LogUtilities.kt +++ b/experimental/behave/src/main/kotlin/net/corda/behave/logging/LogUtilities.kt @@ -13,5 +13,7 @@ package net.corda.behave.logging import org.slf4j.Logger import org.slf4j.LoggerFactory +// TODO Already available in corda core + inline fun getLogger(): Logger = LoggerFactory.getLogger(T::class.java) diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt b/experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt index e08dae7df7..7be4843759 100644 --- a/experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt +++ b/experimental/behave/src/main/kotlin/net/corda/behave/network/Network.kt @@ -13,7 +13,6 @@ package net.corda.behave.network import net.corda.behave.database.DatabaseType import net.corda.behave.file.LogSource import net.corda.behave.file.currentDirectory -import net.corda.behave.file.div import net.corda.behave.file.stagingRoot import net.corda.behave.logging.getLogger 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.process.JarCommand import net.corda.core.CordaException +import net.corda.core.internal.* import org.apache.commons.io.FileUtils import java.io.Closeable -import java.io.File +import java.nio.file.Path import java.time.Duration import java.time.Instant -import java.time.ZoneId +import java.time.ZoneOffset.UTC import java.time.format.DateTimeFormatter import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit class Network private constructor( private val nodes: Map, - private val targetDirectory: File, + private val targetDirectory: Path, private val timeout: Duration = 2.minutes ) : Closeable, Iterable { @@ -47,7 +47,7 @@ class Network private constructor( private var hasError = false init { - FileUtils.forceMkdir(targetDirectory) + targetDirectory.createDirectories() } class Builder internal constructor( @@ -58,10 +58,10 @@ class Network private constructor( private val startTime = DateTimeFormatter .ofPattern("yyyyMMdd-HHmmss") - .withZone(ZoneId.of("UTC")) + .withZone(UTC) .format(Instant.now()) - private val directory = currentDirectory / "build/runs/$startTime" + private val directory = currentDirectory / "build" / "runs" / startTime fun addNode( name: String, @@ -102,12 +102,11 @@ class Network private constructor( } fun copyDatabaseDrivers() { - val driverDirectory = targetDirectory / "libs" + val driverDirectory = (targetDirectory / "libs").createDirectories() log.info("Copying database drivers from $stagingRoot/deps/drivers to $driverDirectory") - FileUtils.forceMkdir(driverDirectory) FileUtils.copyDirectory( - stagingRoot / "deps/drivers", - driverDirectory + (stagingRoot / "deps" / "drivers").toFile(), + driverDirectory.toFile() ) } @@ -160,7 +159,7 @@ class Network private constructor( error("Failed to bootstrap network") { val matches = LogSource(targetDirectory) .find(".*[Ee]xception.*") - .groupBy { it.filename.absolutePath } + .groupBy { it.filename.toAbsolutePath() } for (match in matches) { log.info("Log(${match.key}):\n${match.value.joinToString("\n") { it.contents }}") } @@ -174,30 +173,17 @@ class Network private constructor( try { if (!hasError || CLEANUP_ON_ERROR) { log.info("Cleaning up runtime ...") - FileUtils.deleteDirectory(targetDirectory) + targetDirectory.deleteRecursively() } else { log.info("Deleting temporary files, but retaining logs and config ...") - for (node in nodes.values.map { it.config.name }) { - val nodeFolder = targetDirectory / node - FileUtils.deleteDirectory(nodeFolder / "additional-node-infos") - FileUtils.deleteDirectory(nodeFolder / "artemis") - FileUtils.deleteDirectory(nodeFolder / "certificates") - 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) + for (node in nodes.values) { + val nodeDir = targetDirectory / node.config.name + nodeDir.list { paths -> paths + .filter { it.fileName.toString() !in setOf("logs", "node.conf") } + .forEach(Path::deleteRecursively) } } - FileUtils.deleteDirectory(targetDirectory / "libs") - FileUtils.deleteDirectory(targetDirectory / ".cache") + listOf("libs", ".cache").forEach { (targetDirectory / it).deleteRecursively() } } log.info("Network was shut down successfully") } catch (e: Exception) { diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/Distribution.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/Distribution.kt index a4913b0018..88e72478e0 100644 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/Distribution.kt +++ b/experimental/behave/src/main/kotlin/net/corda/behave/node/Distribution.kt @@ -10,13 +10,15 @@ package net.corda.behave.node -import net.corda.behave.file.div import net.corda.behave.file.stagingRoot import net.corda.behave.logging.getLogger import net.corda.behave.service.Service -import org.apache.commons.io.FileUtils -import java.io.File +import net.corda.core.internal.copyTo +import net.corda.core.internal.createDirectories +import net.corda.core.internal.div +import net.corda.core.internal.exists import java.net.URL +import java.nio.file.Path /** * Corda distribution. @@ -31,7 +33,7 @@ class Distribution private constructor( /** * 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. @@ -47,43 +49,39 @@ class Distribution private constructor( /** * 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. */ - val cordaJar: File = path / "corda.jar" + val cordaJar: Path = path / "corda.jar" /** * The path to available Cordapps for this distribution. */ - val cordappDirectory: File = path / "apps" + val cordappDirectory: Path = path / "apps" /** * 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. */ fun ensureAvailable() { - if (!cordaJar.exists()) { - if (url != null) { - try { - FileUtils.forceMkdirParent(cordaJar) - FileUtils.copyURLToFile(url, cordaJar) - } catch (e: Exception) { - if (e.message!!.contains("HTTP response code: 401")) { - log.warn("CORDA_ARTIFACTORY_USERNAME ${System.getenv("CORDA_ARTIFACTORY_USERNAME")}") - 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.") - } - else throw Exception("Invalid Corda version $version", e) - } - } else { - throw Exception("File not found $cordaJar") + if (cordaJar.exists()) return + val url = checkNotNull(url) { "File not found $cordaJar" } + try { + cordaJar.parent.createDirectories() + url.openStream().use { it.copyTo(cordaJar) } + } catch (e: Exception) { + if ("HTTP response code: 401" in e.message!!) { + log.warn("CORDA_ARTIFACTORY_USERNAME ${System.getenv("CORDA_ARTIFACTORY_USERNAME")}") + 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 e } } @@ -119,7 +117,7 @@ class Distribution private constructor( * @param version The version of the Corda distribution. * @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) distributions.add(distribution) return distribution diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt index c3db76d368..2a3f8b4bc6 100644 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt +++ b/experimental/behave/src/main/kotlin/net/corda/behave/node/Node.kt @@ -14,7 +14,6 @@ import net.corda.behave.database.DatabaseConnection import net.corda.behave.database.DatabaseType import net.corda.behave.file.LogSource import net.corda.behave.file.currentDirectory -import net.corda.behave.file.div import net.corda.behave.file.stagingRoot import net.corda.behave.logging.getLogger 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.client.rpc.CordaRPCClient 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.utilities.NetworkHostAndPort import org.apache.commons.io.FileUtils -import java.io.File import java.net.InetAddress +import java.nio.file.Path import java.time.Duration import java.util.concurrent.CountDownLatch @@ -40,7 +41,7 @@ import java.util.concurrent.CountDownLatch */ class Node( val config: Configuration, - private val rootDirectory: File = currentDirectory, + private val rootDirectory: Path = currentDirectory, private val settings: ServiceSettings = ServiceSettings() ) { @@ -229,10 +230,10 @@ class Node( private fun installApps() { val version = config.distribution.version - val appDirectory = stagingRoot / "deps/corda/$version/apps" + val appDirectory = stagingRoot / "deps" / "corda" / version / "apps" if (appDirectory.exists()) { 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 directory: File? = null + private var directory: Path? = null private var timeout = Duration.ofSeconds(60) @@ -307,7 +308,7 @@ class Node( return this } - fun withDirectory(newDirectory: File): Builder { + fun withDirectory(newDirectory: Path): Builder { directory = newDirectory return this } diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/Configuration.kt b/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/Configuration.kt index f54fd31a45..d0f37699c8 100644 --- a/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/Configuration.kt +++ b/experimental/behave/src/main/kotlin/net/corda/behave/node/configuration/Configuration.kt @@ -12,10 +12,10 @@ package net.corda.behave.node.configuration import net.corda.behave.database.DatabaseType import net.corda.behave.logging.getLogger -import net.corda.behave.node.* +import net.corda.behave.node.Distribution import net.corda.core.identity.CordaX500Name -import org.apache.commons.io.FileUtils -import java.io.File +import net.corda.core.internal.writeText +import java.nio.file.Path class Configuration( val name: String, @@ -53,8 +53,8 @@ class Configuration( private val extraConfig = (configElements.toList() + listOf(users, nodeInterface)) .joinToString(separator = "\n") { it.generate(this) } - fun writeToFile(file: File) { - FileUtils.writeStringToFile(file, this.generate(), "UTF-8") + fun writeToFile(file: Path) { + file.writeText(this.generate()) log.info(this.generate()) } @@ -64,7 +64,7 @@ class Configuration( companion object { private val log = getLogger() - val DEFAULT_PASSWORD = "S0meS3cretW0rd" + const val DEFAULT_PASSWORD = "S0meS3cretW0rd" } } diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/process/Command.kt b/experimental/behave/src/main/kotlin/net/corda/behave/process/Command.kt index 799cdaa480..b5af2a2796 100644 --- a/experimental/behave/src/main/kotlin/net/corda/behave/process/Command.kt +++ b/experimental/behave/src/main/kotlin/net/corda/behave/process/Command.kt @@ -17,14 +17,14 @@ import net.corda.behave.process.output.OutputListener import rx.Observable import rx.Subscriber import java.io.Closeable -import java.io.File import java.io.IOException +import java.nio.file.Path import java.time.Duration import java.util.concurrent.CountDownLatch open class Command( private val command: List, - private val directory: File = currentDirectory, + private val directory: Path = currentDirectory, private val timeout: Duration = 2.minutes ): Closeable { @@ -59,7 +59,7 @@ open class Command( try { log.info("Command: $command") val processBuilder = ProcessBuilder(command) - .directory(directory) + .directory(directory.toFile()) .redirectErrorStream(true) processBuilder.environment().putAll(System.getenv()) process = processBuilder.start() diff --git a/experimental/behave/src/main/kotlin/net/corda/behave/process/JarCommand.kt b/experimental/behave/src/main/kotlin/net/corda/behave/process/JarCommand.kt index 99f7141054..21b897ca85 100644 --- a/experimental/behave/src/main/kotlin/net/corda/behave/process/JarCommand.kt +++ b/experimental/behave/src/main/kotlin/net/corda/behave/process/JarCommand.kt @@ -11,12 +11,13 @@ package net.corda.behave.process import java.io.File +import java.nio.file.Path import java.time.Duration class JarCommand( - val jarFile: File, + jarFile: Path, arguments: Array, - directory: File, + directory: Path, timeout: Duration, enableRemoteDebugging: Boolean = false ) : Command( diff --git a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Startup.kt b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Startup.kt index 5ba3368fa5..8c09e86a00 100644 --- a/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Startup.kt +++ b/experimental/behave/src/scenario/kotlin/net/corda/behave/scenarios/helpers/Startup.kt @@ -10,11 +10,10 @@ package net.corda.behave.scenarios.helpers -import net.corda.behave.file.div import net.corda.behave.minutes import net.corda.behave.process.JarCommand import net.corda.behave.scenarios.ScenarioState -import java.io.File +import net.corda.core.internal.div 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 // eg. Main-Class: net.corda.notaryhealthcheck.MainKt val cordappDirectory = node(nodeName).config.distribution.cordappDirectory - val cordappJar : File = cordappDirectory / "$cordapp.jar" + val cordappJar = cordappDirectory / "$cordapp.jar" // Execute val command = JarCommand(cordappJar, args as Array, cordappDirectory, 1.minutes) command.start() diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt index a410aa2d1c..88c049f0b6 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkBootstrapper.kt @@ -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.kryo.AbstractKryoSerializationScheme import net.corda.nodeapi.internal.serialization.kryo.kryoMagic -import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import java.nio.file.StandardCopyOption.REPLACE_EXISTING @@ -115,13 +114,13 @@ class NetworkBootstrapper { val cordappsDir = (nodeDir / "cordapps").createDirectories() cordappJars.forEach { it.copyToDirectory(cordappsDir) } } - Files.delete(cordaJar) + cordaJar.delete() } private fun extractCordaJarTo(directory: Path): Path { val cordaJarPath = directory / "corda.jar" if (!cordaJarPath.exists()) { - Thread.currentThread().contextClassLoader.getResourceAsStream("corda.jar").copyTo(cordaJarPath) + Thread.currentThread().contextClassLoader.getResourceAsStream("corda.jar").use { it.copyTo(cordaJarPath) } } return cordaJarPath } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopier.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopier.kt index 6981b4e1f7..628ffdd578 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopier.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopier.kt @@ -11,10 +11,7 @@ package net.corda.nodeapi.internal.network import net.corda.cordform.CordformNode -import net.corda.core.internal.ThreadBox -import net.corda.core.internal.createDirectories -import net.corda.core.internal.isRegularFile -import net.corda.core.internal.list +import net.corda.core.internal.* import net.corda.core.utilities.contextLogger import rx.Observable import rx.Scheduler @@ -25,7 +22,6 @@ import java.nio.file.Files import java.nio.file.Path import java.nio.file.StandardCopyOption.COPY_ATTRIBUTES import java.nio.file.StandardCopyOption.REPLACE_EXISTING -import java.nio.file.attribute.BasicFileAttributes import java.nio.file.attribute.FileTime import java.util.concurrent.TimeUnit @@ -110,10 +106,10 @@ class NodeInfoFilesCopier(scheduler: Scheduler = Schedulers.io()) : AutoCloseabl private fun poll() { nodeDataMapBox.locked { for (nodeData in values) { - nodeData.nodeDir.list { paths -> - paths.filter { it.isRegularFile() } - .filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) } - .forEach { path -> processPath(nodeData, path) } + nodeData.nodeDir.list { paths -> paths + .filter { it.isRegularFile() } + .filter { it.fileName.toString().startsWith(NODE_INFO_FILE_NAME_PREFIX) } + .forEach { processPath(nodeData, it) } } } } @@ -123,7 +119,7 @@ class NodeInfoFilesCopier(scheduler: Scheduler = Schedulers.io()) : AutoCloseabl // be copied. private fun processPath(nodeData: NodeData, path: Path) { 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) if (newTimestamp > previousTimestamp) { 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 { // 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) { log.warn("Couldn't copy $source to $tempDestination.", exception) - Files.delete(tempDestination) + tempDestination.delete() throw exception } try { // 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) { log.warn("Couldn't move $tempDestination to $destination.", exception) - Files.delete(tempDestination) + tempDestination.delete() throw exception } } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolver.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolver.kt index 78ff72a88d..b531fce895 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolver.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolver.kt @@ -16,6 +16,7 @@ import com.esotericsoftware.kryo.io.Output import com.esotericsoftware.kryo.serializers.FieldSerializer import com.esotericsoftware.kryo.util.DefaultClassResolver import com.esotericsoftware.kryo.util.Util +import net.corda.core.internal.writer import net.corda.core.serialization.ClassWhitelist import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SerializationContext @@ -26,10 +27,9 @@ import net.corda.nodeapi.internal.serialization.kryo.ThrowableSerializer import java.io.PrintWriter import java.lang.reflect.Modifier import java.lang.reflect.Modifier.isAbstract -import java.nio.charset.StandardCharsets -import java.nio.file.Files +import java.nio.charset.StandardCharsets.UTF_8 import java.nio.file.Paths -import java.nio.file.StandardOpenOption +import java.nio.file.StandardOpenOption.* import java.util.* /** @@ -216,7 +216,7 @@ class LoggingWhitelist(val delegate: ClassWhitelist, val global: Boolean = true) val fileName = System.getenv("WHITELIST_FILE") if (fileName != null && fileName.isNotEmpty()) { 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) { log.error("Could not open/create whitelist journal file for append: $fileName", ioEx) } diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopierTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopierTest.kt index c0c1b38b98..d5b75d227b 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopierTest.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/network/NodeInfoFilesCopierTest.kt @@ -11,18 +11,20 @@ package net.corda.nodeapi.internal.network 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 org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder import rx.schedulers.TestScheduler -import java.nio.file.Files import java.nio.file.Path import java.time.Duration import java.util.concurrent.TimeUnit import kotlin.streams.toList -import kotlin.test.assertEquals class NodeInfoFilesCopierTest { companion object { @@ -31,9 +33,9 @@ class NodeInfoFilesCopierTest { private const val NODE_2_PATH = "node2" private val content = "blah".toByteArray(Charsets.UTF_8) - private 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 val BAD_NODE_INFO_NAME = "something" + private const val GOOD_NODE_INFO_NAME = "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}test" + private const val GOOD_NODE_INFO_NAME_2 = "${NodeInfoFilesCopier.NODE_INFO_FILE_NAME_PREFIX}anotherNode" + private const val BAD_NODE_INFO_NAME = "something" } @Rule @@ -65,8 +67,8 @@ class NodeInfoFilesCopierTest { advanceTime() // Create 2 files, a nodeInfo and another file in node1 folder. - Files.write(node1RootPath.resolve(GOOD_NODE_INFO_NAME), content) - Files.write(node1RootPath.resolve(BAD_NODE_INFO_NAME), content) + (node1RootPath / GOOD_NODE_INFO_NAME).write(content) + (node1RootPath / BAD_NODE_INFO_NAME).write(content) // Configure the second node. nodeInfoFilesCopier.addConfig(node2RootPath) @@ -86,8 +88,8 @@ class NodeInfoFilesCopierTest { advanceTime() // Create 2 files, one of which to be copied, in a node root path. - Files.write(node2RootPath.resolve(GOOD_NODE_INFO_NAME), content) - Files.write(node2RootPath.resolve(BAD_NODE_INFO_NAME), content) + (node2RootPath / GOOD_NODE_INFO_NAME).write(content) + (node2RootPath / BAD_NODE_INFO_NAME).write(content) advanceTime() eventually(Duration.ofMinutes(1)) { @@ -104,14 +106,14 @@ class NodeInfoFilesCopierTest { advanceTime() // 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() // Remove node 2 nodeInfoFilesCopier.removeConfig(node2RootPath) // 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() eventually(Duration.ofMinutes(1)) { @@ -130,11 +132,11 @@ class NodeInfoFilesCopierTest { nodeInfoFilesCopier.reset() 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. Thread.sleep(100) - assertEquals(0, Files.list(node1AdditionalNodeInfoPath).toList().size) + assertThat(node1AdditionalNodeInfoPath.list()).isEmpty() } private fun advanceTime() { @@ -142,8 +144,8 @@ class NodeInfoFilesCopierTest { } private fun checkDirectoryContainsSingleFile(path: Path, filename: String) { - assertEquals(1, Files.list(path).toList().size) - val onlyFileName = Files.list(path).toList().first().fileName.toString() - assertEquals(filename, onlyFileName) + val files = path.list() + assertThat(files).hasSize(1) + assertThat(files[0].fileName.toString()).isEqualTo(filename) } } \ No newline at end of file diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolvabilityTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolvabilityTests.kt index 58b89ab7db..f547b546ac 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolvabilityTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolvabilityTests.kt @@ -14,8 +14,8 @@ import net.corda.core.serialization.* import net.corda.testing.common.internal.ProjectStructure.projectRootDir import org.assertj.core.api.Assertions import org.junit.Test -import java.io.File import java.io.NotSerializableException +import java.net.URI import java.util.* import java.util.concurrent.ConcurrentHashMap import kotlin.test.assertEquals @@ -23,11 +23,11 @@ import kotlin.test.assertTrue class EnumEvolvabilityTests { @Suppress("UNUSED") - var localPath = projectRootDir.toUri().resolve( + var localPath: URI = projectRootDir.toUri().resolve( "node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp") companion object { - val VERBOSE = false + const val VERBOSE = false } enum class NotAnnotated { @@ -442,8 +442,7 @@ class EnumEvolvabilityTests { //File(URI("$localPath/$resource")).writeBytes( // SerializationOutput(sf).serialize(WrapsUnknown(WithUnknownTest.D)).bytes) - val path = EvolvabilityTests::class.java.getResource(resource) - val sb1 = File(path.toURI()).readBytes() + val sb1 = EvolvabilityTests::class.java.getResource(resource).readBytes() val envelope = DeserializationInput(sf).deserializeAndReturnEnvelope(SerializedBytes(sb1)).envelope diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolveTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolveTests.kt index f4ecc1b2a2..efbec4bbf8 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolveTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolveTests.kt @@ -10,25 +10,25 @@ 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.CordaSerializationTransformEnumDefaults import net.corda.core.serialization.SerializedBytes 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 java.io.File import java.io.NotSerializableException +import java.net.URI import kotlin.test.assertEquals 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 // the new ones out, then change each test to write out the serialized bytes rather than read // the file. class EnumEvolveTests { @Suppress("UNUSED") - var localPath = projectRootDir.toUri().resolve( + var localPath: URI = projectRootDir.toUri().resolve( "node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp") // Version of the class as it was serialised @@ -50,9 +50,9 @@ class EnumEvolveTests { // File(URI("$localPath/$resource")).writeBytes( // 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(File(path.toURI()).readBytes())) + val obj = DeserializationInput(sf).deserialize(SerializedBytes(url.readBytes())) 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.E")).writeBytes(so.serialize(C(DeserializeNewerSetToUnknown2.E)).bytes) - val path1 = EvolvabilityTests::class.java.getResource("$resource.C") - val path2 = EvolvabilityTests::class.java.getResource("$resource.D") - val path3 = EvolvabilityTests::class.java.getResource("$resource.E") + val url1 = EvolvabilityTests::class.java.getResource("$resource.C") + val url2 = EvolvabilityTests::class.java.getResource("$resource.D") + val url3 = EvolvabilityTests::class.java.getResource("$resource.E") // C will just work - val obj1 = DeserializationInput(sf).deserialize(SerializedBytes(File(path1.toURI()).readBytes())) + val obj1 = DeserializationInput(sf).deserialize(SerializedBytes(url1.readBytes())) // D will transform directly to C - val obj2 = DeserializationInput(sf).deserialize(SerializedBytes(File(path2.toURI()).readBytes())) + val obj2 = DeserializationInput(sf).deserialize(SerializedBytes(url2.readBytes())) // E will have to transform from E -> D -> C to work, so this should exercise that part // of the evolution code - val obj3 = DeserializationInput(sf).deserialize(SerializedBytes(File(path3.toURI()).readBytes())) + val obj3 = DeserializationInput(sf).deserialize(SerializedBytes(url3.readBytes())) assertEquals(DeserializeNewerSetToUnknown2.C, obj1.e) assertEquals(DeserializeNewerSetToUnknown2.C, obj2.e) @@ -118,10 +118,10 @@ class EnumEvolveTests { // val so = SerializationOutput(sf) // 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 { - DeserializationInput(sf).deserialize(SerializedBytes(File(path.toURI()).readBytes())) + assertThatThrownBy { + DeserializationInput(sf).deserialize(SerializedBytes(url.readBytes())) }.isInstanceOf(NotSerializableException::class.java) } @@ -184,9 +184,9 @@ class EnumEvolveTests { val path1_B = EvolvabilityTests::class.java.getResource("$resource.1.B") val path1_C = EvolvabilityTests::class.java.getResource("$resource.1.C") - val obj1_AA = DeserializationInput(sf).deserialize(SerializedBytes(File(path1_AA.toURI()).readBytes())) - val obj1_B = DeserializationInput(sf).deserialize(SerializedBytes(File(path1_B.toURI()).readBytes())) - val obj1_C = DeserializationInput(sf).deserialize(SerializedBytes(File(path1_C.toURI()).readBytes())) + val obj1_AA = DeserializationInput(sf).deserialize(SerializedBytes(path1_AA.readBytes())) + val obj1_B = DeserializationInput(sf).deserialize(SerializedBytes(path1_B.readBytes())) + val obj1_C = DeserializationInput(sf).deserialize(SerializedBytes(path1_C.readBytes())) assertEquals(DeserializeWithRename.A, obj1_AA.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_C = EvolvabilityTests::class.java.getResource("$resource.2.C") - val obj2_AA = DeserializationInput(sf).deserialize(SerializedBytes(File(path2_AA.toURI()).readBytes())) - val obj2_BB = DeserializationInput(sf).deserialize(SerializedBytes(File(path2_BB.toURI()).readBytes())) - val obj2_C = DeserializationInput(sf).deserialize(SerializedBytes(File(path2_C.toURI()).readBytes())) + val obj2_AA = DeserializationInput(sf).deserialize(SerializedBytes(path2_AA.readBytes())) + val obj2_BB = DeserializationInput(sf).deserialize(SerializedBytes(path2_BB.readBytes())) + val obj2_C = DeserializationInput(sf).deserialize(SerializedBytes(path2_C.readBytes())) assertEquals(DeserializeWithRename.A, obj2_AA.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_C = EvolvabilityTests::class.java.getResource("$resource.3.C") - val obj3_AA = DeserializationInput(sf).deserialize(SerializedBytes(File(path3_AA.toURI()).readBytes())) - val obj3_XX = DeserializationInput(sf).deserialize(SerializedBytes(File(path3_XX.toURI()).readBytes())) - val obj3_C = DeserializationInput(sf).deserialize(SerializedBytes(File(path3_C.toURI()).readBytes())) + val obj3_AA = DeserializationInput(sf).deserialize(SerializedBytes(path3_AA.readBytes())) + val obj3_XX = DeserializationInput(sf).deserialize(SerializedBytes(path3_XX.readBytes())) + val obj3_C = DeserializationInput(sf).deserialize(SerializedBytes(path3_C.readBytes())) assertEquals(DeserializeWithRename.A, obj3_AA.e) assertEquals(DeserializeWithRename.B, obj3_XX.e) @@ -359,11 +359,11 @@ class EnumEvolveTests { Pair("$resource.5.G", MultiOperations.C)) fun load(l: List>) = l.map { - assertNotNull (EvolvabilityTests::class.java.getResource(it.first)) - assertTrue (File(EvolvabilityTests::class.java.getResource(it.first).toURI()).exists()) + assertNotNull(EvolvabilityTests::class.java.getResource(it.first)) + assertThat(EvolvabilityTests::class.java.getResource(it.first).toPath()).exists() Pair(DeserializationInput(sf).deserialize(SerializedBytes( - 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) } @@ -382,7 +382,7 @@ class EnumEvolveTests { data class C(val e: BadNewValue) - Assertions.assertThatThrownBy { + assertThatThrownBy { SerializationOutput(sf).serialize(C(BadNewValue.A)) }.isInstanceOf(NotSerializableException::class.java) } @@ -399,7 +399,7 @@ class EnumEvolveTests { data class C(val e: OutOfOrder) - Assertions.assertThatThrownBy { + assertThatThrownBy { SerializationOutput(sf).serialize(C(OutOfOrder.A)) }.isInstanceOf(NotSerializableException::class.java) } @@ -423,9 +423,9 @@ class EnumEvolveTests { // File(URI("$localPath/$resource")).writeBytes( // SerializationOutput(sf).serialize(C(ChangedOrdinality.A)).bytes) - Assertions.assertThatThrownBy { + assertThatThrownBy { DeserializationInput(sf).deserialize(SerializedBytes( - File(EvolvabilityTests::class.java.getResource(resource).toURI()).readBytes())) + EvolvabilityTests::class.java.getResource(resource).readBytes())) }.isInstanceOf(NotSerializableException::class.java) } } diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumTests.kt index c7b3b9481b..3e80e31d9b 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumTests.kt @@ -15,7 +15,6 @@ import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SerializedBytes import org.assertj.core.api.Assertions import org.junit.Test -import java.io.File import java.io.NotSerializableException import java.time.DayOfWeek import kotlin.test.assertEquals @@ -161,8 +160,7 @@ class EnumTests { @Test(expected = NotSerializableException::class) fun changedEnum1() { - val path = EnumTests::class.java.getResource("EnumTests.changedEnum1") - val f = File(path.toURI()) + val url = EnumTests::class.java.getResource("EnumTests.changedEnum1") data class C(val a: OldBras) @@ -173,7 +171,7 @@ class EnumTests { // f.writeBytes(sc.bytes) // println(path) - val sc2 = f.readBytes() + val sc2 = url.readBytes() // we expect this to throw DeserializationInput(sf1).deserialize(SerializedBytes(sc2)) @@ -181,8 +179,7 @@ class EnumTests { @Test(expected = NotSerializableException::class) fun changedEnum2() { - val path = EnumTests::class.java.getResource("EnumTests.changedEnum2") - val f = File(path.toURI()) + val url = EnumTests::class.java.getResource("EnumTests.changedEnum2") data class C(val a: OldBras2) @@ -196,7 +193,7 @@ class EnumTests { // f.writeBytes(sc.bytes) // println(path) - val sc2 = f.readBytes() + val sc2 = url.readBytes() // we expect this to throw DeserializationInput(sf1).deserialize(SerializedBytes(sc2)) diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EvolvabilityTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EvolvabilityTests.kt index 7af638b59f..bd5408b2f2 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EvolvabilityTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EvolvabilityTests.kt @@ -40,7 +40,7 @@ import kotlin.test.assertEquals class EvolvabilityTests { // When regenerating the test files this needs to be set to the file system location of the resource files @Suppress("UNUSED") - var localPath = projectRootDir.toUri().resolve( + var localPath: URI = projectRootDir.toUri().resolve( "node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp") @Test @@ -59,10 +59,8 @@ class EvolvabilityTests { // 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) - val path = EvolvabilityTests::class.java.getResource(resource) - val f = File(path.toURI()) - - val sc2 = f.readBytes() + val url = EvolvabilityTests::class.java.getResource(resource) + val sc2 = url.readBytes() val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) 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 data class C(val b: String, val a: Int) - val path = EvolvabilityTests::class.java.getResource(resource) - val f = File(path.toURI()) - val sc2 = f.readBytes() + val url = EvolvabilityTests::class.java.getResource(resource) + val sc2 = url.readBytes() val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) assertEquals(A, deserializedC.a) @@ -105,9 +102,8 @@ class EvolvabilityTests { data class C(val a: Int, val b: Int?) - val path = EvolvabilityTests::class.java.getResource(resource) - val f = File(path.toURI()) - val sc2 = f.readBytes() + val url = EvolvabilityTests::class.java.getResource(resource) + val sc2 = url.readBytes() val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) assertEquals(A, deserializedC.a) @@ -117,8 +113,7 @@ class EvolvabilityTests { @Test(expected = NotSerializableException::class) fun addAdditionalParam() { val sf = testDefaultFactory() - val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.addAdditionalParam") - val f = File(path.toURI()) + val url = EvolvabilityTests::class.java.getResource("EvolvabilityTests.addAdditionalParam") @Suppress("UNUSED_VARIABLE") val A = 1 @@ -132,7 +127,7 @@ class EvolvabilityTests { // new version of the class, in this case a new parameter has been added (b) 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 // 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) - val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.removeParameters") - val f = File(path.toURI()) - val sc2 = f.readBytes() + val url = EvolvabilityTests::class.java.getResource("EvolvabilityTests.removeParameters") + val sc2 = url.readBytes() val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) assertEquals(B, deserializedCC.b) @@ -183,9 +177,8 @@ class EvolvabilityTests { data class CC(val a: Int, val e: Boolean?, val d: Int) - val path = EvolvabilityTests::class.java.getResource(resource) - val f = File(path.toURI()) - val sc2 = f.readBytes() + val url = EvolvabilityTests::class.java.getResource(resource) + val sc2 = url.readBytes() val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) assertEquals(A, deserializedCC.a) @@ -209,9 +202,8 @@ class EvolvabilityTests { constructor (a: Int) : this(a, "hello") } - val path = EvolvabilityTests::class.java.getResource(resource) - val f = File(path.toURI()) - val sc2 = f.readBytes() + val url = EvolvabilityTests::class.java.getResource(resource) + val sc2 = url.readBytes() val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) assertEquals(A, deserializedCC.a) @@ -222,9 +214,8 @@ class EvolvabilityTests { @Suppress("UNUSED") fun addMandatoryFieldWithAltConstructorUnAnnotated() { val sf = testDefaultFactory() - val path = EvolvabilityTests::class.java.getResource( + val url = EvolvabilityTests::class.java.getResource( "EvolvabilityTests.addMandatoryFieldWithAltConstructorUnAnnotated") - val f = File(path.toURI()) @Suppress("UNUSED_VARIABLE") val A = 1 @@ -242,7 +233,7 @@ class EvolvabilityTests { // we expect this to throw as we should not find any constructors // capable of dealing with this - DeserializationInput(sf).deserialize(SerializedBytes(f.readBytes())) + DeserializationInput(sf).deserialize(SerializedBytes(url.readBytes())) } @Test @@ -265,9 +256,8 @@ class EvolvabilityTests { constructor (c: String, a: Int, b: Int) : this(a, b, c, "wibble") } - val path = EvolvabilityTests::class.java.getResource(resource) - val f = File(path.toURI()) - val sc2 = f.readBytes() + val url = EvolvabilityTests::class.java.getResource(resource) + val sc2 = url.readBytes() val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) assertEquals(A, deserializedCC.a) @@ -298,9 +288,8 @@ class EvolvabilityTests { constructor (c: String, a: Int) : this(a, c, "wibble") } - val path = EvolvabilityTests::class.java.getResource(resource) - val f = File(path.toURI()) - val sc2 = f.readBytes() + val url = EvolvabilityTests::class.java.getResource(resource) + val sc2 = url.readBytes() val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) 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) } - val path1 = EvolvabilityTests::class.java.getResource(resource1) - val path2 = EvolvabilityTests::class.java.getResource(resource2) - val path3 = EvolvabilityTests::class.java.getResource(resource3) + val url1 = EvolvabilityTests::class.java.getResource(resource1) + val url2 = EvolvabilityTests::class.java.getResource(resource2) + val url3 = EvolvabilityTests::class.java.getResource(resource3) - val sb1 = File(path1.toURI()).readBytes() + val sb1 = url1.readBytes() val db1 = DeserializationInput(sf).deserialize(SerializedBytes(sb1)) assertEquals(a, db1.a) @@ -358,7 +347,7 @@ class EvolvabilityTests { assertEquals(-1, db1.d) assertEquals(-1, db1.e) - val sb2 = File(path2.toURI()).readBytes() + val sb2 = url2.readBytes() val db2 = DeserializationInput(sf).deserialize(SerializedBytes(sb2)) assertEquals(a, db2.a) @@ -367,7 +356,7 @@ class EvolvabilityTests { assertEquals(-1, db2.d) assertEquals(-1, db2.e) - val sb3 = File(path3.toURI()).readBytes() + val sb3 = url3.readBytes() val db3 = DeserializationInput(sf).deserialize(SerializedBytes(sb3)) assertEquals(a, db3.a) @@ -394,9 +383,8 @@ class EvolvabilityTests { data class Outer(val a: Int, val b: Inner) - val path = EvolvabilityTests::class.java.getResource(resource) - val f = File(path.toURI()) - val sc2 = f.readBytes() + val url = EvolvabilityTests::class.java.getResource(resource) + val sc2 = url.readBytes() val outer = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) 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) } - val path1 = EvolvabilityTests::class.java.getResource(resource1) - val path2 = EvolvabilityTests::class.java.getResource(resource2) - val path3 = EvolvabilityTests::class.java.getResource(resource3) + val url1 = EvolvabilityTests::class.java.getResource(resource1) + val url2 = EvolvabilityTests::class.java.getResource(resource2) + val url3 = EvolvabilityTests::class.java.getResource(resource3) - val sb1 = File(path1.toURI()).readBytes() + val sb1 = url1.readBytes() val db1 = DeserializationInput(sf).deserialize(SerializedBytes(sb1)) assertEquals(b, db1.b) @@ -463,7 +451,7 @@ class EvolvabilityTests { assertEquals(-1, db1.f) assertEquals(-1, db1.g) - val sb2 = File(path2.toURI()).readBytes() + val sb2 = url2.readBytes() val db2 = DeserializationInput(sf).deserialize(SerializedBytes(sb2)) assertEquals(b, db2.b) @@ -473,7 +461,7 @@ class EvolvabilityTests { assertEquals(-1, db2.f) assertEquals(-1, db1.g) - val sb3 = File(path3.toURI()).readBytes() + val sb3 = url3.readBytes() val db3 = DeserializationInput(sf).deserialize(SerializedBytes(sb3)) assertEquals(b, db3.b) @@ -511,9 +499,8 @@ class EvolvabilityTests { // val resource = "networkParams.r3corda.6a6b6f256" - val path = EvolvabilityTests::class.java.getResource(resource) - val f = File(path.toURI()) - val sc2 = f.readBytes() + val url = EvolvabilityTests::class.java.getResource(resource) + val sc2 = url.readBytes() val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes>(sc2)) val networkParams = DeserializationInput(sf).deserialize(deserializedC.raw) @@ -548,7 +535,7 @@ class EvolvabilityTests { val signed = SignedData(serialized, sig) val signedAndSerialized = testOutput.serialize(signed) - File(URI("$localPath/$resource")).writeBytes( signedAndSerialized.bytes) + File(URI("$localPath/$resource")).writeBytes(signedAndSerialized.bytes) } @Suppress("UNCHECKED_CAST") @@ -581,10 +568,9 @@ class EvolvabilityTests { constructor() : this(0, 0, 0, 0) } - val path = EvolvabilityTests::class.java.getResource(resource) - val f = File(path.toURI()) + val url = EvolvabilityTests::class.java.getResource(resource) - val sc2 = f.readBytes() + val sc2 = url.readBytes() val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) assertEquals(1, deserializedC.a) diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/GenericsTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/GenericsTests.kt index 68b2b49534..84db597caa 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/GenericsTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/GenericsTests.kt @@ -277,7 +277,7 @@ class GenericsTests { assertEquals("wibble", DeserializationInput(sf).deserialize(SerializedBytes>( - 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) diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/StaticInitialisationOfSerializedObjectTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/StaticInitialisationOfSerializedObjectTest.kt index d8d1b8a424..f5ef970f1b 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/StaticInitialisationOfSerializedObjectTest.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/StaticInitialisationOfSerializedObjectTest.kt @@ -14,9 +14,8 @@ import net.corda.core.serialization.ClassWhitelist import net.corda.core.serialization.SerializedBytes import net.corda.nodeapi.internal.serialization.AllWhitelist 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 java.io.File import java.io.NotSerializableException import java.lang.reflect.Type import java.util.concurrent.ConcurrentHashMap @@ -83,8 +82,7 @@ class StaticInitialisationOfSerializedObjectTest { fun deserializeTest() { data class D(val c: C2) - val path = EvolvabilityTests::class.java.getResource("StaticInitialisationOfSerializedObjectTest.deserializeTest") - val f = File(path.toURI()) + val url = EvolvabilityTests::class.java.getResource("StaticInitialisationOfSerializedObjectTest.deserializeTest") // 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 bytes = f.readBytes() + val bytes = url.readBytes() - Assertions.assertThatThrownBy { + assertThatThrownBy { DeserializationInput(sf2).deserialize(SerializedBytes(bytes)) }.isInstanceOf(NotSerializableException::class.java) } @@ -119,8 +117,7 @@ class StaticInitialisationOfSerializedObjectTest { fun deserializeTest2() { data class D(val c: C2) - val path = EvolvabilityTests::class.java.getResource("StaticInitialisationOfSerializedObjectTest.deserializeTest2") - val f = File(path.toURI()) + val url = EvolvabilityTests::class.java.getResource("StaticInitialisationOfSerializedObjectTest.deserializeTest2") // Original version of the class for the serialised version of this class // @@ -142,12 +139,12 @@ class StaticInitialisationOfSerializedObjectTest { } 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 // we ever went anywhere near statically constructing it prior to not actually // creating an instance of it - Assertions.assertThatThrownBy { + assertThatThrownBy { DeserializationInput(sf2).deserialize(SerializedBytes(bytes)) }.isInstanceOf(NotSerializableException::class.java) } diff --git a/node/src/integration-test/kotlin/net/corda/node/BootTests.kt b/node/src/integration-test/kotlin/net/corda/node/BootTests.kt index dfa637ad6b..8962669597 100644 --- a/node/src/integration-test/kotlin/net/corda/node/BootTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/BootTests.kt @@ -15,6 +15,8 @@ import net.corda.client.rpc.CordaRPCClient import net.corda.core.flows.FlowLogic import net.corda.core.flows.StartableByRPC 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.utilities.getOrThrow import net.corda.node.internal.NodeStartup @@ -35,7 +37,6 @@ import org.assertj.core.api.Assertions.assertThatThrownBy import org.junit.ClassRule import org.junit.Test import java.io.* -import java.nio.file.Files import kotlin.test.assertEquals class BootTests : IntegrationTest() { @@ -63,13 +64,13 @@ class BootTests : IntegrationTest() { driver(DriverParameters(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { val alice = startNode(providedName = ALICE_NAME).get() 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 assertThatThrownBy { startNode(providedName = ALICE_NAME).getOrThrow() } // 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) } } diff --git a/node/src/integration-test/kotlin/net/corda/node/CordappConfigFileProviderTests.kt b/node/src/integration-test/kotlin/net/corda/node/CordappConfigFileProviderTests.kt index 0a6a26dde9..6b91e14500 100644 --- a/node/src/integration-test/kotlin/net/corda/node/CordappConfigFileProviderTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/CordappConfigFileProviderTests.kt @@ -14,57 +14,56 @@ import com.typesafe.config.Config import com.typesafe.config.ConfigException import com.typesafe.config.ConfigFactory 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 org.assertj.core.api.Assertions.assertThat import org.junit.Test -import java.io.File -import java.nio.file.Files -import java.nio.file.Path +import java.nio.file.Paths class CordappConfigFileProviderTests { private companion object { - val cordappConfDir = File("build/tmp/cordapps/config") - val cordappName = "test" - val cordappConfFile = File(cordappConfDir, cordappName + ".conf").toPath() + val cordappConfDir = Paths.get("build") / "tmp" / "cordapps" / "config" + const val cordappName = "test" + val cordappConfFile = cordappConfDir / "$cordappName.conf" - val validConfig = ConfigFactory.parseString("key=value") - val alternateValidConfig = ConfigFactory.parseString("key=alternateValue") - val invalidConfig = "Invalid" + val validConfig: Config = ConfigFactory.parseString("key=value") + val alternateValidConfig: Config = ConfigFactory.parseString("key=alternateValue") + const val invalidConfig = "Invalid" } - val provider = CordappConfigFileProvider(cordappConfDir) + private val provider = CordappConfigFileProvider(cordappConfDir) @Test fun `test that config can be loaded`() { - writeConfig(validConfig, cordappConfFile) + writeConfig(validConfig) assertThat(provider.getConfigByName(cordappName)).isEqualTo(validConfig) } @Test 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) } @Test fun `config is not idempotent if the underlying file is changed`() { - writeConfig(validConfig, cordappConfFile) + writeConfig(validConfig) assertThat(provider.getConfigByName(cordappName)).isEqualTo(validConfig) - writeConfig(alternateValidConfig, cordappConfFile) + writeConfig(alternateValidConfig) assertThat(provider.getConfigByName(cordappName)).isEqualTo(alternateValidConfig) } @Test(expected = ConfigException.Parse::class) fun `an invalid config throws an exception`() { - Files.write(cordappConfFile, invalidConfig.toByteArray()) - + cordappConfFile.writeText(invalidConfig) provider.getConfigByName(cordappName) } /** * 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())) } \ No newline at end of file diff --git a/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt index 982d7be0cf..82e92d39d2 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt @@ -18,6 +18,7 @@ import net.corda.core.flows.FlowLogic import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.internal.concurrent.transpose +import net.corda.core.internal.copyTo import net.corda.core.internal.createDirectories import net.corda.core.internal.div import net.corda.core.internal.toLedgerTransaction @@ -44,7 +45,6 @@ import org.junit.ClassRule import org.junit.Rule import org.junit.Test import java.net.URLClassLoader -import java.nio.file.Files import kotlin.test.assertFailsWith class AttachmentLoadingTests : IntegrationTest() { @@ -65,7 +65,7 @@ class AttachmentLoadingTests : IntegrationTest() { private val logger = contextLogger() 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 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. val path = (baseDirectory(nodeName) / "cordapps").createDirectories() / "isolated.jar" logger.info("Installing isolated jar to $path") - isolatedJAR.openStream().buffered().use { input -> - Files.newOutputStream(path).buffered().use { output -> - input.copyTo(output) - } - } + isolatedJAR.openStream().use { it.copyTo(path) } } } diff --git a/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt index c9a3f6964d..ba57aeab6f 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/network/NetworkMapTest.kt @@ -39,7 +39,6 @@ import org.junit.* import org.junit.Assert.assertEquals import java.net.URL import java.time.Instant -import kotlin.streams.toList class NetworkMapTest : IntegrationTest() { companion object { @@ -216,7 +215,7 @@ class NetworkMapTest : IntegrationTest() { // Make sure the nodes aren't getting the node infos from their additional directories val nodeInfosDir = baseDirectory / CordformNode.NODE_INFO_DIRECTORY if (nodeInfosDir.exists()) { - assertThat(nodeInfosDir.list { it.toList() }).isEmpty() + assertThat(nodeInfosDir.list()).isEmpty() } assertThat(rpc.networkMapSnapshot()).containsOnly(*nodes) } diff --git a/node/src/integration-test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt index e5a585a01f..6f47337d27 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt @@ -15,6 +15,7 @@ import com.google.common.jimfs.Jimfs import net.corda.cordform.CordformNode import net.corda.core.internal.createDirectories import net.corda.core.internal.div +import net.corda.core.internal.size import net.corda.core.node.NodeInfo import net.corda.core.node.services.KeyManagementService 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.makeTestIdentityService import org.assertj.core.api.Assertions.assertThat -import org.assertj.core.api.Assertions.contentOf import org.junit.Before import org.junit.Rule import org.junit.Test @@ -75,9 +75,9 @@ class NodeInfoWatcherTest { assertEquals(1, nodeInfoFiles.size) val fileName = nodeInfoFiles.first() 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. - assertThat(contentOf(file)).isNotEmpty() + assertThat(file.size).isGreaterThan(0) } @Test diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsNodeTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsNodeTest.kt index f64d8102b8..73eeaecadd 100644 --- a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsNodeTest.kt +++ b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityAsNodeTest.kt @@ -103,7 +103,7 @@ class MQSecurityAsNodeTest : P2PMQSecurityTest() { val legalName = CordaX500Name("MegaCorp", "London", "GB") certificatesDirectory.createDirectories() 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) diff --git a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappConfigFileProvider.kt b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappConfigFileProvider.kt index 9cf30dec43..3a10d167e8 100644 --- a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappConfigFileProvider.kt +++ b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappConfigFileProvider.kt @@ -12,33 +12,34 @@ package net.corda.node.internal.cordapp import com.typesafe.config.Config import com.typesafe.config.ConfigFactory -import net.corda.core.utilities.loggerFor -import java.io.File +import net.corda.core.internal.createDirectories +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 { - val DEFAULT_CORDAPP_CONFIG_DIR = File("cordapps/config") - val CONFIG_EXT = ".conf" - val logger = loggerFor() + val DEFAULT_CORDAPP_CONFIG_DIR = Paths.get("cordapps") / "config" + const val CONFIG_EXT = ".conf" + val logger = contextLogger() } init { - configDir.mkdirs() + configDir.createDirectories() } override fun getConfigByName(name: String): Config { - val configFile = File(configDir, name + CONFIG_EXT) + val configFile = configDir / "$name$CONFIG_EXT" return if (configFile.exists()) { - if (configFile.isDirectory) { - throw IllegalStateException("File at ${configFile.absolutePath} is a directory, expected a config file") - } else { - logger.info("Found config for cordapp $name in ${configFile.absolutePath}") - ConfigFactory.parseFile(configFile) - } + check(!configFile.isDirectory()) { "${configFile.toAbsolutePath()} is a directory, expected a config file" } + logger.info("Found config for cordapp $name in ${configFile.toAbsolutePath()}") + ConfigFactory.parseFile(configFile.toFile()) } 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() } } - -} \ No newline at end of file +} diff --git a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt index 68ab744275..cad494e03a 100644 --- a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt +++ b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt @@ -30,15 +30,13 @@ import net.corda.node.services.config.NodeConfiguration import net.corda.nodeapi.internal.coreContractClasses import net.corda.nodeapi.internal.serialization.DefaultWhitelist import org.apache.commons.collections4.map.LRUMap -import java.io.File -import java.io.FileOutputStream import java.lang.reflect.Modifier import java.net.JarURLConnection import java.net.URI import java.net.URL import java.net.URLClassLoader -import java.nio.file.Files import java.nio.file.Path +import java.nio.file.Paths import java.nio.file.attribute.FileTime import java.time.Instant import java.util.* @@ -88,8 +86,7 @@ class CordappLoader private constructor(private val cordappJarPaths: List): CordappLoader { @@ -139,31 +136,26 @@ class CordappLoader private constructor(private val cordappJarPaths: List - val scanDir = File(path.toURI()) - scanDir.walkTopDown().forEach { - val entryPath = jarPackageName + "/" + scanDir.toPath().relativize(it.toPath()).toString().replace('\\', '/') - val time = FileTime.from(Instant.EPOCH) - val entry = ZipEntry(entryPath).setCreationTime(time).setLastAccessTime(time).setLastModifiedTime(time) - jos.putNextEntry(entry) - if (it.isFile) { - Files.copy(it.toPath(), jos) - } - jos.closeEntry() + JarOutputStream(cordappJAR.outputStream()).use { jos -> + val scanDir = url.toPath() + scanDir.walk { it.forEach { + val entryPath = "$jarPackageName/${scanDir.relativize(it).toString().replace('\\', '/')}" + val time = FileTime.from(Instant.EPOCH) + val entry = ZipEntry(entryPath).setCreationTime(time).setLastAccessTime(time).setLastModifiedTime(time) + jos.putNextEntry(entry) + if (it.isRegularFile()) { + it.copyTo(jos) } - } + jos.closeEntry() + } } } - generatedCordapps[path] = cordappJAR.toURI() + cordappJAR.toUri() } - - return generatedCordapps[path]!! } private fun getCordappsInDirectory(cordappsDir: Path): List { diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt index 0befe32125..3a4c2ea198 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt @@ -22,7 +22,6 @@ import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.internal.FlowIORequest 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.serialize @@ -41,7 +40,6 @@ import net.corda.nodeapi.internal.persistence.contextTransaction import net.corda.nodeapi.internal.persistence.contextTransactionOrNull import org.slf4j.Logger import org.slf4j.LoggerFactory -import java.nio.file.Paths import java.util.concurrent.TimeUnit import kotlin.reflect.KProperty1 @@ -309,7 +307,7 @@ val Class>.flowVersionAndInitiatingClass: Pair>.appName: String get() { - val jarFile = Paths.get(protectionDomain.codeSource.location.toURI()) + val jarFile = protectionDomain.codeSource.location.toPath() return if (jarFile.isRegularFile() && jarFile.toString().endsWith(".jar")) { jarFile.fileName.toString().removeSuffix(".jar") } else { diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/BFTSMaRtConfig.kt b/node/src/main/kotlin/net/corda/node/services/transactions/BFTSMaRtConfig.kt index 9d9791d3e4..6b9b514101 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/BFTSMaRtConfig.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/BFTSMaRtConfig.kt @@ -11,10 +11,10 @@ package net.corda.node.services.transactions import net.corda.core.internal.div +import net.corda.core.internal.writer import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.contextLogger import net.corda.core.utilities.debug -import java.io.FileWriter import java.io.PrintWriter import java.net.InetAddress import java.net.Socket @@ -58,7 +58,7 @@ class BFTSMaRtConfig(private val replicaAddresses: List, deb private fun configWriter(name: String, block: PrintWriter.() -> Unit) { // Default charset, consistent with loaders: - FileWriter((path / name).toFile()).use { + (path / name).writer().use { PrintWriter(it).use { it.run(block) } diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/PathManager.kt b/node/src/main/kotlin/net/corda/node/services/transactions/PathManager.kt index a53cd4815c..9b1f9d4200 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/PathManager.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/PathManager.kt @@ -10,6 +10,7 @@ package net.corda.node.services.transactions +import net.corda.core.internal.deleteRecursively import net.corda.core.internal.uncheckedCast import net.corda.nodeapi.internal.addShutdownHook import java.io.Closeable @@ -19,7 +20,7 @@ import java.util.concurrent.atomic.AtomicInteger private class DeleteOnExitPath(internal val path: Path) { private val shutdownHook = addShutdownHook { dispose() } internal fun dispose() { - path.toFile().deleteRecursively() + path.deleteRecursively() shutdownHook.cancel() } } diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/RaftUniquenessProvider.kt b/node/src/main/kotlin/net/corda/node/services/transactions/RaftUniquenessProvider.kt index d09f2bf292..83001812bc 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/RaftUniquenessProvider.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/RaftUniquenessProvider.kt @@ -120,7 +120,7 @@ class RaftUniquenessProvider( get() = _clientFuture.get() fun start() { - log.info("Creating Copycat server, log stored in: ${storagePath.toFile()}") + log.info("Creating Copycat server, log stored in: ${storagePath.toAbsolutePath()}") val stateMachineFactory = { RaftTransactionCommitLog(db, clock, RaftUniquenessProvider.Companion::createMap) } diff --git a/node/src/main/kotlin/net/corda/node/utilities/JVMAgentRegistry.kt b/node/src/main/kotlin/net/corda/node/utilities/JVMAgentRegistry.kt index 84832d6859..732089773a 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/JVMAgentRegistry.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/JVMAgentRegistry.kt @@ -13,6 +13,8 @@ package net.corda.node.utilities import com.ea.agentloader.AgentLoader import net.corda.core.internal.exists import net.corda.core.internal.isRegularFile +import net.corda.core.internal.toPath +import java.net.URL import java.net.URLClassLoader import java.nio.file.Path import java.nio.file.Paths @@ -53,7 +55,7 @@ object JVMAgentRegistry { } else { (this::class.java.classLoader as? URLClassLoader) ?.urLs - ?.map { Paths.get(it.toURI()) } + ?.map(URL::toPath) ?.firstOrNull { it.fileName.toString() == jarFileName } } } diff --git a/node/src/test/kotlin/net/corda/node/ArgsParserTest.kt b/node/src/test/kotlin/net/corda/node/ArgsParserTest.kt index 8c50074f92..050438d317 100644 --- a/node/src/test/kotlin/net/corda/node/ArgsParserTest.kt +++ b/node/src/test/kotlin/net/corda/node/ArgsParserTest.kt @@ -11,6 +11,7 @@ package net.corda.node import joptsimple.OptionException +import net.corda.core.internal.delete import net.corda.core.internal.div import net.corda.nodeapi.internal.crypto.X509KeyStore 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.Test import org.slf4j.event.Level -import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import kotlin.test.assertEquals @@ -150,7 +150,7 @@ class ArgsParserTest { assertEquals(truststorePath.toAbsolutePath(), cmdLineOptions.nodeRegistrationOption?.networkRootTrustStorePath) assertEquals("password-test", cmdLineOptions.nodeRegistrationOption?.networkRootTrustStorePassword) } finally { - Files.delete(truststorePath) + truststorePath.delete() } } diff --git a/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt b/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt index 3acc3d6083..6e72fb8e19 100644 --- a/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt +++ b/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt @@ -13,9 +13,10 @@ package net.corda.node.internal import com.nhaarman.mockito_kotlin.doReturn import com.nhaarman.mockito_kotlin.whenever 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.node.NodeInfo -import net.corda.core.serialization.deserialize import net.corda.core.utilities.NetworkHostAndPort import net.corda.node.VersionInfo 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.Test import org.junit.rules.TemporaryFolder -import java.nio.file.Files +import java.nio.file.Path import kotlin.test.assertEquals import kotlin.test.assertNull @@ -42,14 +43,21 @@ class NodeTest { @JvmField 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 { assertNull(nodeInfoFile()) generateAndSaveNodeInfo() - val path = nodeInfoFile()!!.toPath() - val nodeInfo = path.readObject().raw.deserialize() - Files.delete(path) - return nodeInfo + val path = nodeInfoFile()!! + try { + return path.readObject().verified() + } finally { + path.delete() + } } @Test diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/analytics/example/OGSwapPricingCcpExample.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/analytics/example/OGSwapPricingCcpExample.kt index e98fb84338..401f8dc46c 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/analytics/example/OGSwapPricingCcpExample.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/analytics/example/OGSwapPricingCcpExample.kt @@ -38,8 +38,8 @@ import com.opengamma.strata.report.ReportCalculationResults import com.opengamma.strata.report.trade.TradeReport import net.corda.core.internal.div import net.corda.core.internal.exists +import net.corda.core.internal.toPath import java.nio.file.Path -import java.nio.file.Paths import java.time.LocalDate /** @@ -69,7 +69,7 @@ class SwapPricingCcpExample { */ private val resourcesUri = run { // 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" var path: Path while (true) { diff --git a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/internal/ProcessUtilitiesTests.kt b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/internal/ProcessUtilitiesTests.kt index e0f8fdfa61..6a8931dbb2 100644 --- a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/internal/ProcessUtilitiesTests.kt +++ b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/node/internal/ProcessUtilitiesTests.kt @@ -10,11 +10,12 @@ 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.Test import org.junit.rules.TemporaryFolder -import java.io.File +import java.nio.file.Paths import java.util.concurrent.TimeUnit import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -31,8 +32,7 @@ class ProcessUtilitiesTests { @JvmStatic fun main(args: Array) { - val fileNameToCreate = args[0] - FileUtils.write(File(fileNameToCreate), tmpString) + Paths.get(args[0]).writeText(tmpString) } } @@ -41,6 +41,6 @@ class ProcessUtilitiesTests { val tmpFile = tempFolder.newFile("${ProcessUtilitiesTests::class.java.simpleName}.txt") val startedProcess = ProcessUtilities.startJavaProcess(listOf(tmpFile.absolutePath)) assertTrue { startedProcess.waitFor(20, TimeUnit.SECONDS) } - assertEquals(tmpString, FileUtils.readFileToString(tmpFile)) + assertEquals(tmpString, tmpFile.toPath().readText()) } } \ No newline at end of file diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt index 73084b0bd1..937c6e89f8 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt @@ -73,8 +73,6 @@ import java.net.ConnectException import java.net.URL import java.net.URLClassLoader import java.nio.file.Path -import java.nio.file.Paths -import java.nio.file.StandardCopyOption import java.security.cert.X509Certificate import java.time.Duration import java.time.Instant @@ -136,7 +134,7 @@ class DriverDSLImpl( val urls = (cl as URLClassLoader).urLs val jarPattern = jarNamePattern.toRegex() val jarFileUrl = urls.first { jarPattern.matches(it.path) } - Paths.get(jarFileUrl.toURI()).toString() + jarFileUrl.toPath().toString() } catch (e: Exception) { log.warn("Unable to locate JAR `$jarNamePattern` on classpath: ${e.message}", e) throw e @@ -1094,16 +1092,11 @@ fun getTimestampAsDirectoryName(): String { fun writeConfig(path: Path, filename: String, config: Config) { val configString = config.root().render(ConfigRenderOptions.defaults()) - configString.byteInputStream().copyTo(path / filename, StandardCopyOption.REPLACE_EXISTING) + (path / filename).writeText(configString) } 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) = withValue(property.first, ConfigValueFactory.fromAnyRef(property.second)) \ No newline at end of file diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/demorun/CordformNodeRunner.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/demorun/CordformNodeRunner.kt index 68034f9ed0..7bceaceb94 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/demorun/CordformNodeRunner.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/demorun/CordformNodeRunner.kt @@ -12,6 +12,7 @@ package net.corda.testing.node.internal.demorun import net.corda.cordform.CordformDefinition import net.corda.cordform.CordformNode +import net.corda.core.internal.deleteRecursively import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.getOrThrow import net.corda.testing.driver.JmxPolicy @@ -39,7 +40,7 @@ class CordformNodeRunner(val cordformDefinition: CordformDefinition) { fun clean() { System.err.println("Deleting: ${cordformDefinition.nodesDirectory}") - cordformDefinition.nodesDirectory.toFile().deleteRecursively() + cordformDefinition.nodesDirectory.deleteRecursively() } /** diff --git a/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt b/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt index e4c86ada06..7cdc703b97 100644 --- a/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt +++ b/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt @@ -13,17 +13,13 @@ package net.corda.smoketesting import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCConnection import net.corda.client.rpc.internal.KryoClientSerializationScheme -import net.corda.core.internal.copyTo -import net.corda.core.internal.copyToDirectory -import net.corda.core.internal.createDirectories -import net.corda.core.internal.div +import net.corda.core.internal.* import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.contextLogger import net.corda.nodeapi.internal.network.NetworkParametersCopier import net.corda.testing.common.internal.asContextEnv import net.corda.testing.common.internal.testNetworkParameters import java.io.File -import java.net.URL import java.nio.file.Path import java.nio.file.Paths import java.time.Instant @@ -57,20 +53,21 @@ class NodeProcess( } 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 // as a CorDapp for the nodes. class Factory( private val buildDirectory: Path = Paths.get("build"), - private val cordaJarUrl: URL? = this::class.java.getResource("/corda.jar"), private val extraJvmArgs: Array = emptyArray(), private val redirectConsoleTo: File? = null ) { val cordaJar: Path by lazy { - require(cordaJarUrl != null, { "corda.jar could not be found in classpath" }) - Paths.get(cordaJarUrl!!.toURI()) + val cordaJarUrl = requireNotNull(this::class.java.getResource("/corda.jar")) { + "corda.jar could not be found in classpath" + } + cordaJarUrl.toPath() } private companion object { @@ -102,7 +99,7 @@ class NodeProcess( val nodeDir = baseDirectory(config).createDirectories() log.info("Node directory: {}", nodeDir) - config.toText().byteInputStream().copyTo(nodeDir / "node.conf") + (nodeDir / "node.conf").writeText(config.toText()) defaultNetworkParameters.install(nodeDir) val process = startNode(nodeDir) diff --git a/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/ProjectStructure.kt b/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/ProjectStructure.kt index 4944b69e3d..c4063185ad 100644 --- a/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/ProjectStructure.kt +++ b/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/ProjectStructure.kt @@ -12,12 +12,12 @@ package net.corda.testing.common.internal import net.corda.core.internal.div import net.corda.core.internal.isDirectory +import net.corda.core.internal.toPath import java.nio.file.Path -import java.nio.file.Paths object ProjectStructure { val projectRootDir: Path = run { - var dir = Paths.get(javaClass.getResource("/").toURI()) + var dir = javaClass.getResource("/").toPath() while (!(dir / ".git").isDirectory()) { dir = dir.parent } diff --git a/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/UnsafeCertificatesFactory.kt b/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/UnsafeCertificatesFactory.kt index 5d9dd83d30..d750d631df 100644 --- a/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/UnsafeCertificatesFactory.kt +++ b/testing/test-common/src/main/kotlin/net/corda/testing/common/internal/UnsafeCertificatesFactory.kt @@ -11,6 +11,8 @@ package net.corda.testing.common.internal 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.nodeapi.internal.config.SSLConfiguration 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 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 { - private val file = (directory / fileName).toFile() + val file: Path = (directory / fileName).createFile().toAbsolutePath() init { - file.createNewFile() - file.deleteOnExit() + file.toFile().deleteOnExit() } - val path: Path = file.toPath().toAbsolutePath() - - override fun close() = FileUtils.forceDelete(file) + override fun close() { + file.deleteIfExists() + } } 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) } } - FileUtils.deleteQuietly(clientDir.toFile()) - FileUtils.deleteQuietly(serverDir.toFile()) + clientDir.deleteIfExists() + 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) { diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/explorer/Explorer.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/explorer/Explorer.kt index c1b58696aa..491993e10c 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/explorer/Explorer.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/explorer/Explorer.kt @@ -10,6 +10,7 @@ package net.corda.demobench.explorer +import net.corda.core.internal.copyTo import net.corda.core.internal.createDirectories import net.corda.core.internal.div import net.corda.core.internal.list @@ -103,13 +104,13 @@ class Explorer internal constructor(private val explorerController: ExplorerCont Files.createSymbolicLink(destPath, path) } catch (e: UnsupportedOperationException) { // OS doesn't support symbolic links? - Files.copy(path, destPath, REPLACE_EXISTING) + path.copyTo(destPath, REPLACE_EXISTING) } catch (e: java.nio.file.FileAlreadyExistsException) { // OK, don't care ... } catch (e: IOException) { // Windows 10 might not allow this user to create a symlink log.warn("Failed to create symlink '{}' for '{}': {}", destPath, path, e.message) - Files.copy(path, destPath, REPLACE_EXISTING) + path.copyTo(destPath, REPLACE_EXISTING) } } } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt index a15271dc74..28276c2f41 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt @@ -11,6 +11,7 @@ package net.corda.demobench.model import com.typesafe.config.Config +import net.corda.core.internal.deleteRecursively import net.corda.core.internal.div import net.corda.core.utilities.NetworkHostAndPort 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 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) } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/JVMConfig.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/JVMConfig.kt index 0d2f9b125e..462477d386 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/JVMConfig.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/JVMConfig.kt @@ -13,9 +13,10 @@ package net.corda.demobench.model import javafx.scene.control.Alert import javafx.scene.control.Alert.AlertType.ERROR import javafx.stage.Stage +import net.corda.core.internal.exists +import tornadofx.* import java.nio.file.Path import java.nio.file.Paths -import tornadofx.* class JVMConfig : Controller() { @@ -45,17 +46,17 @@ class JVMConfig : Controller() { typealias atRuntime = (Path, String) -> Unit fun checkExists(path: Path, header: String) { - if (!path.toFile().exists()) { - 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." + if (path.exists()) return - val stage = alert.dialogPane.scene.window as Stage - stage.isAlwaysOnTop = true + 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." - alert.show() - } + val stage = alert.dialogPane.scene.window as Stage + stage.isAlwaysOnTop = true + + alert.show() } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt index 457b2a9d45..6037d425d2 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt @@ -13,10 +13,7 @@ package net.corda.demobench.model import javafx.beans.binding.IntegerExpression import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party -import net.corda.core.internal.copyToDirectory -import net.corda.core.internal.createDirectories -import net.corda.core.internal.div -import net.corda.core.internal.noneOrSingle +import net.corda.core.internal.* import net.corda.core.node.NetworkParameters import net.corda.core.node.NotaryInfo import net.corda.core.utilities.NetworkHostAndPort @@ -27,7 +24,6 @@ import net.corda.nodeapi.internal.network.NetworkParametersCopier import tornadofx.* import java.io.IOException import java.lang.management.ManagementFactory -import java.nio.file.Files import java.nio.file.Path import java.text.SimpleDateFormat import java.time.Instant @@ -131,11 +127,11 @@ class NodeController(check: atRuntime = ::checkExists) : Controller() { // Write this node's configuration file into its working directory. 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. val webConfFile = config.nodeDir / "web-server.conf" - Files.write(webConfFile, config.nodeConfig.toWebServerConfText().toByteArray()) + webConfFile.writeText(config.nodeConfig.toWebServerConfText()) // Execute the Corda node val cordaEnv = System.getenv().toMutableMap().apply { @@ -210,9 +206,7 @@ class NodeController(check: atRuntime = ::checkExists) : Controller() { log.info("Installed: $plugin") } - if (!config.deleteBaseDir()) { - log.warning("Failed to remove '${config.baseDir}'") - } + config.deleteBaseDir() return installed } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/plugin/CordappController.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/plugin/CordappController.kt index dae719c6f8..bcab464385 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/plugin/CordappController.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/plugin/CordappController.kt @@ -10,19 +10,16 @@ package net.corda.demobench.plugin -import net.corda.core.internal.copyToDirectory -import net.corda.core.internal.createDirectories -import net.corda.core.internal.exists +import net.corda.core.internal.* import net.corda.demobench.model.HasCordapps import net.corda.demobench.model.JVMConfig import net.corda.demobench.model.NodeConfig import net.corda.demobench.model.NodeConfigWrapper import tornadofx.* import java.io.IOException -import java.nio.file.Files import java.nio.file.Path import java.nio.file.StandardCopyOption -import java.util.stream.Stream +import kotlin.streams.toList class CordappController : Controller() { @@ -54,18 +51,16 @@ class CordappController : Controller() { * Generates a stream of a node's non-built-in cordapps. */ @Throws(IOException::class) - fun useCordappsFor(config: HasCordapps): Stream = walkCordapps(config.cordappsDir) - .filter { !bankOfCorda.endsWith(it.fileName) } - .filter { !finance.endsWith(it.fileName) } - - private fun walkCordapps(cordappsDir: Path): Stream { - return if (Files.isDirectory(cordappsDir)) - Files.walk(cordappsDir, 1).filter(Path::isCordapp) - else - Stream.empty() + fun useCordappsFor(config: HasCordapps): List { + if (!config.cordappsDir.isDirectory()) return emptyList() + return config.cordappsDir.walk(1) { paths -> paths + .filter(Path::isCordapp) + .filter { !bankOfCorda.endsWith(it.fileName) } + .filter { !finance.endsWith(it.fileName) } + .toList() + } } - } -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/") diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/profile/ProfileController.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/profile/ProfileController.kt index 3a8c1cf7a9..d20a7873ef 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/profile/ProfileController.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/profile/ProfileController.kt @@ -14,8 +14,7 @@ import com.typesafe.config.Config import com.typesafe.config.ConfigFactory import javafx.stage.FileChooser import javafx.stage.FileChooser.ExtensionFilter -import net.corda.core.internal.createDirectories -import net.corda.core.internal.div +import net.corda.core.internal.* import net.corda.demobench.model.* import net.corda.demobench.plugin.CordappController import net.corda.demobench.plugin.inCordappsDir @@ -24,7 +23,6 @@ import tornadofx.* import java.io.File import java.io.IOException import java.net.URI -import java.nio.charset.StandardCharsets.UTF_8 import java.nio.file.FileSystems import java.nio.file.Files import java.nio.file.Path @@ -68,13 +66,13 @@ class ProfileController : Controller() { configs.forEach { config -> // Write the configuration file. 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") // 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 { - val cordapp = Files.copy(it, cordappDir.resolve(it.fileName.toString())) + val cordapp = it.copyToDirectory(cordappDir) log.info("Wrote: $cordapp") } } @@ -132,8 +130,8 @@ class ProfileController : Controller() { val config = nodeIndex[cordapp.getName(0).toString()] ?: return@forEach try { - val cordappDir = Files.createDirectories(config.cordappsDir) - Files.copy(cordapp, cordappDir.resolve(cordapp.fileName.toString())) + val cordappDir = config.cordappsDir.createDirectories() + cordapp.copyToDirectory(cordappDir) log.info("Loaded: $cordapp") } catch (e: Exception) { log.log(Level.SEVERE, "Failed to extract '$cordapp': ${e.message}", e) @@ -146,8 +144,5 @@ class ProfileController : Controller() { return configs } - private fun parse(path: Path): Config = Files.newBufferedReader(path).use { - return ConfigFactory.parseReader(it) - } - + private fun parse(path: Path): Config = path.reader().use { ConfigFactory.parseReader(it) } } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/web/WebServer.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/web/WebServer.kt index 8061251795..465ef5cea3 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/web/WebServer.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/web/WebServer.kt @@ -13,6 +13,7 @@ package net.corda.demobench.web import com.google.common.util.concurrent.RateLimiter import net.corda.core.concurrent.CordaFuture import net.corda.core.internal.concurrent.openFuture +import net.corda.core.internal.isDirectory import net.corda.core.internal.until import net.corda.core.utilities.contextLogger import net.corda.core.utilities.minutes @@ -36,17 +37,17 @@ class WebServer internal constructor(private val webServerController: WebServerC @Throws(IOException::class) fun open(config: NodeConfigWrapper): CordaFuture { - val nodeDir = config.nodeDir.toFile() + val nodeDir = config.nodeDir - if (!nodeDir.isDirectory) { - log.warn("Working directory '{}' does not exist.", nodeDir.absolutePath) + if (!nodeDir.isDirectory()) { + log.warn("Working directory '{}' does not exist.", nodeDir.toAbsolutePath()) return openFuture() } val legalName = config.nodeConfig.myLegalName try { val p = webServerController.process() - .directory(nodeDir) + .directory(nodeDir.toFile()) .start() process = p diff --git a/tools/demobench/src/test/kotlin/net/corda/demobench/model/JVMConfigTest.kt b/tools/demobench/src/test/kotlin/net/corda/demobench/model/JVMConfigTest.kt index 1195a28c5a..9d9db8168a 100644 --- a/tools/demobench/src/test/kotlin/net/corda/demobench/model/JVMConfigTest.kt +++ b/tools/demobench/src/test/kotlin/net/corda/demobench/model/JVMConfigTest.kt @@ -11,30 +11,28 @@ package net.corda.demobench.model import com.jediterm.terminal.ui.UIUtil +import org.assertj.core.api.Assertions.assertThat import org.junit.Test -import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import kotlin.test.assertEquals -import kotlin.test.assertTrue class JVMConfigTest { - private val jvm = JVMConfig() @Test fun `test Java path`() { - assertTrue(Files.isExecutable(jvm.javaPath.onFileSystem())) + assertThat(jvm.javaPath.onFileSystem()).isExecutable() } @Test fun `test application directory`() { - assertTrue(Files.isDirectory(jvm.applicationDir)) + assertThat(jvm.applicationDir).isDirectory() } @Test fun `test user home`() { - assertTrue(Files.isDirectory(jvm.userHome)) + assertThat(jvm.userHome).isDirectory() } @Test @@ -51,8 +49,5 @@ class JVMConfigTest { assertEquals(listOf(java.toString(), "-jar", "testapp.jar", "arg1", "arg2", "arg3"), process.command()) } - private fun Path.onFileSystem(): Path - = if (UIUtil.isWindows) this.parent.resolve(Paths.get(this.fileName.toString() + ".exe")) - else this - + private fun Path.onFileSystem(): Path = if (UIUtil.isWindows) parent.resolve(Paths.get("$fileName.exe")) else this } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/model/SettingsModel.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/model/SettingsModel.kt index aa0bc65a9e..b4dc42922e 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/model/SettingsModel.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/model/SettingsModel.kt @@ -14,12 +14,8 @@ import javafx.beans.InvalidationListener import javafx.beans.Observable import javafx.beans.property.ObjectProperty import javafx.beans.property.SimpleObjectProperty -import net.corda.core.internal.createDirectories -import net.corda.core.internal.div -import net.corda.core.internal.exists -import net.corda.core.internal.uncheckedCast +import net.corda.core.internal.* import tornadofx.* -import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import java.util.* @@ -56,12 +52,12 @@ class SettingsModel(path: Path = Paths.get("conf")) : Component(), Observable { // Load config from properties file. fun load() = config.apply { clear() - if (Files.exists(path)) Files.newInputStream(path).use { load(it) } + if (path.exists()) path.read { load(it) } listeners.forEach { it.invalidated(this@SettingsModel) } } // 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 Properties.getValue(receiver: Any, metadata: KProperty<*>): T { return when (metadata.returnType.javaType) { diff --git a/tools/explorer/src/test/kotlin/net/corda/explorer/model/SettingsModelTest.kt b/tools/explorer/src/test/kotlin/net/corda/explorer/model/SettingsModelTest.kt index e7a2938507..b6fb79e299 100644 --- a/tools/explorer/src/test/kotlin/net/corda/explorer/model/SettingsModelTest.kt +++ b/tools/explorer/src/test/kotlin/net/corda/explorer/model/SettingsModelTest.kt @@ -11,10 +11,10 @@ package net.corda.explorer.model import net.corda.core.internal.div +import net.corda.core.internal.exists import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder -import java.nio.file.Files import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -36,9 +36,9 @@ class SettingsModelTest { setting.portProperty.value = "100" assertEquals("host", setting.hostProperty.value) assertEquals("100", setting.portProperty.value) - assertFalse(Files.exists(config)) + assertFalse(config.exists()) setting.commit() - assertTrue(Files.exists(config)) + assertTrue(config.exists()) setting.hostProperty.value = "host2" setting.portProperty.value = "200" assertEquals("host2", setting.hostProperty.value) diff --git a/tools/shell/src/main/kotlin/net/corda/tools/shell/InteractiveShell.kt b/tools/shell/src/main/kotlin/net/corda/tools/shell/InteractiveShell.kt index 102bfcee36..dfdf588dcf 100644 --- a/tools/shell/src/main/kotlin/net/corda/tools/shell/InteractiveShell.kt +++ b/tools/shell/src/main/kotlin/net/corda/tools/shell/InteractiveShell.kt @@ -118,7 +118,7 @@ object InteractiveShell { config["crash.auth"] = "corda" configuration.sshHostKeyDirectory?.apply { val sshKeysDir = configuration.sshHostKeyDirectory - sshKeysDir.toFile().mkdirs() + sshKeysDir.createDirectories() config["crash.ssh.keypath"] = (sshKeysDir / "hostkey.pem").toString() config["crash.ssh.keygen"] = "true" } diff --git a/tools/shell/src/main/kotlin/net/corda/tools/shell/SerializationSupport.kt b/tools/shell/src/main/kotlin/net/corda/tools/shell/SerializationSupport.kt index 90a1a149e3..16504781b4 100644 --- a/tools/shell/src/main/kotlin/net/corda/tools/shell/SerializationSupport.kt +++ b/tools/shell/src/main/kotlin/net/corda/tools/shell/SerializationSupport.kt @@ -9,11 +9,11 @@ import com.fasterxml.jackson.databind.SerializerProvider import com.google.common.io.Closeables import net.corda.core.contracts.UniqueIdentifier import net.corda.core.internal.copyTo +import net.corda.core.internal.inputStream import org.crsh.command.InvocationContext import rx.Observable import java.io.BufferedInputStream import java.io.InputStream -import java.nio.file.Files import java.nio.file.Paths import java.util.* @@ -85,7 +85,7 @@ object InputStreamDeserializer : JsonDeserializer() { private val streams = Collections.synchronizedSet(HashSet()) 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() { super.close() streams.remove(this) diff --git a/tools/shell/src/test/kotlin/net/corda/tools/shell/StandaloneShellArgsParserTest.kt b/tools/shell/src/test/kotlin/net/corda/tools/shell/StandaloneShellArgsParserTest.kt index 9c3087be20..cd8bff0127 100644 --- a/tools/shell/src/test/kotlin/net/corda/tools/shell/StandaloneShellArgsParserTest.kt +++ b/tools/shell/src/test/kotlin/net/corda/tools/shell/StandaloneShellArgsParserTest.kt @@ -10,20 +10,19 @@ package net.corda.tools.shell +import net.corda.core.internal.toPath import net.corda.core.utilities.NetworkHostAndPort +import org.assertj.core.api.Assertions.assertThat import org.junit.Test import org.slf4j.event.Level import java.nio.file.Paths import kotlin.test.assertEquals -import java.io.File class StandaloneShellArgsParserTest { - - private val CONFIG_FILE = File(StandaloneShellArgsParserTest::class.java.getResource("/config.conf").toURI()) + private val CONFIG_FILE = StandaloneShellArgsParserTest::class.java.getResource("/config.conf").toPath() @Test fun args_to_cmd_options() { - val args = arrayOf("--config-file", "/x/y/z/config.conf", "--commands-directory", "/x/y/commands", "--cordpass-directory", "/x/y/cordapps", @@ -42,7 +41,8 @@ class StandaloneShellArgsParserTest { "--truststore-type", "dummy", "--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(), cordappsDirectory = Paths.get("/x/y/cordapps").normalize().toAbsolutePath(), host = "alocalhost", @@ -62,7 +62,7 @@ class StandaloneShellArgsParserTest { val options = CommandLineOptionParser().parse(*args) - assertEquals(expectedOptions, options) + assertThat(options).isEqualTo(expectedOptions) } @Test @@ -137,7 +137,7 @@ class StandaloneShellArgsParserTest { @Test fun cmd_options_to_config_from_file() { - val options = CommandLineOptions(configFile = CONFIG_FILE.absolutePath, + val options = CommandLineOptions(configFile = CONFIG_FILE.toString(), commandsDirectory = null, cordappsDirectory = null, host = null, @@ -176,7 +176,7 @@ class StandaloneShellArgsParserTest { @Test fun cmd_options_override_config_from_file() { - val options = CommandLineOptions(configFile = CONFIG_FILE.absolutePath, + val options = CommandLineOptions(configFile = CONFIG_FILE.toString(), commandsDirectory = null, cordappsDirectory = null, host = null,