mirror of
https://github.com/corda/corda.git
synced 2025-06-17 06:38:21 +00:00
CORDA-716 Rename one TestClock to DemoClock, and unduplicate code (#1988)
This commit is contained in:
61
node/src/main/kotlin/net/corda/node/internal/CordaClock.kt
Normal file
61
node/src/main/kotlin/net/corda/node/internal/CordaClock.kt
Normal file
@ -0,0 +1,61 @@
|
||||
package net.corda.node.internal
|
||||
|
||||
import net.corda.core.serialization.SerializeAsToken
|
||||
import net.corda.core.serialization.SerializeAsTokenContext
|
||||
import net.corda.core.serialization.SingletonSerializationToken
|
||||
import rx.Observable
|
||||
import rx.Subscriber
|
||||
import rx.subscriptions.Subscriptions
|
||||
import java.time.Clock
|
||||
import java.time.Instant
|
||||
import java.time.ZoneId
|
||||
import java.util.concurrent.CopyOnWriteArraySet
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
import javax.annotation.concurrent.ThreadSafe
|
||||
|
||||
/** A [Clock] that tokenizes itself when serialized, and delegates to an underlying [Clock] implementation. */
|
||||
abstract class CordaClock : Clock(), SerializeAsToken {
|
||||
protected abstract val delegateClock: Clock
|
||||
private val token = SingletonSerializationToken.singletonSerializationToken(javaClass)
|
||||
override fun toToken(context: SerializeAsTokenContext) = token.registerWithContext(context, this)
|
||||
override fun instant(): Instant = delegateClock.instant()
|
||||
override fun getZone(): ZoneId = delegateClock.zone
|
||||
@Deprecated("Do not use this. Instead seek to use ZonedDateTime methods.", level = DeprecationLevel.ERROR)
|
||||
override fun withZone(zone: ZoneId) = throw UnsupportedOperationException("Tokenized clock does not support withZone()")
|
||||
}
|
||||
|
||||
@ThreadSafe
|
||||
class SimpleClock(override val delegateClock: Clock) : CordaClock()
|
||||
|
||||
/**
|
||||
* An abstract class with helper methods for a type of Clock that might have it's concept of "now" adjusted externally.
|
||||
* e.g. for testing (so unit tests do not have to wait for timeouts in realtime) or for demos and simulations.
|
||||
*/
|
||||
abstract class MutableClock(private var _delegateClock: Clock) : CordaClock() {
|
||||
override var delegateClock
|
||||
@Synchronized get() = _delegateClock
|
||||
@Synchronized set(clock) {
|
||||
_delegateClock = clock
|
||||
}
|
||||
private val _version = AtomicLong(0L)
|
||||
/** This is an observer on the mutation count of this [Clock], which reflects the occurence of mutations. */
|
||||
val mutations: Observable<Long> by lazy {
|
||||
Observable.create { subscriber: Subscriber<in Long> ->
|
||||
if (!subscriber.isUnsubscribed) {
|
||||
mutationObservers.add(subscriber)
|
||||
// This is not very intuitive, but subscribing to a subscriber observes unsubscribes.
|
||||
subscriber.add(Subscriptions.create { mutationObservers.remove(subscriber) })
|
||||
}
|
||||
}
|
||||
}
|
||||
private val mutationObservers = CopyOnWriteArraySet<Subscriber<in Long>>()
|
||||
/** Must be called by subclasses when they mutate (but not just with the passage of time as per the "wall clock"). */
|
||||
protected fun notifyMutationObservers() {
|
||||
val version = _version.incrementAndGet()
|
||||
for (observer in mutationObservers) {
|
||||
if (!observer.isUnsubscribed) {
|
||||
observer.onNext(version)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package net.corda.node.internal
|
||||
|
||||
import rx.Observable
|
||||
import rx.Subscriber
|
||||
import rx.subscriptions.Subscriptions
|
||||
import java.time.Clock
|
||||
import java.util.concurrent.CopyOnWriteArraySet
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
/**
|
||||
* An abstract class with helper methods for a type of Clock that might have it's concept of "now"
|
||||
* adjusted externally.
|
||||
*
|
||||
* e.g. for testing (so unit tests do not have to wait for timeouts in realtime) or for demos and simulations.
|
||||
*/
|
||||
abstract class MutableClock : Clock() {
|
||||
private val _version = AtomicLong(0L)
|
||||
|
||||
/**
|
||||
* This is an observer on the mutation count of this [Clock], which reflects the occurence of mutations.
|
||||
*/
|
||||
val mutations: Observable<Long> by lazy {
|
||||
Observable.create({ subscriber: Subscriber<in Long> ->
|
||||
if (!subscriber.isUnsubscribed) {
|
||||
mutationObservers.add(subscriber)
|
||||
// This is not very intuitive, but subscribing to a subscriber observes unsubscribes.
|
||||
subscriber.add(Subscriptions.create { mutationObservers.remove(subscriber) })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private val mutationObservers = CopyOnWriteArraySet<Subscriber<in Long>>()
|
||||
|
||||
/**
|
||||
* Must be called by subclasses when they mutate (but not just with the passage of time as per the "wall clock").
|
||||
*/
|
||||
protected fun notifyMutationObservers() {
|
||||
val version = _version.incrementAndGet()
|
||||
for (observer in mutationObservers) {
|
||||
if (!observer.isUnsubscribed) {
|
||||
observer.onNext(version)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,6 @@ import net.corda.core.utilities.loggerFor
|
||||
import net.corda.node.VersionInfo
|
||||
import net.corda.node.internal.cordapp.CordappLoader
|
||||
import net.corda.node.serialization.KryoServerSerializationScheme
|
||||
import net.corda.node.serialization.NodeClock
|
||||
import net.corda.node.services.RPCUserService
|
||||
import net.corda.node.services.RPCUserServiceImpl
|
||||
import net.corda.node.services.api.SchemaService
|
||||
@ -25,7 +24,7 @@ import net.corda.node.services.messaging.MessagingService
|
||||
import net.corda.node.services.messaging.NodeMessagingClient
|
||||
import net.corda.node.utilities.AddressUtils
|
||||
import net.corda.node.utilities.AffinityExecutor
|
||||
import net.corda.node.utilities.TestClock
|
||||
import net.corda.node.utilities.DemoClock
|
||||
import net.corda.nodeapi.ArtemisMessagingComponent
|
||||
import net.corda.nodeapi.internal.ShutdownHook
|
||||
import net.corda.nodeapi.internal.addShutdownHook
|
||||
@ -67,7 +66,7 @@ open class Node(configuration: NodeConfiguration,
|
||||
}
|
||||
|
||||
private fun createClock(configuration: NodeConfiguration): Clock {
|
||||
return if (configuration.useTestClock) TestClock() else NodeClock()
|
||||
return (if (configuration.useTestClock) ::DemoClock else ::SimpleClock)(Clock.systemUTC())
|
||||
}
|
||||
|
||||
private val sameVmNodeCounter = AtomicInteger()
|
||||
|
@ -1,36 +0,0 @@
|
||||
package net.corda.node.serialization
|
||||
|
||||
import net.corda.core.serialization.SerializeAsToken
|
||||
import net.corda.core.serialization.SerializeAsTokenContext
|
||||
import net.corda.core.serialization.SingletonSerializationToken
|
||||
import net.corda.core.serialization.SingletonSerializationToken.Companion.singletonSerializationToken
|
||||
import java.time.Clock
|
||||
import java.time.Instant
|
||||
import java.time.ZoneId
|
||||
import javax.annotation.concurrent.ThreadSafe
|
||||
|
||||
|
||||
/**
|
||||
* A [Clock] that tokenizes itself when serialized, and delegates to an underlying [Clock] implementation.
|
||||
*/
|
||||
@ThreadSafe
|
||||
class NodeClock(private val delegateClock: Clock = Clock.systemUTC()) : Clock(), SerializeAsToken {
|
||||
|
||||
private val token = singletonSerializationToken(javaClass)
|
||||
|
||||
override fun toToken(context: SerializeAsTokenContext) = token.registerWithContext(context, this)
|
||||
|
||||
override fun instant(): Instant {
|
||||
return delegateClock.instant()
|
||||
}
|
||||
|
||||
// Do not use this. Instead seek to use ZonedDateTime methods.
|
||||
override fun withZone(zone: ZoneId): Clock {
|
||||
throw UnsupportedOperationException("Tokenized clock does not support withZone()")
|
||||
}
|
||||
|
||||
override fun getZone(): ZoneId {
|
||||
return delegateClock.zone
|
||||
}
|
||||
|
||||
}
|
23
node/src/main/kotlin/net/corda/node/utilities/DemoClock.kt
Normal file
23
node/src/main/kotlin/net/corda/node/utilities/DemoClock.kt
Normal file
@ -0,0 +1,23 @@
|
||||
package net.corda.node.utilities
|
||||
|
||||
import net.corda.core.internal.until
|
||||
import net.corda.node.internal.MutableClock
|
||||
import java.time.Clock
|
||||
import java.time.LocalDate
|
||||
import javax.annotation.concurrent.ThreadSafe
|
||||
|
||||
/** A [Clock] that can have the date advanced for use in demos. */
|
||||
@ThreadSafe
|
||||
class DemoClock(delegateClock: Clock) : MutableClock(delegateClock) {
|
||||
@Synchronized
|
||||
fun updateDate(date: LocalDate): Boolean {
|
||||
val currentDate = LocalDate.now(this)
|
||||
if (currentDate.isBefore(date)) {
|
||||
// It's ok to increment
|
||||
delegateClock = Clock.offset(delegateClock, currentDate.atStartOfDay() until date.atStartOfDay())
|
||||
notifyMutationObservers()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package net.corda.node.utilities
|
||||
|
||||
import net.corda.core.internal.until
|
||||
import net.corda.core.serialization.SerializeAsToken
|
||||
import net.corda.core.serialization.SerializeAsTokenContext
|
||||
import net.corda.core.serialization.SingletonSerializationToken.Companion.singletonSerializationToken
|
||||
import net.corda.node.internal.MutableClock
|
||||
import java.time.Clock
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
import java.time.ZoneId
|
||||
import javax.annotation.concurrent.ThreadSafe
|
||||
|
||||
/**
|
||||
* A [Clock] that can have the date advanced for use in demos.
|
||||
*/
|
||||
@ThreadSafe
|
||||
class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableClock(), SerializeAsToken {
|
||||
|
||||
private val token = singletonSerializationToken(javaClass)
|
||||
|
||||
override fun toToken(context: SerializeAsTokenContext) = token.registerWithContext(context, this)
|
||||
|
||||
@Synchronized
|
||||
fun updateDate(date: LocalDate): Boolean {
|
||||
val currentDate = LocalDate.now(this)
|
||||
if (currentDate.isBefore(date)) {
|
||||
// It's ok to increment
|
||||
delegateClock = Clock.offset(delegateClock, currentDate.atStartOfDay() until date.atStartOfDay())
|
||||
notifyMutationObservers()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@Synchronized override fun instant(): Instant {
|
||||
return delegateClock.instant()
|
||||
}
|
||||
|
||||
// Do not use this. Instead seek to use ZonedDateTime methods.
|
||||
override fun withZone(zone: ZoneId): Clock {
|
||||
throw UnsupportedOperationException("Tokenized clock does not support withZone()")
|
||||
}
|
||||
|
||||
@Synchronized override fun getZone(): ZoneId {
|
||||
return delegateClock.zone
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user