Merge remote-tracking branch 'open/master' into tudor-os-merge-7-jun

# Conflicts:
#	node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt
#	node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt
This commit is contained in:
tudor.malene@gmail.com 2018-06-07 16:05:11 +01:00
commit 5140d46aa2
5 changed files with 37 additions and 13 deletions

View File

@ -296,4 +296,6 @@ private fun Throwable.hasSQLExceptionCause(): Boolean =
null -> false
is SQLException -> true
else -> cause?.hasSQLExceptionCause() ?: false
}
}
class CouldNotCreateDataSourceException(override val message: String?, override val cause: Throwable? = null) : Exception()

View File

@ -13,6 +13,7 @@ package net.corda.node.internal
import com.codahale.metrics.MetricRegistry
import com.google.common.collect.MutableClassToInstanceMap
import com.google.common.util.concurrent.MoreExecutors
import com.zaxxer.hikari.pool.HikariPool
import net.corda.confidential.SwapIdentitiesFlow
import net.corda.confidential.SwapIdentitiesHandler
import net.corda.core.CordaException
@ -109,6 +110,7 @@ import net.corda.nodeapi.internal.NodeInfoAndSigned
import net.corda.nodeapi.internal.SignedNodeInfo
import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.CouldNotCreateDataSourceException
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import net.corda.nodeapi.internal.persistence.SchemaMigration
@ -267,7 +269,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
networkMapCache.clearNetworkMapCache()
}
}
open fun start(): StartedNode<AbstractNode> {
check(started == null) { "Node has already been started" }
if (configuration.devMode) {
@ -1065,6 +1067,11 @@ class ConfigurationException(message: String) : CordaException(message)
*/
internal class NetworkMapCacheEmptyException : Exception()
/**
* Creates the connection pool to the database.
*
*@throws [CouldNotCreateDataSourceException]
*/
fun configureDatabase(hikariProperties: Properties,
databaseConfig: DatabaseConfig,
wellKnownPartyFromX500Name: (CordaX500Name) -> Party?,
@ -1075,13 +1082,21 @@ fun configureDatabase(hikariProperties: Properties,
// so we end up providing both descriptor and converter. We should re-examine this in later versions to see if
// either Hibernate can be convinced to stop warning, use the descriptor by default, or something else.
JavaTypeDescriptorRegistry.INSTANCE.addDescriptor(AbstractPartyDescriptor(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous))
val dataSource = DataSourceFactory.createDataSource(hikariProperties)
val attributeConverters = listOf(AbstractPartyToX500NameAsStringConverter(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous))
val jdbcUrl = hikariProperties.getProperty("dataSource.url", "")
SchemaMigration(
schemaService.schemaOptions.keys,
dataSource,
!isH2Database(jdbcUrl),
databaseConfig).nodeStartup()
return CordaPersistence(dataSource, databaseConfig, schemaService.schemaOptions.keys, jdbcUrl, attributeConverters)
try {
val dataSource = DataSourceFactory.createDataSource(hikariProperties)
val attributeConverters = listOf(AbstractPartyToX500NameAsStringConverter(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous))
val jdbcUrl = hikariProperties.getProperty("dataSource.url", "")
SchemaMigration(
schemaService.schemaOptions.keys,
dataSource,
!isH2Database(jdbcUrl),
databaseConfig).nodeStartup()
return CordaPersistence(dataSource, databaseConfig, schemaService.schemaOptions.keys, jdbcUrl, attributeConverters)
} catch (ex: Exception) {
when {
ex is HikariPool.PoolInitializationException -> throw CouldNotCreateDataSourceException("Could not connect to the database. Please check your JDBC connection URL, or the connectivity to the database.")
ex.cause is ClassNotFoundException -> throw CouldNotCreateDataSourceException("Could not find the database driver class. Please add it to the 'drivers' folders. See: https://docs.corda.net/corda-configuration-file.html")
else -> throw CouldNotCreateDataSourceException("Could not create the DataSource: ${ex.message}", ex)
}
}
}

View File

@ -40,6 +40,7 @@ import net.corda.nodeapi.internal.addShutdownHook
import net.corda.nodeapi.internal.config.UnknownConfigurationKeysException
import net.corda.nodeapi.internal.persistence.DatabaseMigrationException
import net.corda.nodeapi.internal.persistence.oracleJdbcDriverSerialFilter
import net.corda.nodeapi.internal.persistence.CouldNotCreateDataSourceException
import net.corda.tools.shell.InteractiveShell
import org.fusesource.jansi.Ansi
import org.fusesource.jansi.AnsiConsole
@ -144,6 +145,9 @@ open class NodeStartup(val args: Array<String>) {
} catch (e: DatabaseMigrationException) {
logger.error(e.message)
return false
} catch (e: CouldNotCreateDataSourceException) {
logger.error(e.message, e.cause)
return false
} catch (e: CheckpointIncompatibleException) {
logger.error(e.message)
return false

View File

@ -17,7 +17,7 @@ object StaffedFlowHospital : FlowHospital {
private val patients = ConcurrentHashMap<StateMachineRunId, MedicalHistory>()
val numberOfPatients = patients.size
val numberOfPatients get() = patients.size
class MedicalHistory {
val records: MutableList<Record> = mutableListOf()

View File

@ -89,8 +89,11 @@ class RetryFlowMockTest {
@Test
fun `Patient records do not leak in hospital`() {
val patientCountBefore = StaffedFlowHospital.numberOfPatients
assertEquals(Unit, internalNodeA.startFlow(RetryFlow(1)).get())
assertEquals(0, StaffedFlowHospital.numberOfPatients)
// Need to make sure the state machine has finished. Otherwise this test is flakey.
mockNet.waitQuiescent()
assertEquals(patientCountBefore, StaffedFlowHospital.numberOfPatients)
assertEquals(2, RetryFlow.count)
}
}