ENT-6588 Restrict database operations platform flag (#7053)

* ENT-6588 Restrict database operations platform flag

Put the restricting of database operations in `RestrictedConnection` and
`RestrictedEntityManager` behind a platform version flag.

`RESTRICTED_DATABASE_OPERATIONS = 7` was added to signify this.

If the version is less than 7, then the database operations will not be
restricted. A warning is logged to indicate that they are using
potentially dangerous methods.

If the version is 7 or greater, then the database operations are
restricted and throw an error if called.
This commit is contained in:
Dan Newton
2022-02-08 10:06:44 +00:00
committed by GitHub
parent 5c052e9273
commit fa739fc467
9 changed files with 559 additions and 124 deletions

View File

@ -1,5 +1,6 @@
package net.corda.nodeapi.internal.persistence
import net.corda.core.node.ServiceHub
import java.sql.Connection
import java.sql.Savepoint
import java.util.concurrent.Executor
@ -8,73 +9,73 @@ import java.util.concurrent.Executor
* A delegate of [Connection] which disallows some operations.
*/
@Suppress("TooManyFunctions")
class RestrictedConnection(private val delegate : Connection) : Connection by delegate {
class RestrictedConnection(private val delegate: Connection, private val serviceHub: ServiceHub) : Connection by delegate {
override fun abort(executor: Executor?) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("abort", serviceHub) { delegate.abort(executor) }
}
override fun clearWarnings() {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("clearWarnings", serviceHub) { delegate.clearWarnings() }
}
override fun close() {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("close", serviceHub) { delegate.close() }
}
override fun commit() {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("commit", serviceHub) { delegate.commit() }
}
override fun setSavepoint(): Savepoint? {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
return restrictDatabaseOperationFromJdbcSession("setSavepoint", serviceHub) { delegate.setSavepoint() }
}
override fun setSavepoint(name : String?): Savepoint? {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
override fun setSavepoint(name: String?): Savepoint? {
return restrictDatabaseOperationFromJdbcSession("setSavepoint", serviceHub) { delegate.setSavepoint(name) }
}
override fun releaseSavepoint(savepoint: Savepoint?) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("releaseSavepoint", serviceHub) { delegate.releaseSavepoint(savepoint) }
}
override fun rollback() {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("rollback", serviceHub) { delegate.rollback() }
}
override fun rollback(savepoint: Savepoint?) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("rollback", serviceHub) { delegate.rollback(savepoint) }
}
override fun setCatalog(catalog : String?) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
override fun setCatalog(catalog: String?) {
restrictDatabaseOperationFromJdbcSession("setCatalog", serviceHub) { delegate.catalog = catalog }
}
override fun setTransactionIsolation(level: Int) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("setTransactionIsolation", serviceHub) { delegate.transactionIsolation = level }
}
override fun setTypeMap(map: MutableMap<String, Class<*>>?) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("setTypeMap", serviceHub) { delegate.typeMap = map }
}
override fun setHoldability(holdability: Int) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("setHoldability", serviceHub) { delegate.holdability = holdability }
}
override fun setSchema(schema: String?) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("setSchema", serviceHub) { delegate.schema = schema }
}
override fun setNetworkTimeout(executor: Executor?, milliseconds: Int) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("setNetworkTimeout", serviceHub) { delegate.setNetworkTimeout(executor, milliseconds) }
}
override fun setAutoCommit(autoCommit: Boolean) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("setAutoCommit", serviceHub) { delegate.autoCommit = autoCommit }
}
override fun setReadOnly(readOnly: Boolean) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.jdbcSession.")
restrictDatabaseOperationFromJdbcSession("setReadOnly", serviceHub) { delegate.isReadOnly = readOnly }
}
}

View File

@ -0,0 +1,31 @@
package net.corda.nodeapi.internal.persistence
import net.corda.core.internal.PlatformVersionSwitches.RESTRICTED_DATABASE_OPERATIONS
import net.corda.core.internal.warnOnce
import net.corda.core.node.ServiceHub
import org.slf4j.LoggerFactory
private val log = LoggerFactory.getLogger("RestrictedDatabaseOperations")
internal inline fun <T> restrictDatabaseOperationFromJdbcSession(method: String, serviceHub: ServiceHub, operation: () -> T): T {
return restrictDatabaseOperation("ServiceHub.jdbcSession.$method", serviceHub, operation)
}
internal inline fun <T> restrictDatabaseOperationFromEntityManager(method: String, serviceHub: ServiceHub, operation: () -> T): T {
return restrictDatabaseOperation("ServiceHub.withEntityManager.$method", serviceHub, operation)
}
internal inline fun <T> restrictDatabaseOperation(method: String, serviceHub: ServiceHub, operation: () -> T): T {
return if (serviceHub.getAppContext().cordapp.targetPlatformVersion >= RESTRICTED_DATABASE_OPERATIONS) {
throw UnsupportedOperationException("$method is restricted and cannot be called")
} else {
log.warnOnce(
"$method should not be called, as manipulating database transactions and connections breaks the Corda flow state machine in " +
"ways that only become evident in failure scenarios. Purely for API backwards compatibility reasons, the prior " +
"behaviour is continued for target platform versions less than $RESTRICTED_DATABASE_OPERATIONS. You should evolve " +
"the CorDapp away from using these problematic APIs as soon as possible. For target platform version of " +
"$RESTRICTED_DATABASE_OPERATIONS or above, an exception will be thrown instead."
)
operation()
}
}

View File

@ -1,5 +1,6 @@
package net.corda.nodeapi.internal.persistence
import net.corda.core.node.ServiceHub
import javax.persistence.EntityManager
import javax.persistence.EntityTransaction
import javax.persistence.LockModeType
@ -8,56 +9,59 @@ import javax.persistence.metamodel.Metamodel
/**
* A delegate of [EntityManager] which disallows some operations.
*/
class RestrictedEntityManager(private val delegate: EntityManager) : EntityManager by delegate {
class RestrictedEntityManager(private val delegate: EntityManager, private val serviceHub: ServiceHub) : EntityManager by delegate {
override fun getTransaction(): EntityTransaction {
return RestrictedEntityTransaction(delegate.transaction)
return RestrictedEntityTransaction(delegate.transaction, serviceHub)
}
override fun close() {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.")
restrictDatabaseOperationFromEntityManager("close", serviceHub) { delegate.close() }
}
override fun <T : Any?> unwrap(cls: Class<T>?): T {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.")
return restrictDatabaseOperationFromEntityManager("unwrap", serviceHub) { delegate.unwrap(cls) }
}
override fun getDelegate(): Any {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.")
return restrictDatabaseOperationFromEntityManager("getDelegate", serviceHub) { delegate.delegate }
}
override fun getMetamodel(): Metamodel? {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.")
return restrictDatabaseOperationFromEntityManager("getMetamodel", serviceHub) { delegate.metamodel }
}
override fun joinTransaction() {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.")
restrictDatabaseOperationFromEntityManager("joinTransaction", serviceHub) { delegate.joinTransaction() }
}
override fun lock(entity: Any?, lockMode: LockModeType?) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.")
restrictDatabaseOperationFromEntityManager("lock", serviceHub) { delegate.lock(entity, lockMode) }
}
override fun lock(entity: Any?, lockMode: LockModeType?, properties: MutableMap<String, Any>?) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.")
restrictDatabaseOperationFromEntityManager("lock", serviceHub) { delegate.lock(entity, lockMode, properties) }
}
override fun setProperty(propertyName: String?, value: Any?) {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.")
restrictDatabaseOperationFromEntityManager("lock", serviceHub) { delegate.setProperty(propertyName, value) }
}
}
class RestrictedEntityTransaction(private val delegate: EntityTransaction) : EntityTransaction by delegate {
class RestrictedEntityTransaction(
private val delegate: EntityTransaction,
private val serviceHub: ServiceHub
) : EntityTransaction by delegate {
override fun rollback() {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.")
restrictDatabaseOperationFromEntityManager("EntityTransaction.rollback", serviceHub) { delegate.rollback() }
}
override fun commit() {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.")
restrictDatabaseOperationFromEntityManager("EntityTransaction.commit", serviceHub) { delegate.commit() }
}
override fun begin() {
throw UnsupportedOperationException("This method cannot be called via ServiceHub.withEntityManager.")
restrictDatabaseOperationFromEntityManager("EntityTransaction.begin", serviceHub) { delegate.begin() }
}
}

View File

@ -1,104 +1,337 @@
package net.corda.nodeapi.internal.persistence
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.cordapp.Cordapp
import net.corda.core.cordapp.CordappContext
import net.corda.core.internal.PLATFORM_VERSION
import net.corda.core.node.ServiceHub
import org.junit.Test
import java.sql.Connection
import java.sql.Savepoint
class RestrictedConnectionTest {
private val connection : Connection = mock()
private val savePoint : Savepoint = mock()
private val restrictedConnection : RestrictedConnection = RestrictedConnection(connection)
private val connection: Connection = mock()
private val savePoint: Savepoint = mock()
private val cordapp = mock<Cordapp>()
private val cordappContext = CordappContext.create(cordapp, null, javaClass.classLoader, mock())
private val serviceHub = mock<ServiceHub>().apply {
whenever(getAppContext()).thenReturn(cordappContext)
}
private val restrictedConnection: RestrictedConnection = RestrictedConnection(connection, serviceHub)
companion object {
private const val TEST_STRING : String = "test"
private const val TEST_INT : Int = 1
private const val TEST_STRING: String = "test"
private const val TEST_INT: Int = 1
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testAbort() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `abort with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.abort { println("I'm just an executor for this test...") }
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testClearWarnings() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `clearWarnings with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.clearWarnings()
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testClose() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `close with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.close()
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testCommit() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `commit with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.commit()
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testSetSavepoint() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setSavepoint with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.setSavepoint()
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testSetSavepointWithName() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setSavepoint with name with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.setSavepoint(TEST_STRING)
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testReleaseSavepoint() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `releaseSavepoint with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.releaseSavepoint(savePoint)
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testRollback() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `rollback with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.rollback()
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testRollbackWithSavepoint() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `rollbackWithSavepoint with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.rollback(savePoint)
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testSetCatalog() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setCatalog with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.catalog = TEST_STRING
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testSetTransactionIsolation() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setTransactionIsolation with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.transactionIsolation = TEST_INT
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testSetTypeMap() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setTypeMap with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
val map: MutableMap<String, Class<*>> = mutableMapOf()
restrictedConnection.typeMap = map
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testSetHoldability() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setHoldability with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.holdability = TEST_INT
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testSetSchema() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setSchema with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.schema = TEST_STRING
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testSetNetworkTimeout() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setNetworkTimeout with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.setNetworkTimeout({ println("I'm just an executor for this test...") }, TEST_INT)
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testSetAutoCommit() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setAutoCommit with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.autoCommit = true
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testSetReadOnly() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setReadOnly with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedConnection.isReadOnly = true
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `abort with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.abort { println("I'm just an executor for this test...") }
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `clearWarnings with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.clearWarnings()
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `close with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.close()
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `commit with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.commit()
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setSavepoint with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.setSavepoint()
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setSavepoint with name with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.setSavepoint(TEST_STRING)
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `releaseSavepoint with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.releaseSavepoint(savePoint)
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `rollback with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.rollback()
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `rollbackWithSavepoint with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.rollback(savePoint)
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setCatalog with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.catalog = TEST_STRING
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setTransactionIsolation with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.transactionIsolation = TEST_INT
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setTypeMap with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
val map: MutableMap<String, Class<*>> = mutableMapOf()
restrictedConnection.typeMap = map
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setHoldability with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.holdability = TEST_INT
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setSchema with target platform version of current 7 unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.schema = TEST_STRING
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setNetworkTimeout with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.setNetworkTimeout({ println("I'm just an executor for this test...") }, TEST_INT)
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setAutoCommit with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.autoCommit = true
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setReadOnly with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedConnection.isReadOnly = true
}
@Test(timeout = 300_000)
fun `abort with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.abort { println("I'm just an executor for this test...") }
}
@Test(timeout = 300_000)
fun `clearWarnings with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.clearWarnings()
}
@Test(timeout = 300_000)
fun `close with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.close()
}
@Test(timeout = 300_000)
fun `commit with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.commit()
}
@Test(timeout = 300_000)
fun `setSavepoint with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.setSavepoint()
}
@Test(timeout = 300_000)
fun `setSavepoint with name with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.setSavepoint(TEST_STRING)
}
@Test(timeout = 300_000)
fun `releaseSavepoint with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.releaseSavepoint(savePoint)
}
@Test(timeout = 300_000)
fun `rollback with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.rollback()
}
@Test(timeout = 300_000)
fun `rollbackWithSavepoint with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.rollback(savePoint)
}
@Test(timeout = 300_000)
fun `setCatalog with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.catalog = TEST_STRING
}
@Test(timeout = 300_000)
fun `setTransactionIsolation with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.transactionIsolation = TEST_INT
}
@Test(timeout = 300_000)
fun `setTypeMap with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
val map: MutableMap<String, Class<*>> = mutableMapOf()
restrictedConnection.typeMap = map
}
@Test(timeout = 300_000)
fun `setHoldability with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.holdability = TEST_INT
}
@Test(timeout = 300_000)
fun `setSchema with target platform version of current 6 unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.schema = TEST_STRING
}
@Test(timeout = 300_000)
fun `setNetworkTimeout with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.setNetworkTimeout({ println("I'm just an executor for this test...") }, TEST_INT)
}
@Test(timeout = 300_000)
fun `setAutoCommit with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.autoCommit = true
}
@Test(timeout = 300_000)
fun `setReadOnly with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedConnection.isReadOnly = true
}
}

View File

@ -3,6 +3,10 @@ package net.corda.nodeapi.internal.persistence
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.cordapp.Cordapp
import net.corda.core.cordapp.CordappContext
import net.corda.core.internal.PLATFORM_VERSION
import net.corda.core.node.ServiceHub
import org.junit.Test
import javax.persistence.EntityManager
import javax.persistence.EntityTransaction
@ -12,47 +16,160 @@ import kotlin.test.assertTrue
class RestrictedEntityManagerTest {
private val entitymanager = mock<EntityManager>()
private val transaction = mock<EntityTransaction>()
private val restrictedEntityManager = RestrictedEntityManager(entitymanager)
private val cordapp = mock<Cordapp>()
private val cordappContext = CordappContext.create(cordapp, null, javaClass.classLoader, mock())
private val serviceHub = mock<ServiceHub>().apply {
whenever(getAppContext()).thenReturn(cordappContext)
}
private val restrictedEntityManager = RestrictedEntityManager(entitymanager, serviceHub)
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testClose() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `close with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.close()
}
@Test(timeout = 300_000)
fun testClear() {
fun `clear with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.clear()
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testGetMetaModel() {
restrictedEntityManager.getMetamodel()
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `getMetaModel with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.metamodel
}
@Test(timeout = 300_000)
fun testGetTransaction() {
fun `getTransaction with target platform version of current corda version executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
whenever(entitymanager.transaction).doReturn(transaction)
assertTrue(restrictedEntityManager.transaction is RestrictedEntityTransaction)
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testJoinTransaction() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `joinTransaction with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.joinTransaction()
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testLockWithTwoParameters() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `lock with two parameters with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC)
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testLockWithThreeParameters() {
val map: MutableMap<String,Any> = mutableMapOf()
restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC,map)
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `lock with three parameters with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
val map: MutableMap<String, Any> = mutableMapOf()
restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC, map)
}
@Test(expected = UnsupportedOperationException::class, timeout=300_000)
fun testSetProperty() {
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setProperty with target platform version of current corda version throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(PLATFORM_VERSION)
restrictedEntityManager.setProperty("number", 12)
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `close with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedEntityManager.close()
}
@Test(timeout = 300_000)
fun `clear with target platform version of 7 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedEntityManager.clear()
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `getMetaModel with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedEntityManager.metamodel
}
@Test(timeout = 300_000)
fun `getTransaction with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
whenever(entitymanager.transaction).doReturn(transaction)
assertTrue(restrictedEntityManager.transaction is RestrictedEntityTransaction)
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `joinTransaction with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedEntityManager.joinTransaction()
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `lock with two parameters with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC)
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `lock with three parameters with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
val map: MutableMap<String, Any> = mutableMapOf()
restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC, map)
}
@Test(expected = UnsupportedOperationException::class, timeout = 300_000)
fun `setProperty with target platform version of 7 throws unsupported exception`() {
whenever(cordapp.targetPlatformVersion).thenReturn(7)
restrictedEntityManager.setProperty("number", 12)
}
@Test(timeout = 300_000)
fun `close with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedEntityManager.close()
}
@Test(timeout = 300_000)
fun `clear with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedEntityManager.clear()
}
@Test(timeout = 300_000)
fun `getMetaModel with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedEntityManager.metamodel
}
@Test(timeout = 300_000)
fun `getTransaction with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
whenever(entitymanager.transaction).doReturn(transaction)
assertTrue(restrictedEntityManager.transaction is RestrictedEntityTransaction)
}
@Test(timeout = 300_000)
fun `joinTransaction with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedEntityManager.joinTransaction()
}
@Test(timeout = 300_000)
fun `lock with two parameters with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC)
}
@Test(timeout = 300_000)
fun `lock with three parameters with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
val map: MutableMap<String, Any> = mutableMapOf()
restrictedEntityManager.lock(Object(), LockModeType.OPTIMISTIC, map)
}
@Test(timeout = 300_000)
fun `setProperty with target platform version of 6 executes successfully`() {
whenever(cordapp.targetPlatformVersion).thenReturn(6)
restrictedEntityManager.setProperty("number", 12)
}
}