mirror of
https://github.com/corda/corda.git
synced 2025-06-01 15:10:54 +00:00
CORDA-2128: Some utils which shouldn't be public (#4468)
This commit is contained in:
parent
c08f65a92c
commit
347d779c03
@ -5,7 +5,6 @@ import net.corda.core.crypto.isFulfilledBy
|
|||||||
import net.corda.core.crypto.keys
|
import net.corda.core.crypto.keys
|
||||||
import net.corda.core.internal.cordapp.CordappImpl
|
import net.corda.core.internal.cordapp.CordappImpl
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.core.utilities.warnOnce
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contract version and flow versions are integers.
|
* Contract version and flow versions are integers.
|
||||||
|
@ -50,7 +50,6 @@ import java.util.stream.StreamSupport
|
|||||||
import java.util.zip.Deflater
|
import java.util.zip.Deflater
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
import kotlin.collections.AbstractList
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.full.createInstance
|
import kotlin.reflect.full.createInstance
|
||||||
|
|
||||||
@ -517,7 +516,10 @@ fun <K, V> createSimpleCache(maxSize: Int, onEject: (MutableMap.MutableEntry<K,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @see Collections.synchronizedMap */
|
||||||
fun <K, V> MutableMap<K, V>.toSynchronised(): MutableMap<K, V> = Collections.synchronizedMap(this)
|
fun <K, V> MutableMap<K, V>.toSynchronised(): MutableMap<K, V> = Collections.synchronizedMap(this)
|
||||||
|
/** @see Collections.synchronizedSet */
|
||||||
|
fun <E> MutableSet<E>.toSynchronised(): MutableSet<E> = Collections.synchronizedSet(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List implementation that applies the expensive [transform] function only when the element is accessed and caches calculated values.
|
* List implementation that applies the expensive [transform] function only when the element is accessed and caches calculated values.
|
||||||
@ -531,3 +533,22 @@ class LazyMappedList<T, U>(val originalList: List<T>, val transform: (T, Int) ->
|
|||||||
?: transform(originalList[index], index).also { computed -> partialResolvedList[index] = computed }
|
?: transform(originalList[index], index).also { computed -> partialResolvedList[index] = computed }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a [List] implementation that applies the expensive [transform] function only when an element is accessed and then caches the calculated values.
|
||||||
|
* Size is very cheap as it doesn't call [transform].
|
||||||
|
*/
|
||||||
|
fun <T, U> List<T>.lazyMapped(transform: (T, Int) -> U): List<U> = LazyMappedList(this, transform)
|
||||||
|
|
||||||
|
private const val MAX_SIZE = 100
|
||||||
|
private val warnings = Collections.newSetFromMap(createSimpleCache<String, Boolean>(MAX_SIZE)).toSynchronised()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility to help log a warning message only once.
|
||||||
|
* It implements an ad hoc Fifo cache because there's none available in the standard libraries.
|
||||||
|
*/
|
||||||
|
fun Logger.warnOnce(warning: String) {
|
||||||
|
if (warnings.add(warning)) {
|
||||||
|
this.warn(warning)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,7 +10,6 @@ import net.corda.core.identity.Party
|
|||||||
import net.corda.core.serialization.*
|
import net.corda.core.serialization.*
|
||||||
import net.corda.core.transactions.*
|
import net.corda.core.transactions.*
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.core.utilities.lazyMapped
|
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
@ -2,7 +2,7 @@ package net.corda.core.internal.rules
|
|||||||
|
|
||||||
import net.corda.core.contracts.ContractState
|
import net.corda.core.contracts.ContractState
|
||||||
import net.corda.core.internal.cordapp.targetPlatformVersion
|
import net.corda.core.internal.cordapp.targetPlatformVersion
|
||||||
import net.corda.core.utilities.warnOnce
|
import net.corda.core.internal.warnOnce
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
@ -17,7 +17,6 @@ import net.corda.core.serialization.CordaSerializable
|
|||||||
import net.corda.core.serialization.DeprecatedConstructorForDeserialization
|
import net.corda.core.serialization.DeprecatedConstructorForDeserialization
|
||||||
import net.corda.core.serialization.internal.AttachmentsClassLoaderBuilder
|
import net.corda.core.serialization.internal.AttachmentsClassLoaderBuilder
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.core.utilities.warnOnce
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.function.Predicate
|
import java.util.function.Predicate
|
||||||
import kotlin.collections.HashSet
|
import kotlin.collections.HashSet
|
||||||
|
@ -17,7 +17,6 @@ import net.corda.core.node.services.KeyManagementService
|
|||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
import net.corda.core.serialization.SerializationFactory
|
import net.corda.core.serialization.SerializationFactory
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.core.utilities.warnOnce
|
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
@ -18,7 +18,6 @@ import net.corda.core.serialization.CordaSerializable
|
|||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
import net.corda.core.utilities.lazyMapped
|
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.security.SignatureException
|
import java.security.SignatureException
|
||||||
import java.util.function.Predicate
|
import java.util.function.Predicate
|
||||||
|
@ -30,10 +30,6 @@ infix fun Int.exactAdd(b: Int): Int = Math.addExact(this, b)
|
|||||||
/** Like the + operator but throws [ArithmeticException] in case of integer overflow. */
|
/** Like the + operator but throws [ArithmeticException] in case of integer overflow. */
|
||||||
infix fun Long.exactAdd(b: Long): Long = Math.addExact(this, b)
|
infix fun Long.exactAdd(b: Long): Long = Math.addExact(this, b)
|
||||||
|
|
||||||
/** There is no special case function for filtering null values out of a map in the stdlib */
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
fun <K, V> Map<K, V?>.filterNotNullValues() = filterValues { it != null } as Map<K, V>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usually you won't need this method:
|
* Usually you won't need this method:
|
||||||
* * If you're in a companion object, use [contextLogger]
|
* * If you're in a companion object, use [contextLogger]
|
||||||
@ -142,24 +138,3 @@ fun <V> Future<V>.getOrThrow(timeout: Duration? = null): V = try {
|
|||||||
} catch (e: ExecutionException) {
|
} catch (e: ExecutionException) {
|
||||||
throw e.cause!!
|
throw e.cause!!
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a [List] implementation that applies the expensive [transform] function only when an element is accessed and then caches the calculated values.
|
|
||||||
* Size is very cheap as it doesn't call [transform].
|
|
||||||
*/
|
|
||||||
fun <T, U> List<T>.lazyMapped(transform: (T, Int) -> U): List<U> = LazyMappedList(this, transform)
|
|
||||||
|
|
||||||
private const val MAX_SIZE = 100
|
|
||||||
private val warnings = Collections.newSetFromMap(createSimpleCache<String, Boolean>(MAX_SIZE))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility to help log a warning message only once.
|
|
||||||
* It implements an ad hoc Fifo cache because there's none available in the standard libraries.
|
|
||||||
*/
|
|
||||||
@Synchronized
|
|
||||||
fun Logger.warnOnce(warning: String) {
|
|
||||||
if (warning !in warnings) {
|
|
||||||
warnings.add(warning)
|
|
||||||
this.warn(warning)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
package net.corda.core
|
package net.corda.core
|
||||||
|
|
||||||
import com.nhaarman.mockito_kotlin.mock
|
|
||||||
import com.nhaarman.mockito_kotlin.times
|
|
||||||
import com.nhaarman.mockito_kotlin.verify
|
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
import net.corda.core.utilities.warnOnce
|
|
||||||
import org.assertj.core.api.Assertions.*
|
import org.assertj.core.api.Assertions.*
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.slf4j.Logger
|
|
||||||
import rx.subjects.PublishSubject
|
import rx.subjects.PublishSubject
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.CancellationException
|
import java.util.concurrent.CancellationException
|
||||||
@ -63,24 +58,4 @@ class UtilsTest {
|
|||||||
future.get()
|
future.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `warnOnce works, but the backing cache grows only to a maximum size`() {
|
|
||||||
val MAX_SIZE = 100
|
|
||||||
|
|
||||||
val logger = mock<Logger>()
|
|
||||||
logger.warnOnce("a")
|
|
||||||
logger.warnOnce("b")
|
|
||||||
logger.warnOnce("b")
|
|
||||||
|
|
||||||
// This should cause the eviction of "a".
|
|
||||||
(1..MAX_SIZE).forEach { logger.warnOnce("$it") }
|
|
||||||
logger.warnOnce("a")
|
|
||||||
|
|
||||||
// "a" should be logged twice because it was evicted.
|
|
||||||
verify(logger, times(2)).warn("a")
|
|
||||||
|
|
||||||
// "b" should be logged only once because there was no eviction.
|
|
||||||
verify(logger, times(1)).warn("b")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
package net.corda.core.internal
|
package net.corda.core.internal
|
||||||
|
|
||||||
|
import com.nhaarman.mockito_kotlin.mock
|
||||||
|
import com.nhaarman.mockito_kotlin.times
|
||||||
|
import com.nhaarman.mockito_kotlin.verify
|
||||||
import net.corda.core.contracts.TimeWindow
|
import net.corda.core.contracts.TimeWindow
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.Assert.assertArrayEquals
|
import org.junit.Assert.assertArrayEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import org.slf4j.Logger
|
||||||
import rx.subjects.PublishSubject
|
import rx.subjects.PublishSubject
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.stream.IntStream
|
import java.util.stream.IntStream
|
||||||
@ -109,10 +113,10 @@ open class InternalUtilsTest {
|
|||||||
|
|
||||||
sourceSubject.onNext(1)
|
sourceSubject.onNext(1)
|
||||||
|
|
||||||
var itemsFromBufferedObservable = mutableSetOf<Int>()
|
val itemsFromBufferedObservable = mutableSetOf<Int>()
|
||||||
bufferedObservable.subscribe{itemsFromBufferedObservable.add(it)}
|
bufferedObservable.subscribe{itemsFromBufferedObservable.add(it)}
|
||||||
|
|
||||||
var itemsFromNonBufferedObservable = mutableSetOf<Int>()
|
val itemsFromNonBufferedObservable = mutableSetOf<Int>()
|
||||||
sourceSubject.subscribe{itemsFromNonBufferedObservable.add(it)}
|
sourceSubject.subscribe{itemsFromNonBufferedObservable.add(it)}
|
||||||
|
|
||||||
assertThat(itemsFromBufferedObservable.contains(1))
|
assertThat(itemsFromBufferedObservable.contains(1))
|
||||||
@ -126,6 +130,26 @@ open class InternalUtilsTest {
|
|||||||
.isEqualTo(SecureHash.parse("A4759E7AA20338328866A2EA17EAF8C7FE4EC6BBE3BB71CEE7DF7C0461B3C22F"))
|
.isEqualTo(SecureHash.parse("A4759E7AA20338328866A2EA17EAF8C7FE4EC6BBE3BB71CEE7DF7C0461B3C22F"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `warnOnce works, but the backing cache grows only to a maximum size`() {
|
||||||
|
val MAX_SIZE = 100
|
||||||
|
|
||||||
|
val logger = mock<Logger>()
|
||||||
|
logger.warnOnce("a")
|
||||||
|
logger.warnOnce("b")
|
||||||
|
logger.warnOnce("b")
|
||||||
|
|
||||||
|
// This should cause the eviction of "a".
|
||||||
|
(1..MAX_SIZE).forEach { logger.warnOnce("$it") }
|
||||||
|
logger.warnOnce("a")
|
||||||
|
|
||||||
|
// "a" should be logged twice because it was evicted.
|
||||||
|
verify(logger, times(2)).warn("a")
|
||||||
|
|
||||||
|
// "b" should be logged only once because there was no eviction.
|
||||||
|
verify(logger, times(1)).warn("b")
|
||||||
|
}
|
||||||
|
|
||||||
private fun arrayOfJunk(size: Int) = ByteArray(size).apply {
|
private fun arrayOfJunk(size: Int) = ByteArray(size).apply {
|
||||||
for (i in 0 until size) {
|
for (i in 0 until size) {
|
||||||
this[i] = (i and 0xFF).toByte()
|
this[i] = (i and 0xFF).toByte()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.corda.core.utilities
|
package net.corda.core.utilities
|
||||||
|
|
||||||
|
import net.corda.core.internal.lazyMapped
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user