Add optional debug options to config and allow to switch checkpointChecking off in dev mode

This commit is contained in:
Christian Sailer 2017-10-24 15:58:17 +01:00
parent 71fe0daa08
commit 74595c65c9
4 changed files with 78 additions and 6 deletions

View File

@ -28,6 +28,7 @@ interface NodeConfiguration : NodeSSLConfiguration {
val database: Properties? val database: Properties?
val rpcUsers: List<User> val rpcUsers: List<User>
val devMode: Boolean val devMode: Boolean
val debugOptions: Properties?
val certificateSigningService: URL val certificateSigningService: URL
val certificateChainCheckPolicies: List<CertChainPolicyConfig> val certificateChainCheckPolicies: List<CertChainPolicyConfig>
val verifierType: VerifierType val verifierType: VerifierType
@ -93,6 +94,7 @@ data class FullNodeConfiguration(
override val notary: NotaryConfig?, override val notary: NotaryConfig?,
override val certificateChainCheckPolicies: List<CertChainPolicyConfig>, override val certificateChainCheckPolicies: List<CertChainPolicyConfig>,
override val devMode: Boolean = false, override val devMode: Boolean = false,
override val debugOptions: Properties? = null,
val useTestClock: Boolean = false, val useTestClock: Boolean = false,
val detectPublicIp: Boolean = true, val detectPublicIp: Boolean = true,
override val activeMQServer: ActiveMqServerConfiguration, override val activeMQServer: ActiveMqServerConfiguration,
@ -103,6 +105,7 @@ data class FullNodeConfiguration(
init { init {
// This is a sanity feature do not remove. // This is a sanity feature do not remove.
require(!useTestClock || devMode) { "Cannot use test clock outside of dev mode" } require(!useTestClock || devMode) { "Cannot use test clock outside of dev mode" }
require(debugOptions == null || devMode){"Cannot use debugOptions outside of dev mode"}
// TODO Move this to ArtemisMessagingServer // TODO Move this to ArtemisMessagingServer
rpcUsers.forEach { rpcUsers.forEach {
require(it.username.matches("\\w+".toRegex())) { "Username ${it.username} contains invalid characters" } require(it.username.matches("\\w+".toRegex())) { "Username ${it.username} contains invalid characters" }

View File

@ -33,10 +33,7 @@ import net.corda.node.services.api.CheckpointStorage
import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.messaging.ReceivedMessage import net.corda.node.services.messaging.ReceivedMessage
import net.corda.node.services.messaging.TopicSession import net.corda.node.services.messaging.TopicSession
import net.corda.node.utilities.AffinityExecutor import net.corda.node.utilities.*
import net.corda.node.utilities.CordaPersistence
import net.corda.node.utilities.bufferUntilDatabaseCommit
import net.corda.node.utilities.wrapWithDatabaseTransaction
import net.corda.nodeapi.internal.serialization.SerializeAsTokenContextImpl import net.corda.nodeapi.internal.serialization.SerializeAsTokenContextImpl
import net.corda.nodeapi.internal.serialization.withTokenContext import net.corda.nodeapi.internal.serialization.withTokenContext
import org.apache.activemq.artemis.utils.ReusableLatch import org.apache.activemq.artemis.utils.ReusableLatch
@ -92,7 +89,7 @@ class StateMachineManagerImpl(
private val scheduler = FiberScheduler() private val scheduler = FiberScheduler()
private val mutex = ThreadBox(InnerState()) private val mutex = ThreadBox(InnerState())
// This thread (only enabled in dev mode) deserialises checkpoints in the background to shake out bugs in checkpoint restore. // This thread (only enabled in dev mode) deserialises checkpoints in the background to shake out bugs in checkpoint restore.
private val checkpointCheckerThread = if (serviceHub.configuration.devMode) Executors.newSingleThreadExecutor() else null private val checkpointCheckerThread = if (serviceHub.configuration.devMode && serviceHub.configuration.debugOptions?.getProperty("disableCheckpointChecking") != "true") newNamedSingleThreadExecutor("CheckpointChecker") else null
@Volatile private var unrestorableCheckpoints = false @Volatile private var unrestorableCheckpoints = false

View File

@ -14,6 +14,6 @@ class NamedThreadFactory(private val name:String, private val underlyingFactory:
} }
} }
fun newNamedSinleThreadExecutor(name: String): ExecutorService { fun newNamedSingleThreadExecutor(name: String): ExecutorService {
return Executors.newSingleThreadExecutor(NamedThreadFactory(name, Executors.defaultThreadFactory())) return Executors.newSingleThreadExecutor(NamedThreadFactory(name, Executors.defaultThreadFactory()))
} }

View File

@ -10,6 +10,8 @@ import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test import org.junit.Test
import java.net.URL import java.net.URL
import java.nio.file.Paths import java.nio.file.Paths
import java.util.*
import kotlin.test.assertFalse
class FullNodeConfigurationTest { class FullNodeConfigurationTest {
@Test @Test
@ -43,4 +45,74 @@ class FullNodeConfigurationTest {
assertThatThrownBy { configWithRPCUsername("user*1") }.hasMessageContaining("*") assertThatThrownBy { configWithRPCUsername("user*1") }.hasMessageContaining("*")
assertThatThrownBy { configWithRPCUsername("user#1") }.hasMessageContaining("#") assertThatThrownBy { configWithRPCUsername("user#1") }.hasMessageContaining("#")
} }
@Test
fun `Can't have debug options if not in dev mode`() {
val testConfiguration = FullNodeConfiguration(
baseDirectory = Paths.get("."),
myLegalName = ALICE.name,
networkMapService = null,
emailAddress = "",
keyStorePassword = "cordacadevpass",
trustStorePassword = "trustpass",
dataSourceProperties = makeTestDataSourceProperties(ALICE.name.organisation),
database = makeTestDatabaseProperties(),
certificateSigningService = URL("http://localhost"),
rpcUsers = emptyList(),
verifierType = VerifierType.InMemory,
useHTTPS = false,
p2pAddress = NetworkHostAndPort("localhost", 0),
rpcAddress = NetworkHostAndPort("localhost", 1),
messagingServerAddress = null,
notary = null,
certificateChainCheckPolicies = emptyList(),
devMode = true,
activeMQServer = ActiveMqServerConfiguration(BridgeConfiguration(0, 0, 0.0)),
additionalNodeInfoPollingFrequencyMsec = 5.seconds.toMillis())
fun configDebugOptions(devMode: Boolean, debugOptions: Properties?) {
testConfiguration.copy(devMode = devMode, debugOptions = debugOptions)
}
val debugOptions = Properties()
configDebugOptions(true, debugOptions)
configDebugOptions(true,null)
assertThatThrownBy{configDebugOptions(false, debugOptions)}.hasMessageMatching("Cannot use debugOptions outside of dev mode")
configDebugOptions(false,null)
}
@Test
fun `check properties behave as expected`()
{
val testConfiguration = FullNodeConfiguration(
baseDirectory = Paths.get("."),
myLegalName = ALICE.name,
networkMapService = null,
emailAddress = "",
keyStorePassword = "cordacadevpass",
trustStorePassword = "trustpass",
dataSourceProperties = makeTestDataSourceProperties(ALICE.name.organisation),
database = makeTestDatabaseProperties(),
certificateSigningService = URL("http://localhost"),
rpcUsers = emptyList(),
verifierType = VerifierType.InMemory,
useHTTPS = false,
p2pAddress = NetworkHostAndPort("localhost", 0),
rpcAddress = NetworkHostAndPort("localhost", 1),
messagingServerAddress = null,
notary = null,
certificateChainCheckPolicies = emptyList(),
devMode = true,
activeMQServer = ActiveMqServerConfiguration(BridgeConfiguration(0, 0, 0.0)),
additionalNodeInfoPollingFrequencyMsec = 5.seconds.toMillis())
fun configDebugOptions(devMode: Boolean, debugOptions: Properties?) : NodeConfiguration {
return testConfiguration.copy(devMode = devMode, debugOptions = debugOptions)
}
val debugOptions = Properties()
assertFalse { configDebugOptions(true, debugOptions).debugOptions?.getProperty("foo") == "bar"}
assertFalse { configDebugOptions(true,null).debugOptions?.getProperty("foo") == "bar"}
debugOptions.setProperty("foo", "bar")
assert( configDebugOptions(true, debugOptions).debugOptions?.getProperty("foo") == "bar")
}
} }