Merge pull request #953 from corda/tudor-os-merge-7-jun

Tudor os merge 7 jun
This commit is contained in:
Tudor Malene 2018-06-07 18:00:15 +01:00 committed by GitHub
commit db3da50070
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 13 deletions

View File

@ -297,3 +297,5 @@ private fun Throwable.hasSQLExceptionCause(): Boolean =
is SQLException -> true is SQLException -> true
else -> cause?.hasSQLExceptionCause() ?: false 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.codahale.metrics.MetricRegistry
import com.google.common.collect.MutableClassToInstanceMap import com.google.common.collect.MutableClassToInstanceMap
import com.google.common.util.concurrent.MoreExecutors import com.google.common.util.concurrent.MoreExecutors
import com.zaxxer.hikari.pool.HikariPool
import net.corda.confidential.SwapIdentitiesFlow import net.corda.confidential.SwapIdentitiesFlow
import net.corda.confidential.SwapIdentitiesHandler import net.corda.confidential.SwapIdentitiesHandler
import net.corda.core.CordaException 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.SignedNodeInfo
import net.corda.nodeapi.internal.crypto.X509Utilities import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.persistence.CordaPersistence 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.DatabaseConfig
import net.corda.nodeapi.internal.persistence.HibernateConfiguration import net.corda.nodeapi.internal.persistence.HibernateConfiguration
import net.corda.nodeapi.internal.persistence.SchemaMigration import net.corda.nodeapi.internal.persistence.SchemaMigration
@ -1065,6 +1067,11 @@ class ConfigurationException(message: String) : CordaException(message)
*/ */
internal class NetworkMapCacheEmptyException : Exception() internal class NetworkMapCacheEmptyException : Exception()
/**
* Creates the connection pool to the database.
*
*@throws [CouldNotCreateDataSourceException]
*/
fun configureDatabase(hikariProperties: Properties, fun configureDatabase(hikariProperties: Properties,
databaseConfig: DatabaseConfig, databaseConfig: DatabaseConfig,
wellKnownPartyFromX500Name: (CordaX500Name) -> Party?, wellKnownPartyFromX500Name: (CordaX500Name) -> Party?,
@ -1075,6 +1082,7 @@ fun configureDatabase(hikariProperties: Properties,
// so we end up providing both descriptor and converter. We should re-examine this in later versions to see if // 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. // either Hibernate can be convinced to stop warning, use the descriptor by default, or something else.
JavaTypeDescriptorRegistry.INSTANCE.addDescriptor(AbstractPartyDescriptor(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous)) JavaTypeDescriptorRegistry.INSTANCE.addDescriptor(AbstractPartyDescriptor(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous))
try {
val dataSource = DataSourceFactory.createDataSource(hikariProperties) val dataSource = DataSourceFactory.createDataSource(hikariProperties)
val attributeConverters = listOf(AbstractPartyToX500NameAsStringConverter(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous)) val attributeConverters = listOf(AbstractPartyToX500NameAsStringConverter(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous))
val jdbcUrl = hikariProperties.getProperty("dataSource.url", "") val jdbcUrl = hikariProperties.getProperty("dataSource.url", "")
@ -1084,4 +1092,11 @@ fun configureDatabase(hikariProperties: Properties,
!isH2Database(jdbcUrl), !isH2Database(jdbcUrl),
databaseConfig).nodeStartup() databaseConfig).nodeStartup()
return CordaPersistence(dataSource, databaseConfig, schemaService.schemaOptions.keys, jdbcUrl, attributeConverters) 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.config.UnknownConfigurationKeysException
import net.corda.nodeapi.internal.persistence.DatabaseMigrationException import net.corda.nodeapi.internal.persistence.DatabaseMigrationException
import net.corda.nodeapi.internal.persistence.oracleJdbcDriverSerialFilter import net.corda.nodeapi.internal.persistence.oracleJdbcDriverSerialFilter
import net.corda.nodeapi.internal.persistence.CouldNotCreateDataSourceException
import net.corda.tools.shell.InteractiveShell import net.corda.tools.shell.InteractiveShell
import org.fusesource.jansi.Ansi import org.fusesource.jansi.Ansi
import org.fusesource.jansi.AnsiConsole import org.fusesource.jansi.AnsiConsole
@ -144,6 +145,9 @@ open class NodeStartup(val args: Array<String>) {
} catch (e: DatabaseMigrationException) { } catch (e: DatabaseMigrationException) {
logger.error(e.message) logger.error(e.message)
return false return false
} catch (e: CouldNotCreateDataSourceException) {
logger.error(e.message, e.cause)
return false
} catch (e: CheckpointIncompatibleException) { } catch (e: CheckpointIncompatibleException) {
logger.error(e.message) logger.error(e.message)
return false return false

View File

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

View File

@ -89,8 +89,11 @@ class RetryFlowMockTest {
@Test @Test
fun `Patient records do not leak in hospital`() { fun `Patient records do not leak in hospital`() {
val patientCountBefore = StaffedFlowHospital.numberOfPatients
assertEquals(Unit, internalNodeA.startFlow(RetryFlow(1)).get()) 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) assertEquals(2, RetryFlow.count)
} }
} }