From d3446e213c7c1b1de64c2cbf9997236b88f3bbae Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Mon, 23 Apr 2018 14:31:49 +0100 Subject: [PATCH] Introduced a few more extension methods to Path, which are clearer than the static methods in Files. (#2985) Also migrated code away from the old File API. --- .../net/corda/core/internal/InternalUtils.kt | 59 +----- .../net/corda/core/internal/PathUtils.kt | 176 ++++++++++++++++++ .../core/internal/cordapp/CordappImpl.kt | 4 +- .../core/internal/AbstractAttachmentTest.kt | 13 +- .../net/corda/core/internal/PathUtilsTest.kt | 62 ++++++ .../net/corda/docs/ExampleConfigTest.kt | 6 +- .../main/kotlin/net/corda/behave/Utilities.kt | 2 + .../net/corda/behave/file/FileUtilities.kt | 15 +- .../kotlin/net/corda/behave/file/LogSource.kt | 19 +- .../net/corda/behave/logging/LogUtilities.kt | 2 + .../net/corda/behave/network/Network.kt | 50 ++--- .../net/corda/behave/node/Distribution.kt | 46 +++-- .../main/kotlin/net/corda/behave/node/Node.kt | 15 +- .../node/configuration/Configuration.kt | 12 +- .../net/corda/behave/process/Command.kt | 6 +- .../net/corda/behave/process/JarCommand.kt | 5 +- .../corda/behave/scenarios/helpers/Startup.kt | 5 +- .../internal/network/NetworkBootstrapper.kt | 5 +- .../internal/network/NodeInfoFilesCopier.kt | 24 +-- .../serialization/CordaClassResolver.kt | 8 +- .../network/NodeInfoFilesCopierTest.kt | 34 ++-- .../amqp/EnumEvolvabilityTests.kt | 9 +- .../serialization/amqp/EnumEvolveTests.kt | 64 +++---- .../internal/serialization/amqp/EnumTests.kt | 11 +- .../serialization/amqp/EvolvabilityTests.kt | 94 ++++------ .../serialization/amqp/GenericsTests.kt | 2 +- ...ticInitialisationOfSerializedObjectTest.kt | 17 +- .../kotlin/net/corda/node/BootTests.kt | 11 +- .../node/CordappConfigFileProviderTests.kt | 33 ++-- .../node/services/AttachmentLoadingTests.kt | 12 +- .../node/services/network/NetworkMapTest.kt | 3 +- .../services/network/NodeInfoWatcherTest.kt | 6 +- .../messaging/MQSecurityAsNodeTest.kt | 2 +- .../cordapp/CordappConfigFileProvider.kt | 35 ++-- .../node/internal/cordapp/CordappLoader.kt | 44 ++--- .../statemachine/FlowStateMachineImpl.kt | 3 +- .../services/transactions/BFTSMaRtConfig.kt | 4 +- .../node/services/transactions/PathManager.kt | 3 +- .../transactions/RaftUniquenessProvider.kt | 2 +- .../corda/node/utilities/JVMAgentRegistry.kt | 4 +- .../kotlin/net/corda/node/ArgsParserTest.kt | 4 +- .../net/corda/node/internal/NodeTest.kt | 22 ++- .../example/OGSwapPricingCcpExample.kt | 4 +- .../node/internal/ProcessUtilitiesTests.kt | 10 +- .../testing/node/internal/DriverDSLImpl.kt | 13 +- .../internal/demorun/CordformNodeRunner.kt | 3 +- .../net/corda/smoketesting/NodeProcess.kt | 20 +- .../common/internal/ProjectStructure.kt | 4 +- .../internal/UnsafeCertificatesFactory.kt | 19 +- .../net/corda/demobench/explorer/Explorer.kt | 5 +- .../corda/demobench/model/InstallFactory.kt | 3 +- .../net/corda/demobench/model/JVMConfig.kt | 25 +-- .../corda/demobench/model/NodeController.kt | 20 +- .../demobench/plugin/CordappController.kt | 27 ++- .../demobench/profile/ProfileController.kt | 19 +- .../net/corda/demobench/web/WebServer.kt | 9 +- .../corda/demobench/model/JVMConfigTest.kt | 15 +- .../net/corda/explorer/model/SettingsModel.kt | 10 +- .../corda/explorer/model/SettingsModelTest.kt | 6 +- .../net/corda/tools/shell/InteractiveShell.kt | 2 +- .../corda/tools/shell/SerializationSupport.kt | 4 +- .../shell/StandaloneShellArgsParserTest.kt | 16 +- 62 files changed, 661 insertions(+), 526 deletions(-) create mode 100644 core/src/main/kotlin/net/corda/core/internal/PathUtils.kt create mode 100644 core/src/test/kotlin/net/corda/core/internal/PathUtilsTest.kt 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 411bb95454..e8762f69e5 100644 --- a/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt +++ b/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt @@ -34,13 +34,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 @@ -68,14 +68,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. @@ -120,43 +112,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. */ @@ -351,6 +306,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 034f3a9d10..cc62490065 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 @@ -2,11 +2,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( @@ -20,7 +20,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 71b7fa8d37..a379e57673 100644 --- a/core/src/test/kotlin/net/corda/core/internal/AbstractAttachmentTest.kt +++ b/core/src/test/kotlin/net/corda/core/internal/AbstractAttachmentTest.kt @@ -2,13 +2,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 { @@ -36,23 +39,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 2cd762ec4e..24c7e85c78 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 @@ -1,7 +1,7 @@ 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 @@ -15,7 +15,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) { @@ -27,7 +27,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 1fdc9f9bcc..0b4951e0cc 100644 --- a/experimental/behave/src/main/kotlin/net/corda/behave/Utilities.kt +++ b/experimental/behave/src/main/kotlin/net/corda/behave/Utilities.kt @@ -3,6 +3,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 621994a5ca..85855ae5d5 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 @@ -1,14 +1,11 @@ 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 4649a4898a..b329c68e4c 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 @@ -1,9 +1,12 @@ 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 ) { @@ -11,7 +14,7 @@ class LogSource( private val fileRegex = Regex(filePattern ?: ".*") data class MatchedLogContent( - val filename: File, + val filename: Path, val contents: String ) @@ -21,10 +24,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 76a66c9c4e..16491e6c87 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 @@ -3,5 +3,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 9da2bfb63d..2e52f9fe1c 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 @@ -3,7 +3,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 @@ -12,19 +11,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 { @@ -37,7 +37,7 @@ class Network private constructor( private var hasError = false init { - FileUtils.forceMkdir(targetDirectory) + targetDirectory.createDirectories() } class Builder internal constructor( @@ -48,10 +48,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, @@ -92,12 +92,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() ) } @@ -150,7 +149,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 }}") } @@ -164,30 +163,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 da82242968..cbc0d6518f 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 @@ -1,12 +1,14 @@ 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. @@ -21,7 +23,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. @@ -37,43 +39,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 } } @@ -109,7 +107,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 c768e2b377..67eddc6543 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 @@ -4,7 +4,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 @@ -17,11 +16,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 @@ -30,7 +31,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() ) { @@ -219,10 +220,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()) } } @@ -247,7 +248,7 @@ class Node( private var includeFinance = false - private var directory: File? = null + private var directory: Path? = null private var timeout = Duration.ofSeconds(60) @@ -297,7 +298,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 5b625600ee..e28d9c5888 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 @@ -2,10 +2,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, @@ -43,8 +43,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()) } @@ -54,7 +54,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 817d7e56a3..0860cfdb7b 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 @@ -7,14 +7,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 { @@ -49,7 +49,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 674d01b3ab..7d95ae5065 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 @@ -1,12 +1,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 cc9bfd1633..5b4ac767d9 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 @@ -1,10 +1,9 @@ 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) { @@ -103,7 +102,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 eb48fe37ba..8f6d815d82 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 @@ -26,7 +26,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 @@ -105,13 +104,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 f11fa2265e..f4421535c9 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 @@ -1,10 +1,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 @@ -15,7 +12,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 @@ -100,10 +96,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) } } } } @@ -113,7 +109,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 }) { @@ -133,18 +129,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 682b2f85b3..c6458e53a4 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 @@ -6,6 +6,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 @@ -16,10 +17,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.* /** @@ -206,7 +206,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 d4d95ba6fd..f2825bbecd 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 @@ -1,18 +1,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 { @@ -21,9 +23,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 @@ -55,8 +57,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) @@ -76,8 +78,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)) { @@ -94,14 +96,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)) { @@ -120,11 +122,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() { @@ -132,8 +134,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 2769c31798..7e898aa46d 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 @@ -4,8 +4,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 @@ -13,11 +13,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 { @@ -432,8 +432,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 2324930abf..146eba4d2f 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 @@ -1,24 +1,24 @@ 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 @@ -40,9 +40,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) } @@ -70,17 +70,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) @@ -108,10 +108,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) } @@ -174,9 +174,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) @@ -189,9 +189,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) @@ -204,9 +204,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) @@ -349,11 +349,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) } @@ -372,7 +372,7 @@ class EnumEvolveTests { data class C(val e: BadNewValue) - Assertions.assertThatThrownBy { + assertThatThrownBy { SerializationOutput(sf).serialize(C(BadNewValue.A)) }.isInstanceOf(NotSerializableException::class.java) } @@ -389,7 +389,7 @@ class EnumEvolveTests { data class C(val e: OutOfOrder) - Assertions.assertThatThrownBy { + assertThatThrownBy { SerializationOutput(sf).serialize(C(OutOfOrder.A)) }.isInstanceOf(NotSerializableException::class.java) } @@ -413,9 +413,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 cc46273f08..5cb337efa7 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 @@ -5,7 +5,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 @@ -151,8 +150,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) @@ -163,7 +161,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)) @@ -171,8 +169,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) @@ -186,7 +183,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 c7d9795cbb..d126cd1df8 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 @@ -30,7 +30,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 @@ -48,10 +48,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) @@ -72,9 +70,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) @@ -93,9 +90,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) @@ -105,8 +101,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 @@ -120,7 +115,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 @@ -144,9 +139,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) @@ -171,9 +165,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) @@ -197,9 +190,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) @@ -210,9 +202,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 @@ -230,7 +221,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 @@ -253,9 +244,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) @@ -286,9 +276,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) @@ -334,11 +323,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) @@ -347,7 +336,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) @@ -356,7 +345,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) @@ -383,9 +372,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) @@ -438,11 +426,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) @@ -452,7 +440,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) @@ -462,7 +450,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) @@ -500,9 +488,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) @@ -537,7 +524,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") @@ -570,10 +557,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 6490f48522..21a26dde5d 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 @@ -267,7 +267,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 1a85fc784b..d303f0dd52 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 @@ -4,9 +4,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 @@ -73,8 +72,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 // @@ -90,9 +88,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) } @@ -109,8 +107,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 // @@ -132,12 +129,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 516663d17c..3224fb1d4e 100644 --- a/node/src/integration-test/kotlin/net/corda/node/BootTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/BootTests.kt @@ -5,20 +5,21 @@ 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 import net.corda.node.services.Permissions.Companion.startFlow -import net.corda.testing.core.ALICE_NAME -import net.corda.testing.node.User import net.corda.testing.common.internal.ProjectStructure.projectRootDir +import net.corda.testing.core.ALICE_NAME import net.corda.testing.driver.DriverParameters import net.corda.testing.driver.driver +import net.corda.testing.node.User import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy import org.junit.Test import java.io.* -import java.nio.file.Files import kotlin.test.assertEquals class BootTests { @@ -40,13 +41,13 @@ class BootTests { 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 ee2fd4674f..05bd36412b 100644 --- a/node/src/integration-test/kotlin/net/corda/node/CordappConfigFileProviderTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/CordappConfigFileProviderTests.kt @@ -4,57 +4,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 016eaa1f4f..c00b44a24b 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 @@ -8,6 +8,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 @@ -30,15 +31,14 @@ import net.corda.testing.core.TestIdentity import net.corda.testing.driver.DriverDSL import net.corda.testing.driver.NodeHandle import net.corda.testing.driver.driver +import net.corda.testing.internal.MockCordappConfigProvider import net.corda.testing.internal.rigorousMock import net.corda.testing.internal.withoutTestSerialization -import net.corda.testing.internal.MockCordappConfigProvider import net.corda.testing.services.MockAttachmentStorage import org.junit.Assert.assertEquals import org.junit.Rule import org.junit.Test import java.net.URLClassLoader -import java.nio.file.Files import kotlin.test.assertFailsWith class AttachmentLoadingTests { @@ -54,7 +54,7 @@ class AttachmentLoadingTests { private companion object { 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") @@ -74,11 +74,7 @@ class AttachmentLoadingTests { // 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 521edc9bc5..2fee74ceaf 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 @@ -29,7 +29,6 @@ import org.junit.Rule import org.junit.Test import java.net.URL import java.time.Instant -import kotlin.streams.toList class NetworkMapTest { @Rule @@ -197,7 +196,7 @@ class NetworkMapTest { // 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 da2a56fa05..9528078c41 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 @@ -5,6 +5,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 @@ -15,7 +16,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 @@ -65,9 +65,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 d24b4b1811..97e05787f9 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 @@ -93,7 +93,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 81daea5504..dbf4daf657 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 @@ -2,33 +2,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 5cfd21b920..fb29a65633 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 @@ -20,15 +20,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.* @@ -78,8 +76,7 @@ class CordappLoader private constructor(private val cordappJarPaths: List): CordappLoader { @@ -129,31 +126,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 7fc71e37c7..f1897204f3 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 @@ -32,7 +32,6 @@ import net.corda.nodeapi.internal.persistence.contextTransactionOrNull import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.IOException -import java.nio.file.Paths import java.sql.SQLException import java.time.Duration import java.time.Instant @@ -576,7 +575,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 1ba8515fee..368502fb5f 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 @@ -1,10 +1,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 @@ -48,7 +48,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 20e69d5aae..3fef37b3d6 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 @@ -1,5 +1,6 @@ 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 @@ -9,7 +10,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 f339373b51..a5b8e9401a 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 @@ -110,7 +110,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 1b0c685cb9..0c9e83dc60 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/JVMAgentRegistry.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/JVMAgentRegistry.kt @@ -3,6 +3,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 @@ -43,7 +45,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 ff0f8f7916..cefe327322 100644 --- a/node/src/test/kotlin/net/corda/node/ArgsParserTest.kt +++ b/node/src/test/kotlin/net/corda/node/ArgsParserTest.kt @@ -1,6 +1,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 @@ -8,7 +9,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 @@ -140,7 +140,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 4c734bf17b..adc7b7441a 100644 --- a/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt +++ b/node/src/test/kotlin/net/corda/node/internal/NodeTest.kt @@ -3,9 +3,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 @@ -18,7 +19,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 @@ -32,14 +33,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 4c4821d4f5..d07207111b 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 @@ -34,8 +34,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 /** @@ -65,7 +65,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 a1822d0e3a..5a9d2b3a96 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 @@ -1,10 +1,11 @@ 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 @@ -21,8 +22,7 @@ class ProcessUtilitiesTests { @JvmStatic fun main(args: Array) { - val fileNameToCreate = args[0] - FileUtils.write(File(fileNameToCreate), tmpString) + Paths.get(args[0]).writeText(tmpString) } } @@ -31,6 +31,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 36f6661364..fc9430a245 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 @@ -63,8 +63,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 @@ -126,7 +124,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 @@ -1088,16 +1086,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 bbaf5724a5..1ffe04a291 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 @@ -2,6 +2,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 @@ -29,7 +30,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 11ec0e7bb7..3c89bcb97d 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 @@ -3,15 +3,12 @@ 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.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.net.URL import java.nio.file.Path import java.nio.file.Paths import java.time.Instant @@ -45,18 +42,17 @@ 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") - ) { + class Factory(private val buildDirectory: Path = Paths.get("build")) { 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 { @@ -88,7 +84,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 4b4d5cac34..43e6767ebc 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 @@ -2,12 +2,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 bb35d341f1..7ef6ec7a3d 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 @@ -1,6 +1,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.* @@ -113,20 +115,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?) { @@ -195,8 +196,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 3c4aaebe84..62cfb8223c 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 @@ -1,5 +1,6 @@ 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 @@ -93,13 +94,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 2626eb882d..dc253888cf 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 @@ -1,6 +1,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 @@ -37,6 +38,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 148cc9025b..4d8ce5c85a 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 @@ -3,9 +3,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() { @@ -35,17 +36,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 bd1226374a..7ffff3cfbb 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 @@ -3,21 +3,17 @@ 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 import net.corda.demobench.plugin.CordappController import net.corda.demobench.pty.R3Pty -import net.corda.core.node.NetworkParameters -import net.corda.nodeapi.internal.network.NetworkParametersCopier -import net.corda.core.node.NotaryInfo import net.corda.nodeapi.internal.DevIdentityGenerator +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 @@ -121,11 +117,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 { @@ -200,9 +196,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 765824f4e8..566159ac5a 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 @@ -1,18 +1,15 @@ 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() { @@ -44,18 +41,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 45b2a94a5e..90914ee197 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 @@ -4,8 +4,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 @@ -14,7 +13,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 @@ -58,13 +56,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") } } @@ -122,8 +120,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) @@ -136,8 +134,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 f3bfefdd17..a94c427f60 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 @@ -3,6 +3,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 @@ -26,17 +27,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 5d01353c22..9e47e7736b 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 @@ -1,30 +1,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 @@ -41,8 +39,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 19bba7b639..9aee44c69b 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 @@ -4,12 +4,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.* @@ -46,12 +42,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 d09cde66cb..df66ec83f7 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 @@ -1,10 +1,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 @@ -26,9 +26,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 646bc3929b..01efc40be1 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 @@ -108,7 +108,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 9c96317e98..411d7230a3 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 @@ -1,19 +1,18 @@ 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", @@ -32,7 +31,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", @@ -52,7 +52,7 @@ class StandaloneShellArgsParserTest { val options = CommandLineOptionParser().parse(*args) - assertEquals(expectedOptions, options) + assertThat(options).isEqualTo(expectedOptions) } @Test @@ -127,7 +127,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, @@ -166,7 +166,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,