mirror of
https://github.com/corda/corda.git
synced 2025-06-18 07:08:15 +00:00
Replace mapToArray with Streams-based code (#739)
and you can now do (1..10).stream()...
This commit is contained in:
30
core/src/main/kotlin/net/corda/core/Streams.kt
Normal file
30
core/src/main/kotlin/net/corda/core/Streams.kt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package net.corda.core
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
import java.util.Spliterator.*
|
||||||
|
import java.util.stream.IntStream
|
||||||
|
import java.util.stream.Stream
|
||||||
|
import java.util.stream.StreamSupport
|
||||||
|
import kotlin.streams.asSequence
|
||||||
|
|
||||||
|
private fun IntProgression.spliteratorOfInt(): Spliterator.OfInt {
|
||||||
|
val kotlinIterator = iterator()
|
||||||
|
val javaIterator = object : PrimitiveIterator.OfInt {
|
||||||
|
override fun nextInt() = kotlinIterator.nextInt()
|
||||||
|
override fun hasNext() = kotlinIterator.hasNext()
|
||||||
|
override fun remove() = throw UnsupportedOperationException("remove")
|
||||||
|
}
|
||||||
|
val spliterator = Spliterators.spliterator(
|
||||||
|
javaIterator,
|
||||||
|
(1 + (last - first) / step).toLong(),
|
||||||
|
SUBSIZED or IMMUTABLE or NONNULL or SIZED or ORDERED or SORTED or DISTINCT
|
||||||
|
)
|
||||||
|
return if (step > 0) spliterator else object : Spliterator.OfInt by spliterator {
|
||||||
|
override fun getComparator() = Comparator.reverseOrder<Int>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IntProgression.stream(): IntStream = StreamSupport.intStream(spliteratorOfInt(), false)
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST") // When toArray has filled in the array, the component type is no longer T? but T (that may itself be nullable).
|
||||||
|
inline fun <reified T> Stream<out T>.toTypedArray() = toArray { size -> arrayOfNulls<T>(size) } as Array<T>
|
@ -24,7 +24,6 @@ import java.nio.file.*
|
|||||||
import java.nio.file.attribute.FileAttribute
|
import java.nio.file.attribute.FileAttribute
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.temporal.Temporal
|
import java.time.temporal.Temporal
|
||||||
import java.util.HashMap
|
|
||||||
import java.util.concurrent.*
|
import java.util.concurrent.*
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
import java.util.function.BiConsumer
|
import java.util.function.BiConsumer
|
||||||
@ -111,16 +110,6 @@ fun <T> ListenableFuture<T>.andForget(log: Logger) = failure(RunOnCallerThread)
|
|||||||
infix fun <F, T> ListenableFuture<F>.map(mapper: (F) -> T): ListenableFuture<T> = Futures.transform(this, { (mapper as (F?) -> T)(it) })
|
infix fun <F, T> ListenableFuture<F>.map(mapper: (F) -> T): ListenableFuture<T> = Futures.transform(this, { (mapper as (F?) -> T)(it) })
|
||||||
infix fun <F, T> ListenableFuture<F>.flatMap(mapper: (F) -> ListenableFuture<T>): ListenableFuture<T> = Futures.transformAsync(this) { mapper(it!!) }
|
infix fun <F, T> ListenableFuture<F>.flatMap(mapper: (F) -> ListenableFuture<T>): ListenableFuture<T> = Futures.transformAsync(this) { mapper(it!!) }
|
||||||
|
|
||||||
inline fun <T, reified R> Collection<T>.mapToArray(transform: (T) -> R) = mapToArray(transform, iterator(), size)
|
|
||||||
inline fun <reified R> IntProgression.mapToArray(transform: (Int) -> R) = mapToArray(transform, iterator(), 1 + (last - first) / step)
|
|
||||||
inline fun <T, reified R> mapToArray(transform: (T) -> R, iterator: Iterator<T>, size: Int) = run {
|
|
||||||
var expected = 0
|
|
||||||
Array(size) {
|
|
||||||
expected++ == it || throw UnsupportedOperationException("Array constructor is non-sequential!")
|
|
||||||
transform(iterator.next())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Executes the given block and sets the future to either the result, or any exception that was thrown. */
|
/** Executes the given block and sets the future to either the result, or any exception that was thrown. */
|
||||||
inline fun <T> SettableFuture<T>.catch(block: () -> T) {
|
inline fun <T> SettableFuture<T>.catch(block: () -> T) {
|
||||||
try {
|
try {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package net.corda.core.crypto
|
package net.corda.core.crypto
|
||||||
|
|
||||||
import net.corda.core.crypto.Crypto.generateKeyPair
|
import net.corda.core.crypto.Crypto.generateKeyPair
|
||||||
import net.corda.core.mapToArray
|
|
||||||
import org.bouncycastle.asn1.ASN1Encodable
|
import org.bouncycastle.asn1.ASN1Encodable
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
import org.bouncycastle.asn1.x500.X500NameBuilder
|
import org.bouncycastle.asn1.x500.X500NameBuilder
|
||||||
|
42
core/src/test/kotlin/net/corda/core/StreamsTest.kt
Normal file
42
core/src/test/kotlin/net/corda/core/StreamsTest.kt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package net.corda.core
|
||||||
|
|
||||||
|
import org.junit.Assert.assertArrayEquals
|
||||||
|
import org.junit.Test
|
||||||
|
import java.util.stream.IntStream
|
||||||
|
import java.util.stream.Stream
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class StreamsTest {
|
||||||
|
@Test
|
||||||
|
fun `IntProgression stream works`() {
|
||||||
|
assertArrayEquals(intArrayOf(1, 2, 3, 4), (1..4).stream().toArray())
|
||||||
|
assertArrayEquals(intArrayOf(1, 2, 3, 4), (1 until 5).stream().toArray())
|
||||||
|
assertArrayEquals(intArrayOf(1, 3), (1..4 step 2).stream().toArray())
|
||||||
|
assertArrayEquals(intArrayOf(1, 3), (1..3 step 2).stream().toArray())
|
||||||
|
assertArrayEquals(intArrayOf(), (1..0).stream().toArray())
|
||||||
|
assertArrayEquals(intArrayOf(1, 0), (1 downTo 0).stream().toArray())
|
||||||
|
assertArrayEquals(intArrayOf(3, 1), (3 downTo 0 step 2).stream().toArray())
|
||||||
|
assertArrayEquals(intArrayOf(3, 1), (3 downTo 1 step 2).stream().toArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `IntProgression spliterator characteristics and comparator`() {
|
||||||
|
val rangeCharacteristics = IntStream.range(0, 2).spliterator().characteristics()
|
||||||
|
val forward = (0..9 step 3).stream().spliterator()
|
||||||
|
assertEquals(rangeCharacteristics, forward.characteristics())
|
||||||
|
assertEquals(null, forward.comparator)
|
||||||
|
val reverse = (9 downTo 0 step 3).stream().spliterator()
|
||||||
|
assertEquals(rangeCharacteristics, reverse.characteristics())
|
||||||
|
assertEquals(Comparator.reverseOrder(), reverse.comparator)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Stream toTypedArray works`() {
|
||||||
|
val a: Array<String> = Stream.of("one", "two").toTypedArray()
|
||||||
|
assertEquals(Array<String>::class.java, a.javaClass)
|
||||||
|
assertArrayEquals(arrayOf("one", "two"), a)
|
||||||
|
val b: Array<String?> = Stream.of("one", "two", null).toTypedArray()
|
||||||
|
assertEquals(Array<String?>::class.java, b.javaClass)
|
||||||
|
assertArrayEquals(arrayOf("one", "two", null), b)
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,16 @@
|
|||||||
package net.corda.core.crypto
|
package net.corda.core.crypto
|
||||||
|
|
||||||
import net.corda.core.mapToArray
|
import net.corda.core.toTypedArray
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
import org.bouncycastle.asn1.x509.GeneralName
|
import org.bouncycastle.asn1.x509.GeneralName
|
||||||
import org.bouncycastle.asn1.x509.GeneralSubtree
|
import org.bouncycastle.asn1.x509.GeneralSubtree
|
||||||
import org.bouncycastle.asn1.x509.NameConstraints
|
import org.bouncycastle.asn1.x509.NameConstraints
|
||||||
import org.bouncycastle.cert.X509CertificateHolder
|
|
||||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
|
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.security.KeyStore
|
import java.security.KeyStore
|
||||||
import java.security.cert.*
|
import java.security.cert.*
|
||||||
|
import java.util.stream.Stream
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ class X509NameConstraintsTest {
|
|||||||
val keyStore = KeyStore.getInstance(KeyStoreUtilities.KEYSTORE_TYPE)
|
val keyStore = KeyStore.getInstance(KeyStoreUtilities.KEYSTORE_TYPE)
|
||||||
keyStore.load(null, keyPass.toCharArray())
|
keyStore.load(null, keyPass.toCharArray())
|
||||||
keyStore.addOrReplaceKey(X509Utilities.CORDA_CLIENT_TLS, tlsKey.private, keyPass.toCharArray(),
|
keyStore.addOrReplaceKey(X509Utilities.CORDA_CLIENT_TLS, tlsKey.private, keyPass.toCharArray(),
|
||||||
listOf(tlsCert, clientCACert, intermediateCACert, rootCACert).mapToArray<X509CertificateHolder, Certificate>(converter::getCertificate))
|
Stream.of(tlsCert, clientCACert, intermediateCACert, rootCACert).map(converter::getCertificate).toTypedArray<Certificate>())
|
||||||
return Pair(keyStore, trustStore)
|
return Pair(keyStore, trustStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,14 +5,13 @@ import net.corda.core.crypto.Crypto.generateKeyPair
|
|||||||
import net.corda.core.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME
|
import net.corda.core.crypto.X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME
|
||||||
import net.corda.core.crypto.X509Utilities.createSelfSignedCACertificate
|
import net.corda.core.crypto.X509Utilities.createSelfSignedCACertificate
|
||||||
import net.corda.core.div
|
import net.corda.core.div
|
||||||
import net.corda.core.mapToArray
|
import net.corda.core.toTypedArray
|
||||||
import net.corda.testing.MEGA_CORP
|
import net.corda.testing.MEGA_CORP
|
||||||
import net.corda.testing.getTestX509Name
|
import net.corda.testing.getTestX509Name
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
import org.bouncycastle.asn1.x509.BasicConstraints
|
import org.bouncycastle.asn1.x509.BasicConstraints
|
||||||
import org.bouncycastle.asn1.x509.Extension
|
import org.bouncycastle.asn1.x509.Extension
|
||||||
import org.bouncycastle.asn1.x509.KeyUsage
|
import org.bouncycastle.asn1.x509.KeyUsage
|
||||||
import org.bouncycastle.cert.X509CertificateHolder
|
|
||||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
|
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
|
||||||
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder
|
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
@ -21,7 +20,6 @@ import org.junit.rules.TemporaryFolder
|
|||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.math.BigInteger
|
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.net.InetSocketAddress
|
import java.net.InetSocketAddress
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@ -31,6 +29,7 @@ import java.security.SecureRandom
|
|||||||
import java.security.cert.Certificate
|
import java.security.cert.Certificate
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.stream.Stream
|
||||||
import javax.net.ssl.*
|
import javax.net.ssl.*
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
@ -94,7 +93,7 @@ class X509UtilitiesTest {
|
|||||||
// Save the EdDSA private key with self sign cert in the keystore.
|
// Save the EdDSA private key with self sign cert in the keystore.
|
||||||
val keyStore = KeyStoreUtilities.loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
val keyStore = KeyStoreUtilities.loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||||
keyStore.setKeyEntry("Key", keyPair.private, "password".toCharArray(),
|
keyStore.setKeyEntry("Key", keyPair.private, "password".toCharArray(),
|
||||||
listOf(selfSignCert).mapToArray(converter::getCertificate))
|
Stream.of(selfSignCert).map(converter::getCertificate).toTypedArray())
|
||||||
keyStore.save(tmpKeyStore, "keystorepass")
|
keyStore.save(tmpKeyStore, "keystorepass")
|
||||||
|
|
||||||
// Load the keystore from file and make sure keys are intact.
|
// Load the keystore from file and make sure keys are intact.
|
||||||
@ -120,7 +119,7 @@ class X509UtilitiesTest {
|
|||||||
val converter = JcaX509CertificateConverter()
|
val converter = JcaX509CertificateConverter()
|
||||||
val keyStore = KeyStoreUtilities.loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
val keyStore = KeyStoreUtilities.loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||||
keyStore.setKeyEntry("Key", edDSAKeypair.private, "password".toCharArray(),
|
keyStore.setKeyEntry("Key", edDSAKeypair.private, "password".toCharArray(),
|
||||||
listOf(ecDSACert, edDSACert).mapToArray(converter::getCertificate))
|
Stream.of(ecDSACert, edDSACert).map(converter::getCertificate).toTypedArray())
|
||||||
keyStore.save(tmpKeyStore, "keystorepass")
|
keyStore.save(tmpKeyStore, "keystorepass")
|
||||||
|
|
||||||
// Load the keystore from file and make sure keys are intact.
|
// Load the keystore from file and make sure keys are intact.
|
||||||
@ -360,7 +359,7 @@ class X509UtilitiesTest {
|
|||||||
keyStore.addOrReplaceKey(X509Utilities.CORDA_INTERMEDIATE_CA,
|
keyStore.addOrReplaceKey(X509Utilities.CORDA_INTERMEDIATE_CA,
|
||||||
intermediateCAKeyPair.private,
|
intermediateCAKeyPair.private,
|
||||||
keyPass,
|
keyPass,
|
||||||
listOf(intermediateCACert, rootCACert).mapToArray<X509CertificateHolder, Certificate>(converter::getCertificate))
|
Stream.of(intermediateCACert, rootCACert).map(converter::getCertificate).toTypedArray<Certificate>())
|
||||||
|
|
||||||
keyStore.save(keyStoreFilePath, storePassword)
|
keyStore.save(keyStoreFilePath, storePassword)
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import com.nhaarman.mockito_kotlin.eq
|
|||||||
import com.nhaarman.mockito_kotlin.mock
|
import com.nhaarman.mockito_kotlin.mock
|
||||||
import net.corda.core.crypto.*
|
import net.corda.core.crypto.*
|
||||||
import net.corda.core.exists
|
import net.corda.core.exists
|
||||||
import net.corda.core.mapToArray
|
import net.corda.core.toTypedArray
|
||||||
import net.corda.core.utilities.ALICE
|
import net.corda.core.utilities.ALICE
|
||||||
import net.corda.testing.TestNodeConfiguration
|
import net.corda.testing.TestNodeConfiguration
|
||||||
import net.corda.testing.getTestX509Name
|
import net.corda.testing.getTestX509Name
|
||||||
@ -32,8 +32,8 @@ class NetworkRegistrationHelperTest {
|
|||||||
"CORDA_ROOT_CA")
|
"CORDA_ROOT_CA")
|
||||||
.map { getTestX509Name(it) }
|
.map { getTestX509Name(it) }
|
||||||
val converter = JcaX509CertificateConverter()
|
val converter = JcaX509CertificateConverter()
|
||||||
val certs = identities.map { X509Utilities.createSelfSignedCACertificate(it, Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)) }
|
val certs = identities.stream().map { X509Utilities.createSelfSignedCACertificate(it, Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)) }
|
||||||
.mapToArray(converter::getCertificate)
|
.map(converter::getCertificate).toTypedArray()
|
||||||
|
|
||||||
val certService: NetworkRegistrationService = mock {
|
val certService: NetworkRegistrationService = mock {
|
||||||
on { submitRequest(any()) }.then { id }
|
on { submitRequest(any()) }.then { id }
|
||||||
|
@ -13,13 +13,14 @@ import net.corda.node.utilities.ServiceIdentityGenerator
|
|||||||
import net.corda.cordform.CordformDefinition
|
import net.corda.cordform.CordformDefinition
|
||||||
import net.corda.cordform.CordformContext
|
import net.corda.cordform.CordformContext
|
||||||
import net.corda.cordform.CordformNode
|
import net.corda.cordform.CordformNode
|
||||||
import net.corda.core.mapToArray
|
import net.corda.core.stream
|
||||||
|
import net.corda.core.toTypedArray
|
||||||
import net.corda.node.services.transactions.minCorrectReplicas
|
import net.corda.node.services.transactions.minCorrectReplicas
|
||||||
import org.bouncycastle.asn1.x500.X500Name
|
import org.bouncycastle.asn1.x500.X500Name
|
||||||
|
|
||||||
fun main(args: Array<String>) = BFTNotaryCordform.runNodes()
|
fun main(args: Array<String>) = BFTNotaryCordform.runNodes()
|
||||||
|
|
||||||
private val clusterSize = 4 // Minimum size thats tolerates a faulty replica.
|
private val clusterSize = 4 // Minimum size that tolerates a faulty replica.
|
||||||
private val notaryNames = createNotaryNames(clusterSize)
|
private val notaryNames = createNotaryNames(clusterSize)
|
||||||
|
|
||||||
object BFTNotaryCordform : CordformDefinition("build" / "notary-demo-nodes", notaryNames[0]) {
|
object BFTNotaryCordform : CordformDefinition("build" / "notary-demo-nodes", notaryNames[0]) {
|
||||||
@ -38,7 +39,7 @@ object BFTNotaryCordform : CordformDefinition("build" / "notary-demo-nodes", not
|
|||||||
p2pPort(10005)
|
p2pPort(10005)
|
||||||
rpcPort(10006)
|
rpcPort(10006)
|
||||||
}
|
}
|
||||||
val clusterAddresses = (0 until clusterSize).mapToArray { HostAndPort.fromParts("localhost", 11000 + it * 10) }
|
val clusterAddresses = (0 until clusterSize).stream().mapToObj { HostAndPort.fromParts("localhost", 11000 + it * 10) }.toTypedArray()
|
||||||
fun notaryNode(replicaId: Int, configure: CordformNode.() -> Unit) = node {
|
fun notaryNode(replicaId: Int, configure: CordformNode.() -> Unit) = node {
|
||||||
name(notaryNames[replicaId])
|
name(notaryNames[replicaId])
|
||||||
advertisedServices(advertisedService)
|
advertisedServices(advertisedService)
|
||||||
|
@ -14,6 +14,7 @@ import net.corda.core.transactions.SignedTransaction
|
|||||||
import net.corda.core.utilities.BOB
|
import net.corda.core.utilities.BOB
|
||||||
import net.corda.notarydemo.flows.DummyIssueAndMove
|
import net.corda.notarydemo.flows.DummyIssueAndMove
|
||||||
import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient
|
import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient
|
||||||
|
import kotlin.streams.asSequence
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
val address = HostAndPort.fromParts("localhost", 10003)
|
val address = HostAndPort.fromParts("localhost", 10003)
|
||||||
@ -28,7 +29,8 @@ private class NotaryDemoClientApi(val rpc: CordaRPCOps) {
|
|||||||
private val notary by lazy {
|
private val notary by lazy {
|
||||||
val (parties, partyUpdates) = rpc.networkMapUpdates()
|
val (parties, partyUpdates) = rpc.networkMapUpdates()
|
||||||
partyUpdates.notUsed()
|
partyUpdates.notUsed()
|
||||||
parties.filter { it.advertisedServices.any { it.info.type.isNotary() } }.map { it.notaryIdentity }.distinct().single()
|
val id = parties.stream().filter { it.advertisedServices.any { it.info.type.isNotary() } }.map { it.notaryIdentity }.distinct().asSequence().singleOrNull()
|
||||||
|
checkNotNull(id) { "No unique notary identity, try cleaning the node directories." }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val counterpartyNode by lazy {
|
private val counterpartyNode by lazy {
|
||||||
|
Reference in New Issue
Block a user