From 24e9ceac484f3ed42a929a095010aed1d168db70 Mon Sep 17 00:00:00 2001 From: Michele Sollecito Date: Fri, 2 Nov 2018 11:36:28 +0000 Subject: [PATCH 1/3] [ENT-2678] PluginRegistrationTest is failing (fix) (OS part) (#4153) --- config/dev/log4j2.xml | 7 ++- .../node/logging/ErrorCodeLoggingTests.kt | 48 +++++++++++++++++++ .../net/corda/node/internal/NodeStartup.kt | 5 +- .../subcommands/ValidateConfigurationCli.kt | 4 +- .../resources/log4j2.component.properties | 2 +- .../net/corda/cliutils/CordaCliWrapper.kt | 7 +-- .../cliutils/CordaLog4j2ConfigFactory.kt | 9 ++-- 7 files changed, 64 insertions(+), 18 deletions(-) create mode 100644 node/src/integration-test/kotlin/net/corda/node/logging/ErrorCodeLoggingTests.kt diff --git a/config/dev/log4j2.xml b/config/dev/log4j2.xml index 3ed3eea003..bb2bdbeb70 100644 --- a/config/dev/log4j2.xml +++ b/config/dev/log4j2.xml @@ -1,13 +1,12 @@ - + ${sys:log-path:-logs} node-${hostName} ${log-path}/archive - ${sys:log4j2.level:-info} + ${sys:defaultLogLevel:-info} ${sys:consoleLogLevel:-error} - ${sys:fileLogLevel:-${defaultLogLevel}} @@ -78,7 +77,7 @@ - + diff --git a/node/src/integration-test/kotlin/net/corda/node/logging/ErrorCodeLoggingTests.kt b/node/src/integration-test/kotlin/net/corda/node/logging/ErrorCodeLoggingTests.kt new file mode 100644 index 0000000000..3b07bcbb49 --- /dev/null +++ b/node/src/integration-test/kotlin/net/corda/node/logging/ErrorCodeLoggingTests.kt @@ -0,0 +1,48 @@ +package net.corda.node.logging + +import net.corda.core.flows.FlowLogic +import net.corda.core.flows.InitiatingFlow +import net.corda.core.flows.StartableByRPC +import net.corda.core.internal.div +import net.corda.core.messaging.FlowHandle +import net.corda.core.messaging.startFlow +import net.corda.core.utilities.getOrThrow +import net.corda.testing.driver.DriverParameters +import net.corda.testing.driver.NodeHandle +import net.corda.testing.driver.driver +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test +import java.io.File + +class ErrorCodeLoggingTests { + @Test + fun `log entries with a throwable and ERROR or WARN get an error code appended`() { + driver(DriverParameters(notarySpecs = emptyList())) { + val node = startNode(startInSameProcess = false).getOrThrow() + node.rpc.startFlow(::MyFlow).waitForCompletion() + val logFile = node.logFile() + + val linesWithErrorCode = logFile.useLines { lines -> lines.filter { line -> line.contains("[errorCode=") }.toList() } + + assertThat(linesWithErrorCode).isNotEmpty + } + } + + @StartableByRPC + @InitiatingFlow + class MyFlow : FlowLogic() { + override fun call(): String { + throw IllegalArgumentException("Mwahahahah") + } + } +} + +private fun FlowHandle<*>.waitForCompletion() { + try { + returnValue.getOrThrow() + } catch (e: Exception) { + // This is expected to throw an exception, using getOrThrow() just to wait until done. + } +} + +private fun NodeHandle.logFile(): File = (baseDirectory / "logs").toFile().walk().filter { it.name.startsWith("node-") && it.extension == "log" }.single() \ No newline at end of file diff --git a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt index 047898c1da..628a4e2508 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt @@ -426,10 +426,9 @@ interface NodeStartupLogging { } fun CliWrapperBase.initLogging(baseDirectory: Path) { - val loggingLevel = loggingLevel.name.toLowerCase(Locale.ENGLISH) - System.setProperty("defaultLogLevel", loggingLevel) // These properties are referenced from the XML config file. + System.setProperty("defaultLogLevel", specifiedLogLevel) // These properties are referenced from the XML config file. if (verbose) { - System.setProperty("consoleLogLevel", loggingLevel) + System.setProperty("consoleLogLevel", specifiedLogLevel) Node.renderBasicInfoToConsole = false } System.setProperty("log-path", (baseDirectory / NodeCliCommand.LOGS_DIRECTORY_NAME).toString()) diff --git a/node/src/main/kotlin/net/corda/node/internal/subcommands/ValidateConfigurationCli.kt b/node/src/main/kotlin/net/corda/node/internal/subcommands/ValidateConfigurationCli.kt index 8c93c64cad..2cf2544fa8 100644 --- a/node/src/main/kotlin/net/corda/node/internal/subcommands/ValidateConfigurationCli.kt +++ b/node/src/main/kotlin/net/corda/node/internal/subcommands/ValidateConfigurationCli.kt @@ -17,7 +17,7 @@ import java.nio.file.Path internal class ValidateConfigurationCli : CliWrapperBase("validate-configuration", "Validate the configuration without starting the node.") { internal companion object { - private val logger = loggerFor() + private val logger by lazy { loggerFor() } internal fun logConfigurationErrors(errors: Iterable, configFile: Path) { errors.forEach { error -> @@ -56,7 +56,7 @@ internal class ValidateConfigurationCli : CliWrapperBase("validate-configuration internal fun SharedNodeCmdLineOptions.nodeConfiguration(): Valid = NodeConfigurationParser.invoke(this) private object NodeConfigurationParser : (SharedNodeCmdLineOptions) -> Valid { - private val logger = loggerFor() + private val logger by lazy { loggerFor() } private val configRenderingOptions = ConfigRenderOptions.defaults().setComments(false).setOriginComments(false).setFormatted(true) diff --git a/node/src/main/resources/log4j2.component.properties b/node/src/main/resources/log4j2.component.properties index 1b55982139..40a6560d2f 100644 --- a/node/src/main/resources/log4j2.component.properties +++ b/node/src/main/resources/log4j2.component.properties @@ -1,2 +1,2 @@ -Log4jContextSelector=net.corda.node.utilities.logging.AsyncLoggerContextSelectorNoThreadLocal +log4jContextSelector=net.corda.node.utilities.logging.AsyncLoggerContextSelectorNoThreadLocal AsyncLogger.RingBufferSize=262144 \ No newline at end of file diff --git a/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaCliWrapper.kt b/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaCliWrapper.kt index 21c8fb5507..fd7fa5fd11 100644 --- a/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaCliWrapper.kt +++ b/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaCliWrapper.kt @@ -137,10 +137,9 @@ abstract class CliWrapperBase(val alias: String, val description: String) : Call // This needs to be called before loggers (See: NodeStartup.kt:51 logger called by lazy, initLogging happens before). // Node's logging is more rich. In corda configurations two properties, defaultLoggingLevel and consoleLogLevel, are usually used. open fun initLogging() { - val loggingLevel = loggingLevel.name.toLowerCase(Locale.ENGLISH) - System.setProperty("defaultLogLevel", loggingLevel) // These properties are referenced from the XML config file. + System.setProperty("defaultLogLevel", specifiedLogLevel) // These properties are referenced from the XML config file. if (verbose) { - System.setProperty("consoleLogLevel", loggingLevel) + System.setProperty("consoleLogLevel", specifiedLogLevel) } System.setProperty("log-path", Paths.get(".").toString()) } @@ -154,6 +153,8 @@ abstract class CliWrapperBase(val alias: String, val description: String) : Call logger.info("Application Args: ${args.joinToString(" ")}") return runProgram() } + + val specifiedLogLevel: String by lazy { System.getProperty("log4j2.level")?.toLowerCase(Locale.ENGLISH) ?: loggingLevel.name.toLowerCase(Locale.ENGLISH) } } /** diff --git a/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaLog4j2ConfigFactory.kt b/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaLog4j2ConfigFactory.kt index 1dc245b26a..2f0931d9ba 100644 --- a/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaLog4j2ConfigFactory.kt +++ b/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaLog4j2ConfigFactory.kt @@ -10,9 +10,8 @@ import org.apache.logging.log4j.core.config.xml.XmlConfiguration import org.apache.logging.log4j.core.impl.LogEventFactory @Plugin(name = "CordaLog4j2ConfigFactory", category = "ConfigurationFactory") -@Order(10) +@Order(Integer.MAX_VALUE) class CordaLog4j2ConfigFactory : ConfigurationFactory() { - private companion object { private val SUPPORTED_TYPES = arrayOf(".xml", "*") } @@ -22,13 +21,13 @@ class CordaLog4j2ConfigFactory : ConfigurationFactory() { override fun getSupportedTypes() = SUPPORTED_TYPES private class ErrorCodeAppendingConfiguration(loggerContext: LoggerContext, source: ConfigurationSource) : XmlConfiguration(loggerContext, source) { - override fun doConfigure() { - super.doConfigure() loggers.values.forEach { val existingFactory = it.logEventFactory - it.logEventFactory = LogEventFactory { loggerName, marker, fqcn, level, message, properties, error -> existingFactory.createEvent(loggerName, marker, fqcn, level, message?.withErrorCodeFor(error, level), properties, error) } + it.logEventFactory = LogEventFactory { loggerName, marker, fqcn, level, message, properties, error -> + existingFactory.createEvent(loggerName, marker, fqcn, level, message?.withErrorCodeFor(error, level), properties, error) + } } } } From 094eb266a812ea492e8f38c6602c14755e0dc25c Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Fri, 2 Nov 2018 13:44:18 +0200 Subject: [PATCH 2/3] [CORDA-2174] Fix demo node startup (#4151) - Make issuableCurrencies config optional - Allow additionalCordapps to override cordappsForAllNodes In driver DSL when passing additionalCordapps to startNode and one of the CordApps is also in cordappsForAllNodes will lead to confilc. This commit is resolving the conflict by using the CordApp provided by additionalCordapps --- .../net/corda/finance/internal/CashConfigDataFlow.kt | 7 ++++++- .../net/corda/testing/node/internal/DriverDSLImpl.kt | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/finance/src/main/kotlin/net/corda/finance/internal/CashConfigDataFlow.kt b/finance/src/main/kotlin/net/corda/finance/internal/CashConfigDataFlow.kt index 3c2ab3c988..020667c174 100644 --- a/finance/src/main/kotlin/net/corda/finance/internal/CashConfigDataFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/internal/CashConfigDataFlow.kt @@ -24,7 +24,12 @@ class ConfigHolder(services: AppServiceHub) : SingletonSerializeAsToken() { val issuableCurrencies: List init { - val issuableCurrenciesStringList: List = uncheckedCast(services.getAppContext().config.get("issuableCurrencies")) + val config = services.getAppContext().config + val issuableCurrenciesStringList: List = if (config.exists("issuableCurrencies")) { + uncheckedCast(config.get("issuableCurrencies")) + } else { + emptyList() + } issuableCurrencies = issuableCurrenciesStringList.map(Currency::getInstance) (issuableCurrencies - supportedCurrencies).let { require(it.isEmpty()) { "$it are not supported currencies" } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt index 45dcbf077d..36e54c297e 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt @@ -595,7 +595,12 @@ class DriverDSLImpl( emptyList() } - val cordappDirectories = existingCorDappDirectoriesOption + (cordappsForAllNodes + additionalCordapps).map { TestCordappDirectories.getJarDirectory(it).toString() } + // Instead of using cordappsForAllNodes we get only these that are missing from additionalCordapps + // This way we prevent errors when we want the same CordApp but with different config + val appOverrides = additionalCordapps.map { it.name to it.version}.toSet() + val baseCordapps = cordappsForAllNodes.filter { !appOverrides.contains(it.name to it.version) } + + val cordappDirectories = existingCorDappDirectoriesOption + (baseCordapps + additionalCordapps).map { TestCordappDirectories.getJarDirectory(it).toString() } val config = NodeConfig(specifiedConfig.typesafe.withValue(NodeConfiguration.cordappDirectoriesKey, ConfigValueFactory.fromIterable(cordappDirectories.toSet()))) From 460cf3480fa15e6570bbe8698310f951af35a41f Mon Sep 17 00:00:00 2001 From: Andrius Dagys Date: Fri, 2 Nov 2018 14:23:57 +0000 Subject: [PATCH 3/3] ENT-1858: Minor fix for a uniqueness provider test --- .../transactions/PersistentUniquenessProviderTests.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt index daa8132459..540991b887 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt @@ -50,11 +50,12 @@ class PersistentUniquenessProviderTests { } @Test - fun `should commit a transaction with unused inputs without exception`() { + fun `should successfully commit a transaction with unused inputs`() { val provider = PersistentUniquenessProvider(Clock.systemUTC(), database, TestingNamedCacheFactory()) val inputState = generateStateRef() - provider.commit(listOf(inputState), txID, identity, requestSignature).get() + val result = provider.commit(listOf(inputState), txID, identity, requestSignature).get() + assertEquals(UniquenessProvider.Result.Success, result) } @Test @@ -64,7 +65,8 @@ class PersistentUniquenessProviderTests { val inputs = listOf(inputState) val firstTxId = txID - provider.commit(inputs, firstTxId, identity, requestSignature).get() + val result = provider.commit(inputs, firstTxId, identity, requestSignature).get() + assertEquals(UniquenessProvider.Result.Success, result) val secondTxId = SecureHash.randomSHA256()