CORDA-742 merge build fixes (#83)

* CORDA-741 changed formatted to true

# Conflicts:
#	gradle-plugins/cordformation/src/main/kotlin/net/corda/plugins/Node.kt

* CORDA-742 Test capsule cache directory

# Conflicts:
#	gradle-plugins/cordformation/src/main/kotlin/net/corda/plugins/Cordform.kt

* CORDA-742 Test capsule cache directory

* CORDA-742 Test capsule cache directory

* CORDA-742 Test capsule cache directory

# Conflicts:
#	gradle-plugins/cordformation/src/main/kotlin/net/corda/plugins/Cordform.kt

* CORDA-742 Refactored back to more parallel execution

# Conflicts:
#	gradle-plugins/cordformation/src/main/kotlin/net/corda/plugins/Cordform.kt

* CORDA-742 Minor refactor

* CORDA-742 Refactors

* CORDA-742 Added constant for cache directory.

* CORDA-742 PR #1951 Moved extension methods into node.

* CORDA-742 PR #1951 Moved extension methods back.

* CORDA-742 PR #1951 Fixed compilation error
This commit is contained in:
Christian Sailer 2017-10-30 10:21:06 +00:00 committed by GitHub
parent fe5b683c1a
commit ea612246c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 29 deletions

View File

@ -11,6 +11,7 @@ import org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME
import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.TaskAction
import java.io.File import java.io.File
import java.net.URLClassLoader import java.net.URLClassLoader
import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -141,8 +142,6 @@ open class Cordform : DefaultTask() {
} }
} }
private fun fullNodePath(node: Node): Path = project.projectDir.toPath().resolve(node.nodeDir.toPath())
private fun generateAndInstallNodeInfos() { private fun generateAndInstallNodeInfos() {
generateNodeInfos() generateNodeInfos()
installNodeInfos() installNodeInfos()
@ -150,35 +149,65 @@ open class Cordform : DefaultTask() {
private fun generateNodeInfos() { private fun generateNodeInfos() {
project.logger.info("Generating node infos") project.logger.info("Generating node infos")
val generateTimeoutSeconds = 60L var nodeProcesses = buildNodeProcesses()
val processes = nodes.map { node ->
project.logger.info("Generating node info for ${fullNodePath(node)}")
val logDir = File(fullNodePath(node).toFile(), "logs")
logDir.mkdirs() // Directory may not exist at this point
Pair(node, ProcessBuilder("java", "-jar", Node.nodeJarName, "--just-generate-node-info")
.directory(fullNodePath(node).toFile())
.redirectErrorStream(true)
// InheritIO causes hangs on windows due the gradle buffer also not being flushed.
// Must redirect to output or logger (node log is still written, this is just startup banner)
.redirectOutput(File(logDir, "generate-info-log.txt"))
.start())
}
try { try {
processes.parallelStream().forEach { (node, process) -> validateNodeProcessess(nodeProcesses)
if (!process.waitFor(generateTimeoutSeconds, TimeUnit.SECONDS)) {
throw GradleException("Node took longer $generateTimeoutSeconds seconds than too to generate node info - see node log at ${fullNodePath(node)}/logs")
} else if (process.exitValue() != 0) {
throw GradleException("Node exited with ${process.exitValue()} when generating node infos - see node log at ${fullNodePath(node)}/logs")
}
}
} finally { } finally {
// This will be a no-op on success - abort remaining on failure destroyNodeProcesses(nodeProcesses)
processes.forEach {
it.second.destroyForcibly()
}
} }
} }
private fun buildNodeProcesses(): Map<Node, Process> {
return nodes
.map { buildNodeProcess(it) }
.toMap()
}
private fun validateNodeProcessess(nodeProcesses: Map<Node, Process>) {
nodeProcesses.forEach { (node, process) ->
validateNodeProcess(node, process)
}
}
private fun destroyNodeProcesses(nodeProcesses: Map<Node, Process>) {
nodeProcesses.forEach { (_, process) ->
process.destroyForcibly()
}
}
private fun buildNodeProcess(node: Node): Pair<Node, Process> {
node.makeLogDirectory()
var process = ProcessBuilder(generateNodeInfoCommand())
.directory(node.fullPath().toFile())
.redirectErrorStream(true)
// InheritIO causes hangs on windows due the gradle buffer also not being flushed.
// Must redirect to output or logger (node log is still written, this is just startup banner)
.redirectOutput(node.logFile().toFile())
.addEnvironment("CAPSULE_CACHE_DIR", Node.capsuleCacheDir)
.start()
return Pair(node, process)
}
private fun generateNodeInfoCommand(): List<String> = listOf(
"java",
"-Dcapsule.log=verbose",
"-Dcapsule.dir=${Node.capsuleCacheDir}",
"-jar",
Node.nodeJarName,
"--just-generate-node-info"
)
private fun validateNodeProcess(node: Node, process: Process) {
val generateTimeoutSeconds = 60L
if (!process.waitFor(generateTimeoutSeconds, TimeUnit.SECONDS)) {
throw GradleException("Node took longer $generateTimeoutSeconds seconds than too to generate node info - see node log at ${node.fullPath()}/logs")
}
if (process.exitValue() != 0) {
throw GradleException("Node exited with ${process.exitValue()} when generating node infos - see node log at ${node.fullPath()}/logs")
}
project.logger.info("Generated node info for ${node.fullPath()}")
}
private fun installNodeInfos() { private fun installNodeInfos() {
project.logger.info("Installing node infos") project.logger.info("Installing node infos")
for (source in nodes) { for (source in nodes) {
@ -186,13 +215,15 @@ open class Cordform : DefaultTask() {
if (source.nodeDir != destination.nodeDir) { if (source.nodeDir != destination.nodeDir) {
project.copy { project.copy {
it.apply { it.apply {
from(fullNodePath(source).toString()) from(source.fullPath().toString())
include("nodeInfo-*") include("nodeInfo-*")
into(fullNodePath(destination).resolve(CordformNode.NODE_INFO_DIRECTORY).toString()) into(destination.fullPath().resolve(CordformNode.NODE_INFO_DIRECTORY).toString())
} }
} }
} }
} }
} }
} }
private fun Node.logFile(): Path = this.logDirectory().resolve("generate-info.log")
private fun ProcessBuilder.addEnvironment(key: String, value: String) = this.apply { environment().put(key, value) }
} }

View File

@ -21,8 +21,13 @@ class Node(private val project: Project) : CordformNode() {
@JvmStatic @JvmStatic
val webJarName = "corda-webserver.jar" val webJarName = "corda-webserver.jar"
private val configFileProperty = "configFile" private val configFileProperty = "configFile"
val capsuleCacheDir: String = "./cache"
} }
fun fullPath(): Path = project.projectDir.toPath().resolve(nodeDir.toPath())
fun logDirectory(): Path = fullPath().resolve("logs")
fun makeLogDirectory() = Files.createDirectories(logDirectory())
/** /**
* Set the list of CorDapps to install to the plugins directory. Each cordapp is a fully qualified Maven * Set the list of CorDapps to install to the plugins directory. Each cordapp is a fully qualified Maven
* dependency name, eg: com.example:product-name:0.1 * dependency name, eg: com.example:product-name:0.1
@ -201,7 +206,12 @@ class Node(private val project: Project) : CordformNode() {
* Installs the configuration file to this node's directory and detokenises it. * Installs the configuration file to this node's directory and detokenises it.
*/ */
private fun installConfig() { private fun installConfig() {
val options = ConfigRenderOptions.defaults().setOriginComments(false).setComments(false).setFormatted(false).setJson(false) val options = ConfigRenderOptions
.defaults()
.setOriginComments(false)
.setComments(false)
.setFormatted(true)
.setJson(false)
val configFileText = config.root().render(options).split("\n").toList() val configFileText = config.root().render(options).split("\n").toList()
// Need to write a temporary file first to use the project.copy, which resolves directories correctly. // Need to write a temporary file first to use the project.copy, which resolves directories correctly.