mirror of
https://github.com/corda/corda.git
synced 2024-12-19 13:08:04 +00:00
H2 database exported via configurable port number.
This commit is contained in:
parent
31956ce78e
commit
2e3952ee1f
@ -75,6 +75,18 @@ To enable remote debugging of the corda process use a command line such as:
|
||||
|
||||
This command line will start the debugger on port 5005 and pause the process awaiting debugger attachment.
|
||||
|
||||
Viewing persisted state of your Node
|
||||
------------------------------------
|
||||
|
||||
To make examining the persisted contract states of your node or the internal node database tables easier, and providing you are
|
||||
using the default database configuration used for demos, you should be able to connect to the internal node database over
|
||||
a JDBC connection at the URL that is output to the logs at node start up. That URL will be of the form ``jdbc:h2:tcp://<host>:<port>/node``.
|
||||
|
||||
The user name and password for the login are as per the node data source configuration.
|
||||
|
||||
The name and column layout of the internal node tables is in a state of flux and should not be relied upon to remain static
|
||||
at the present time, and should certainly be treated as read-only.
|
||||
|
||||
.. _CordaPluginRegistry: api/com.r3corda.core.node/-corda-plugin-registry/index.html
|
||||
.. _ServiceHubInternal: api/com.r3corda.node.services.api/-service-hub-internal/index.html
|
||||
.. _ServiceHub: api/com.r3corda.node.services.api/-service-hub/index.html
|
||||
|
@ -11,7 +11,9 @@ as annotations and is converted to database table rows by the node automatically
|
||||
node's local vault as part of a transaction.
|
||||
|
||||
.. note:: Presently the node includes an instance of the H2 database but any database that supports JDBC is a candidate and
|
||||
the node will in the future support a range of database implementations via their JDBC drivers.
|
||||
the node will in the future support a range of database implementations via their JDBC drivers. Much of the node
|
||||
internal state is also persisted there. If a node is using the default H2 JDBC configuration you should be able to connect
|
||||
to the H2 instance using the JDBC URL output to the logs at startup of the form ``jdbc:h2:tcp://<host>:<port>/node``
|
||||
|
||||
Schemas
|
||||
-------
|
||||
|
@ -235,6 +235,35 @@ class Node(override val configuration: FullNodeConfiguration, networkMapAddress:
|
||||
|
||||
override fun makeUniquenessProvider() = PersistentUniquenessProvider()
|
||||
|
||||
/**
|
||||
* If the node is persisting to an embedded H2 database, then expose this via TCP with a JDBC URL of the form:
|
||||
* jdbc:h2:tcp://<host>:<port>/node
|
||||
* with username and password as per the DataSource connection details. The key element to enabling this support is to
|
||||
* ensure that you specify a JDBC connection URL of the form jdbc:h2:file: in the node config and that you include
|
||||
* the H2 option AUTO_SERVER_PORT set to the port you desire to use (0 will give a dynamically allocated port number)
|
||||
* but exclude the H2 option AUTO_SERVER=TRUE.
|
||||
* This is not using the H2 "automatic mixed mode" directly but leans on many of the underpinnings. For more details
|
||||
* on H2 URLs and configuration see: http://www.h2database.com/html/features.html#database_url
|
||||
*/
|
||||
override fun initialiseDatabasePersistence(insideTransaction: () -> Unit) {
|
||||
val databaseUrl = configuration.dataSourceProperties.getProperty("dataSource.url")
|
||||
val h2Prefix = "jdbc:h2:file:"
|
||||
if (databaseUrl != null && databaseUrl.startsWith(h2Prefix)) {
|
||||
val h2Port = databaseUrl.substringAfter(";AUTO_SERVER_PORT=", "").substringBefore(';')
|
||||
if (h2Port.isNotBlank()) {
|
||||
val databaseName = databaseUrl.removePrefix(h2Prefix).substringBefore(';')
|
||||
val server = org.h2.tools.Server.createTcpServer(
|
||||
"-tcpPort", h2Port,
|
||||
"-tcpAllowOthers",
|
||||
"-tcpDaemon",
|
||||
"-key", "node", databaseName)
|
||||
val url = server.start().url
|
||||
log.info("H2 JDBC url is jdbc:h2:$url/node")
|
||||
}
|
||||
}
|
||||
super.initialiseDatabasePersistence(insideTransaction)
|
||||
}
|
||||
|
||||
override fun start(): Node {
|
||||
alreadyRunningNodeCheck()
|
||||
super.start()
|
||||
|
@ -6,10 +6,11 @@ keyStorePassword = "cordacadevpass"
|
||||
trustStorePassword = "trustpass"
|
||||
dataSourceProperties = {
|
||||
dataSourceClassName = org.h2.jdbcx.JdbcDataSource
|
||||
"dataSource.url" = "jdbc:h2:"${basedir}"/persistence;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=10000;MVCC=true;MV_STORE=true;WRITE_DELAY=0"
|
||||
"dataSource.url" = "jdbc:h2:file:"${basedir}"/persistence;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=10000;MVCC=true;MV_STORE=true;WRITE_DELAY=0;AUTO_SERVER_PORT="${h2port}
|
||||
"dataSource.user" = sa
|
||||
"dataSource.password" = ""
|
||||
}
|
||||
devMode = true
|
||||
certificateSigningService = "https://cordaci-netperm.corda.r3cev.com"
|
||||
useHTTPS = false
|
||||
h2port = 0
|
@ -66,7 +66,8 @@ private fun startNode(baseDirectory: Path,
|
||||
"--base-directory", baseDirectory.toString(),
|
||||
"--network-address", nodeAddr.toString(),
|
||||
"--network-map-address", networkMapAddr.toString(),
|
||||
"--api-address", apiAddr.toString())
|
||||
"--api-address", apiAddr.toString(),
|
||||
"--h2-port", "0")
|
||||
val proc = spawn("com.r3corda.demos.IRSDemoKt", args, "IRSDemo$nodeType")
|
||||
NodeApi.ensureNodeStartsOrKill(proc, apiAddr)
|
||||
return proc
|
||||
|
@ -26,7 +26,8 @@ class TraderDemoTest {
|
||||
"--role", "BUYER",
|
||||
"--network-address", buyerAddr.toString(),
|
||||
"--api-address", buyerApiAddr.toString(),
|
||||
"--base-directory", baseDirectory
|
||||
"--base-directory", baseDirectory,
|
||||
"--h2-port", "0"
|
||||
)
|
||||
val proc = spawn("com.r3corda.demos.TraderDemoKt", args, "TradeDemoBuyer")
|
||||
NodeApi.ensureNodeStartsOrKill(proc, buyerApiAddr)
|
||||
@ -42,7 +43,8 @@ class TraderDemoTest {
|
||||
"--network-address", sellerAddr.toString(),
|
||||
"--api-address", sellerApiAddr.toString(),
|
||||
"--other-network-address", buyerAddr.toString(),
|
||||
"--base-directory", baseDirectory
|
||||
"--base-directory", baseDirectory,
|
||||
"--h2-port", "0"
|
||||
)
|
||||
val proc = spawn("com.r3corda.demos.TraderDemoKt", args, "TradeDemoSeller")
|
||||
assertExitOrKill(proc)
|
||||
|
@ -87,7 +87,8 @@ sealed class CliParams {
|
||||
val tradeWithIdentities: List<Path>,
|
||||
val uploadRates: Boolean,
|
||||
val defaultLegalName: String,
|
||||
val autoSetup: Boolean // Run Setup for both nodes automatically with default arguments
|
||||
val autoSetup: Boolean, // Run Setup for both nodes automatically with default arguments
|
||||
val h2Port: Int
|
||||
) : CliParams()
|
||||
|
||||
/**
|
||||
@ -151,6 +152,12 @@ sealed class CliParams {
|
||||
IRSDemoNode.NodeB -> Node.DEFAULT_PORT + 3
|
||||
}
|
||||
|
||||
private fun defaultH2Port(node: IRSDemoNode) =
|
||||
when (node) {
|
||||
IRSDemoNode.NodeA -> Node.DEFAULT_PORT + 4
|
||||
IRSDemoNode.NodeB -> Node.DEFAULT_PORT + 5
|
||||
}
|
||||
|
||||
private fun parseRunNode(options: OptionSet, node: IRSDemoNode): RunNode {
|
||||
val dir = nodeDirectory(options, node)
|
||||
|
||||
@ -171,7 +178,8 @@ sealed class CliParams {
|
||||
},
|
||||
uploadRates = node == IRSDemoNode.NodeB,
|
||||
defaultLegalName = legalName(node),
|
||||
autoSetup = !options.has(CliParamsSpec.baseDirectoryArg) && !options.has(CliParamsSpec.fakeTradeWithIdentityFile)
|
||||
autoSetup = !options.has(CliParamsSpec.baseDirectoryArg) && !options.has(CliParamsSpec.fakeTradeWithIdentityFile),
|
||||
h2Port = options.valueOf(CliParamsSpec.h2PortArg.defaultsTo(defaultH2Port(node)))
|
||||
)
|
||||
}
|
||||
|
||||
@ -263,6 +271,7 @@ object CliParamsSpec {
|
||||
val fakeTradeWithIdentityFile =
|
||||
parser.accepts("fake-trade-with-identity-file", "Extra identities to be registered with the identity service")
|
||||
.withOptionalArg()
|
||||
val h2PortArg = parser.accepts("h2-port").withRequiredArg().ofType(Int::class.java)
|
||||
val nonOptions = parser.nonOptions()
|
||||
val help = parser.accepts("help", "Prints this help").forHelp()
|
||||
}
|
||||
@ -449,7 +458,8 @@ private fun getNodeConfig(cliParams: CliParams.RunNode): FullNodeConfiguration {
|
||||
val configFile = cliParams.dir.resolve("config")
|
||||
val configOverrides = mapOf(
|
||||
"artemisAddress" to cliParams.networkAddress.toString(),
|
||||
"webAddress" to cliParams.apiAddress.toString()
|
||||
"webAddress" to cliParams.apiAddress.toString(),
|
||||
"h2port" to cliParams.h2Port.toString()
|
||||
)
|
||||
return loadConfigFile(cliParams.dir, configFile, configOverrides, cliParams.defaultLegalName)
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ fun main(args: Array<String>) {
|
||||
val theirNetworkAddress = parser.accepts("other-network-address").withRequiredArg().defaultsTo("localhost")
|
||||
val apiNetworkAddress = parser.accepts("api-address").withRequiredArg().defaultsTo("localhost")
|
||||
val baseDirectoryArg = parser.accepts("base-directory").withRequiredArg().defaultsTo(DEFAULT_BASE_DIRECTORY)
|
||||
|
||||
val h2PortArg = parser.accepts("h2-port").withRequiredArg().ofType(Int::class.java).defaultsTo(-1)
|
||||
val options = try {
|
||||
parser.parse(*args)
|
||||
} catch (e: Exception) {
|
||||
@ -104,6 +104,9 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
)
|
||||
val apiNetAddr = HostAndPort.fromString(options.valueOf(apiNetworkAddress)).withDefaultPort(myNetAddr.port + 1)
|
||||
val h2Port = if (options.valueOf(h2PortArg) < 0) {
|
||||
myNetAddr.port + 2
|
||||
} else options.valueOf(h2PortArg)
|
||||
|
||||
val baseDirectory = options.valueOf(baseDirectoryArg)!!
|
||||
|
||||
@ -125,7 +128,8 @@ fun main(args: Array<String>) {
|
||||
val configOverrides = mapOf(
|
||||
"myLegalName" to myLegalName,
|
||||
"artemisAddress" to myNetAddr.toString(),
|
||||
"webAddress" to apiNetAddr.toString()
|
||||
"webAddress" to apiNetAddr.toString(),
|
||||
"h2port" to h2Port.toString()
|
||||
)
|
||||
FullNodeConfiguration(NodeConfiguration.loadConfig(directory, allowMissingConfig = true, configOverrides = configOverrides))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user