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.
This commit is contained in:
Shams Asari 2018-04-23 14:31:49 +01:00 committed by GitHub
parent 3aaa176dd4
commit d3446e213c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 661 additions and 526 deletions

View File

@ -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 <T> List<T>.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 <R> Path.list(block: (Stream<Path>) -> R): R = Files.list(this).use(block)
fun Path.deleteIfExists(): Boolean = Files.deleteIfExists(this)
fun Path.reader(charset: Charset = UTF_8): BufferedReader = Files.newBufferedReader(this, charset)
fun Path.writer(charset: Charset = UTF_8, vararg options: OpenOption): BufferedWriter = Files.newBufferedWriter(this, charset, *options)
fun Path.readAll(): ByteArray = Files.readAllBytes(this)
inline fun <R> Path.read(vararg options: OpenOption, block: (InputStream) -> R): R = Files.newInputStream(this, *options).use(block)
inline fun Path.write(createDirs: Boolean = false, vararg options: OpenOption = emptyArray(), block: (OutputStream) -> Unit) {
if (createDirs) {
normalize().parent?.createDirectories()
}
Files.newOutputStream(this, *options).use(block)
}
inline fun <R> Path.readLines(charset: Charset = UTF_8, block: (Stream<String>) -> R): R = Files.lines(this, charset).use(block)
fun Path.readAllLines(charset: Charset = UTF_8): List<String> = Files.readAllLines(this, charset)
fun Path.writeLines(lines: Iterable<CharSequence>, charset: Charset = UTF_8, vararg options: OpenOption): Path = Files.write(this, lines, charset, *options)
inline fun <reified T : Any> Path.readObject(): T = readAll().deserialize()
/** Calculate the hash of the contents of this file. */
val Path.hash: SecureHash get() = read { it.hash() }
fun InputStream.copyTo(target: Path, vararg options: CopyOption): Long = Files.copy(this, target, *options)
/** 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<String, String>): ByteArray {

View File

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

View File

@ -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<SerializationCustomSerializer<*, *>>,
override val customSchemas: Set<MappedSchema>,
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

View File

@ -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

View File

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

View File

@ -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<NodeConfiguration>(
readAndCheckConfigurations(
"example-node.conf",
"example-out-of-process-verifier-node.conf"
) {

View File

@ -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())

View File

@ -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

View File

@ -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<MatchedLogContent>()
for (file in logFiles) {
val contents = file.readText()

View File

@ -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 <reified T> getLogger(): Logger =
LoggerFactory.getLogger(T::class.java)

View File

@ -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<String, Node>,
private val targetDirectory: File,
private val targetDirectory: Path,
private val timeout: Duration = 2.minutes
) : Closeable, Iterable<Node> {
@ -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) {

View File

@ -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

View File

@ -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
}

View File

@ -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<Configuration>()
val DEFAULT_PASSWORD = "S0meS3cretW0rd"
const val DEFAULT_PASSWORD = "S0meS3cretW0rd"
}
}

View File

@ -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<String>,
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()

View File

@ -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<String>,
directory: File,
directory: Path,
timeout: Duration,
enableRemoteDebugging: Boolean = false
) : Command(

View File

@ -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<String>, cordappDirectory, 1.minutes)
command.start()

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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)
}

View File

@ -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<AssertionError, Unit>(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<AssertionError, Unit>(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)
}
}

View File

@ -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<WrapsUnknown>(sb1)).envelope

View File

@ -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<C>(File(path.toURI()).readBytes()))
val obj = DeserializationInput(sf).deserialize(SerializedBytes<C>(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<C>(File(path1.toURI()).readBytes()))
val obj1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(url1.readBytes()))
// D will transform directly to C
val obj2 = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path2.toURI()).readBytes()))
val obj2 = DeserializationInput(sf).deserialize(SerializedBytes<C>(url2.readBytes()))
// E will have to transform from E -> D -> C to work, so this should exercise that part
// of the evolution code
val obj3 = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path3.toURI()).readBytes()))
val obj3 = DeserializationInput(sf).deserialize(SerializedBytes<C>(url3.readBytes()))
assertEquals(DeserializeNewerSetToUnknown2.C, obj1.e)
assertEquals(DeserializeNewerSetToUnknown2.C, 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<C>(File(path.toURI()).readBytes()))
assertThatThrownBy {
DeserializationInput(sf).deserialize(SerializedBytes<C>(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<C>(File(path1_AA.toURI()).readBytes()))
val obj1_B = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path1_B.toURI()).readBytes()))
val obj1_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path1_C.toURI()).readBytes()))
val obj1_AA = DeserializationInput(sf).deserialize(SerializedBytes<C>(path1_AA.readBytes()))
val obj1_B = DeserializationInput(sf).deserialize(SerializedBytes<C>(path1_B.readBytes()))
val obj1_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(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<C>(File(path2_AA.toURI()).readBytes()))
val obj2_BB = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path2_BB.toURI()).readBytes()))
val obj2_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path2_C.toURI()).readBytes()))
val obj2_AA = DeserializationInput(sf).deserialize(SerializedBytes<C>(path2_AA.readBytes()))
val obj2_BB = DeserializationInput(sf).deserialize(SerializedBytes<C>(path2_BB.readBytes()))
val obj2_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(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<C>(File(path3_AA.toURI()).readBytes()))
val obj3_XX = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path3_XX.toURI()).readBytes()))
val obj3_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(File(path3_C.toURI()).readBytes()))
val obj3_AA = DeserializationInput(sf).deserialize(SerializedBytes<C>(path3_AA.readBytes()))
val obj3_XX = DeserializationInput(sf).deserialize(SerializedBytes<C>(path3_XX.readBytes()))
val obj3_C = DeserializationInput(sf).deserialize(SerializedBytes<C>(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<Pair<String, MultiOperations>>) = 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<C>(
File(EvolvabilityTests::class.java.getResource(it.first).toURI()).readBytes())), it.second)
EvolvabilityTests::class.java.getResource(it.first).readBytes())), it.second)
}
load(stage1Resources).forEach { assertEquals(it.second, it.first.e) }
@ -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<C>(
File(EvolvabilityTests::class.java.getResource(resource).toURI()).readBytes()))
EvolvabilityTests::class.java.getResource(resource).readBytes()))
}.isInstanceOf(NotSerializableException::class.java)
}
}

View File

@ -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<C>(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<C>(sc2))

View File

@ -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<C>(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<C>(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<C>(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<CC>(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<CC>(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<CC>(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<CC>(f.readBytes()))
DeserializationInput(sf).deserialize(SerializedBytes<CC>(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<CC>(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<CC>(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<C>(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<C>(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<C>(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<Outer>(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<C>(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<C>(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<C>(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<SignedData<NetworkParameters>>(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<C>(sc2))
assertEquals(1, deserializedC.a)

View File

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

View File

@ -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<D>(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<D>(bytes))
}.isInstanceOf(NotSerializableException::class.java)
}

View File

@ -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)
}
}

View File

@ -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()))
}

View File

@ -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) }
}
}

View File

@ -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)
}

View File

@ -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

View File

@ -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)

View File

@ -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<CordappConfigFileProvider>()
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()
}
}
}
}

View File

@ -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<Restri
* Create a dev mode CordappLoader for test environments that creates and loads cordapps from the classpath
* and cordapps directory. This is intended mostly for use by the driver.
*
* @param baseDir See [createDefault.baseDir]
* @param testPackages See [createWithTestPackages.testPackages]
* @param testPackages See [createWithTestPackages]
*/
@VisibleForTesting
fun createDefaultWithTestPackages(configuration: NodeConfiguration, testPackages: List<String>): CordappLoader {
@ -129,31 +126,26 @@ class CordappLoader private constructor(private val cordappJarPaths: List<Restri
}
/** Takes a package of classes and creates a JAR from them - only use in tests. */
private fun createDevCordappJar(scanPackage: String, path: URL, jarPackageName: String): URI {
if (!generatedCordapps.contains(path)) {
val cordappDir = File("build/tmp/generated-test-cordapps")
cordappDir.mkdirs()
val cordappJAR = File(cordappDir, "$scanPackage-${UUID.randomUUID()}.jar")
private fun createDevCordappJar(scanPackage: String, url: URL, jarPackageName: String): URI {
return generatedCordapps.computeIfAbsent(url) {
val cordappDir = (Paths.get("build") / "tmp" / "generated-test-cordapps").createDirectories()
val cordappJAR = cordappDir / "$scanPackage-${UUID.randomUUID()}.jar"
logger.info("Generating a test-only cordapp of classes discovered in $scanPackage at $cordappJAR")
FileOutputStream(cordappJAR).use {
JarOutputStream(it).use { jos ->
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<RestrictedURL> {

View File

@ -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<out FlowLogic<*>>.flowVersionAndInitiatingClass: Pair<Int, Class<out F
val Class<out FlowLogic<*>>.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 {

View File

@ -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<NetworkHostAndPort>, 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)
}

View File

@ -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()
}
}

View File

@ -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)
}

View File

@ -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 }
}
}

View File

@ -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()
}
}

View File

@ -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<SignedNodeInfo>().raw.deserialize()
Files.delete(path)
return nodeInfo
val path = nodeInfoFile()!!
try {
return path.readObject<SignedNodeInfo>().verified()
} finally {
path.delete()
}
}
@Test

View File

@ -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) {

View File

@ -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<String>) {
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<ProcessUtilitiesTests>(listOf(tmpFile.absolutePath))
assertTrue { startedProcess.waitFor(20, TimeUnit.SECONDS) }
assertEquals(tmpString, FileUtils.readFileToString(tmpFile))
assertEquals(tmpString, tmpFile.toPath().readText())
}
}

View File

@ -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<String, Any>) = withValue(property.first, ConfigValueFactory.fromAnyRef(property.second))

View File

@ -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()
}
/**

View File

@ -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)

View File

@ -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
}

View File

@ -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) {

View File

@ -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)
}
}
}

View File

@ -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)
}

View File

@ -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()
}

View File

@ -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
}

View File

@ -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<Path> = walkCordapps(config.cordappsDir)
.filter { !bankOfCorda.endsWith(it.fileName) }
.filter { !finance.endsWith(it.fileName) }
private fun walkCordapps(cordappsDir: Path): Stream<Path> {
return if (Files.isDirectory(cordappsDir))
Files.walk(cordappsDir, 1).filter(Path::isCordapp)
else
Stream.empty()
fun useCordappsFor(config: HasCordapps): List<Path> {
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/")

View File

@ -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) }
}

View File

@ -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<URI> {
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

View File

@ -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
}

View File

@ -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 <T> Properties.getValue(receiver: Any, metadata: KProperty<*>): T {
return when (metadata.returnType.javaType) {

View File

@ -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)

View File

@ -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"
}

View File

@ -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<InputStream>() {
private val streams = Collections.synchronizedSet(HashSet<InputStream>())
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): InputStream {
val stream = object : BufferedInputStream(Files.newInputStream(Paths.get(p.text))) {
val stream = object : BufferedInputStream(Paths.get(p.text).inputStream()) {
override fun close() {
super.close()
streams.remove(this)

View File

@ -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,