mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
ENT-4334 Configuration option to exclude packages from Quasar instrumentation (#6005)
* Add quasarExcludePackages configuration option * Change quasarExcludePackages to quasar.excludePackages * Add doc comment for QuasarConfiguration * Use forEach method * Fix rule violation (TooGenericExceptionThrown) * Mention new configuration option in changelog * Remove outer section from new quasarExcludePackages configuration option
This commit is contained in:
parent
2887dd0c88
commit
217926092d
@ -109,6 +109,8 @@ Unreleased
|
||||
options, as well as ``extensions.sshd`` configuration entry, have been removed from the standalone shell.
|
||||
Available alternatives are either to use the standalone shell directly, or connect to the node embedded shell via SSH.
|
||||
|
||||
* Added new node configuration option to exclude packages from Quasar instrumentation.
|
||||
|
||||
.. _changelog_v4.1:
|
||||
|
||||
Version 4.1
|
||||
|
@ -558,7 +558,19 @@ p2pAddress
|
||||
|
||||
|
||||
*Default:* not defined
|
||||
|
||||
|
||||
quasarExcludePackages
|
||||
A list of packages to exclude from Quasar instrumentation. Wildcards are allowed, for example ``org.xml**``.
|
||||
|
||||
**Important: Do not change unless requested by support.**
|
||||
|
||||
*Default:* empty list
|
||||
|
||||
Example configuration:
|
||||
|
||||
.. parsed-literal::
|
||||
quasarExcludePackages=["org.xml**", "org.yaml**"]
|
||||
|
||||
rpcAddress (deprecated)
|
||||
The address of the RPC system on which RPC requests can be made to the node.
|
||||
If not provided then the node will run without RPC.
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.node.internal
|
||||
|
||||
import co.paralleluniverse.fibers.instrument.Retransform
|
||||
import com.codahale.metrics.MetricRegistry
|
||||
import com.google.common.collect.MutableClassToInstanceMap
|
||||
import com.google.common.util.concurrent.MoreExecutors
|
||||
@ -227,6 +228,8 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
||||
MoreExecutors.shutdownAndAwaitTermination(it, 50, SECONDS)
|
||||
}
|
||||
}
|
||||
|
||||
quasarExcludePackages(configuration)
|
||||
}
|
||||
|
||||
private val notaryLoader = configuration.notary?.let {
|
||||
@ -420,6 +423,14 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
|
||||
return validateKeyStores()
|
||||
}
|
||||
|
||||
private fun quasarExcludePackages(nodeConfiguration: NodeConfiguration) {
|
||||
val quasarInstrumentor = Retransform.getInstrumentor()
|
||||
|
||||
nodeConfiguration.quasarExcludePackages.forEach { packageExclude ->
|
||||
quasarInstrumentor.addExcludedPackage(packageExclude)
|
||||
}
|
||||
}
|
||||
|
||||
open fun generateAndSaveNodeInfo(): NodeInfo {
|
||||
check(started == null) { "Node has already been started" }
|
||||
log.info("Generating nodeInfo ...")
|
||||
|
@ -90,6 +90,8 @@ interface NodeConfiguration : ConfigurationWithOptionsContainer {
|
||||
|
||||
val flowExternalOperationThreadPoolSize: Int
|
||||
|
||||
val quasarExcludePackages: List<String>
|
||||
|
||||
companion object {
|
||||
// default to at least 8MB and a bit extra for larger heap sizes
|
||||
val defaultTransactionCacheSize: Long = 8.MB + getAdditionalCacheMemory()
|
||||
|
@ -82,7 +82,8 @@ data class NodeConfigurationImpl(
|
||||
Defaults.networkParameterAcceptanceSettings,
|
||||
override val blacklistedAttachmentSigningKeys: List<String> = Defaults.blacklistedAttachmentSigningKeys,
|
||||
override val configurationWithOptions: ConfigurationWithOptions,
|
||||
override val flowExternalOperationThreadPoolSize: Int = Defaults.flowExternalOperationThreadPoolSize
|
||||
override val flowExternalOperationThreadPoolSize: Int = Defaults.flowExternalOperationThreadPoolSize,
|
||||
override val quasarExcludePackages: List<String> = Defaults.quasarExcludePackages
|
||||
) : NodeConfiguration {
|
||||
internal object Defaults {
|
||||
val jmxMonitoringHttpPort: Int? = null
|
||||
@ -119,6 +120,7 @@ data class NodeConfigurationImpl(
|
||||
val networkParameterAcceptanceSettings: NetworkParameterAcceptanceSettings = NetworkParameterAcceptanceSettings()
|
||||
val blacklistedAttachmentSigningKeys: List<String> = emptyList()
|
||||
const val flowExternalOperationThreadPoolSize: Int = 1
|
||||
val quasarExcludePackages: List<String> = emptyList()
|
||||
|
||||
fun cordappsDirectories(baseDirectory: Path) = listOf(baseDirectory / CORDAPPS_DIR_NAME_DEFAULT)
|
||||
|
||||
|
@ -64,6 +64,7 @@ internal object V1NodeConfigurationSpec : Configuration.Specification<NodeConfig
|
||||
.optional()
|
||||
.withDefaultValue(Defaults.networkParameterAcceptanceSettings)
|
||||
private val flowExternalOperationThreadPoolSize by int().optional().withDefaultValue(Defaults.flowExternalOperationThreadPoolSize)
|
||||
private val quasarExcludePackages by string().list().optional().withDefaultValue(Defaults.quasarExcludePackages)
|
||||
@Suppress("unused")
|
||||
private val custom by nestedObject().optional()
|
||||
@Suppress("unused")
|
||||
@ -128,7 +129,8 @@ internal object V1NodeConfigurationSpec : Configuration.Specification<NodeConfig
|
||||
blacklistedAttachmentSigningKeys = configuration[blacklistedAttachmentSigningKeys],
|
||||
networkParameterAcceptanceSettings = configuration[networkParameterAcceptanceSettings],
|
||||
configurationWithOptions = ConfigurationWithOptions(configuration, Configuration.Validation.Options.defaults),
|
||||
flowExternalOperationThreadPoolSize = configuration[flowExternalOperationThreadPoolSize]
|
||||
flowExternalOperationThreadPoolSize = configuration[flowExternalOperationThreadPoolSize],
|
||||
quasarExcludePackages = configuration[quasarExcludePackages]
|
||||
))
|
||||
} catch (e: Exception) {
|
||||
return when (e) {
|
||||
|
@ -0,0 +1,64 @@
|
||||
package net.corda.node.internal
|
||||
|
||||
import co.paralleluniverse.fibers.instrument.Retransform
|
||||
import com.typesafe.config.Config
|
||||
import net.corda.core.internal.toPath
|
||||
import net.corda.node.VersionInfo
|
||||
import net.corda.node.services.config.ConfigHelper
|
||||
import net.corda.node.services.config.NodeConfiguration
|
||||
import net.corda.node.services.config.schema.v1.V1NodeConfigurationSpec
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class QuasarExcludePackagesTest {
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `quasarExcludePackages default is empty list`() {
|
||||
|
||||
// Arrange
|
||||
val config = getConfig("working-config.conf")
|
||||
|
||||
// Act
|
||||
val nodeConfiguration :NodeConfiguration = V1NodeConfigurationSpec.parse(config).value()
|
||||
|
||||
// Assert
|
||||
Assert.assertEquals(emptyList<String>(), nodeConfiguration.quasarExcludePackages)
|
||||
}
|
||||
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `quasarExcludePackages is read from configuration`() {
|
||||
|
||||
// Arrange
|
||||
val config = getConfig("test-config-quasarexcludepackages.conf")
|
||||
|
||||
// Act
|
||||
val nodeConfiguration :NodeConfiguration = V1NodeConfigurationSpec.parse(config).value()
|
||||
|
||||
// Assert
|
||||
Assert.assertEquals(listOf("net.corda.node.internal.QuasarExcludePackagesTest**"), nodeConfiguration.quasarExcludePackages)
|
||||
}
|
||||
|
||||
@Test(timeout=300_000)
|
||||
fun `quasarExcludePackages is passed through to QuasarInstrumentor`() {
|
||||
|
||||
// Arrange
|
||||
val config = getConfig("test-config-quasarexcludepackages.conf")
|
||||
val nodeConfiguration :NodeConfiguration = V1NodeConfigurationSpec.parse(config).value()
|
||||
|
||||
// Act
|
||||
val node = Node(nodeConfiguration, VersionInfo.UNKNOWN)
|
||||
node.stop()
|
||||
|
||||
// Assert
|
||||
Assert.assertTrue(Retransform.getInstrumentor().isExcluded("net.corda.node.internal.QuasarExcludePackagesTest.Test"))
|
||||
}
|
||||
|
||||
class ResourceMissingException(message: String) : Exception(message)
|
||||
|
||||
private fun getConfig(cfgName: String): Config {
|
||||
val resource = this::class.java.classLoader.getResource(cfgName) ?: throw ResourceMissingException("Resource not found")
|
||||
val path = resource.toPath()
|
||||
return ConfigHelper.loadConfig(path.parent, path)
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
myLegalName = "O=Alice Corp, L=Madrid, C=ES"
|
||||
emailAddress = "admin@company.com"
|
||||
keyStorePassword = "cordacadevpass"
|
||||
trustStorePassword = "trustpass"
|
||||
crlCheckSoftFail = true
|
||||
baseDirectory = "/opt/corda"
|
||||
cordappDirectories = ["./myCorDapps1", "./myCorDapps2"]
|
||||
dataSourceProperties = {
|
||||
dataSourceClassName = org.h2.jdbcx.JdbcDataSource
|
||||
dataSource.url = "jdbc:h2:file:blah"
|
||||
dataSource.user = "sa"
|
||||
dataSource.password = ""
|
||||
}
|
||||
database = {
|
||||
transactionIsolationLevel = "REPEATABLE_READ"
|
||||
exportHibernateJMXStatistics = "false"
|
||||
}
|
||||
p2pAddress = "localhost:2233"
|
||||
h2port = 0
|
||||
useTestClock = false
|
||||
verifierType = InMemory
|
||||
rpcSettings = {
|
||||
address = "locahost:3418"
|
||||
adminAddress = "localhost:3419"
|
||||
useSsl = false
|
||||
standAloneBroker = false
|
||||
}
|
||||
flowTimeout {
|
||||
timeout = 30 seconds
|
||||
maxRestartCount = 3
|
||||
backoffBase = 2.0
|
||||
}
|
||||
quasarExcludePackages = [ "net.corda.node.internal.QuasarExcludePackagesTest**" ]
|
@ -461,6 +461,7 @@ open class InternalMockNetwork(cordappPackages: List<String> = emptyList(),
|
||||
doReturn(makeTestDataSourceProperties("node_${id}_net_$networkId")).whenever(it).dataSourceProperties
|
||||
doReturn(emptyList<SecureHash>()).whenever(it).extraNetworkMapKeys
|
||||
doReturn(listOf(baseDirectory / "cordapps")).whenever(it).cordappDirectories
|
||||
doReturn(emptyList<String>()).whenever(it).quasarExcludePackages
|
||||
parameters.configOverrides(it)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user