mirror of
https://github.com/corda/corda.git
synced 2025-02-21 01:42:24 +00:00
Replace mapToArray with Streams-based code (#739)
and you can now do (1..10).stream()...
This commit is contained in:
parent
db9cc3a460
commit
c2ab4cf26f
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.time.Duration
|
||||
import java.time.temporal.Temporal
|
||||
import java.util.HashMap
|
||||
import java.util.concurrent.*
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
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>.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. */
|
||||
inline fun <T> SettableFuture<T>.catch(block: () -> T) {
|
||||
try {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.corda.core.crypto
|
||||
|
||||
import net.corda.core.crypto.Crypto.generateKeyPair
|
||||
import net.corda.core.mapToArray
|
||||
import org.bouncycastle.asn1.ASN1Encodable
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
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
|
||||
|
||||
import net.corda.core.mapToArray
|
||||
import net.corda.core.toTypedArray
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.asn1.x509.GeneralName
|
||||
import org.bouncycastle.asn1.x509.GeneralSubtree
|
||||
import org.bouncycastle.asn1.x509.NameConstraints
|
||||
import org.bouncycastle.cert.X509CertificateHolder
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import org.junit.Test
|
||||
import java.security.KeyStore
|
||||
import java.security.cert.*
|
||||
import java.util.stream.Stream
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@ -38,7 +38,7 @@ class X509NameConstraintsTest {
|
||||
val keyStore = KeyStore.getInstance(KeyStoreUtilities.KEYSTORE_TYPE)
|
||||
keyStore.load(null, 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)
|
||||
}
|
||||
|
||||
|
@ -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.createSelfSignedCACertificate
|
||||
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.getTestX509Name
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import org.bouncycastle.asn1.x509.BasicConstraints
|
||||
import org.bouncycastle.asn1.x509.Extension
|
||||
import org.bouncycastle.asn1.x509.KeyUsage
|
||||
import org.bouncycastle.cert.X509CertificateHolder
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
|
||||
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder
|
||||
import org.junit.Rule
|
||||
@ -21,7 +20,6 @@ import org.junit.rules.TemporaryFolder
|
||||
import java.io.DataInputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.io.IOException
|
||||
import java.math.BigInteger
|
||||
import java.net.InetAddress
|
||||
import java.net.InetSocketAddress
|
||||
import java.nio.file.Path
|
||||
@ -31,6 +29,7 @@ import java.security.SecureRandom
|
||||
import java.security.cert.Certificate
|
||||
import java.security.cert.X509Certificate
|
||||
import java.util.*
|
||||
import java.util.stream.Stream
|
||||
import javax.net.ssl.*
|
||||
import kotlin.concurrent.thread
|
||||
import kotlin.test.*
|
||||
@ -94,7 +93,7 @@ class X509UtilitiesTest {
|
||||
// Save the EdDSA private key with self sign cert in the keystore.
|
||||
val keyStore = KeyStoreUtilities.loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||
keyStore.setKeyEntry("Key", keyPair.private, "password".toCharArray(),
|
||||
listOf(selfSignCert).mapToArray(converter::getCertificate))
|
||||
Stream.of(selfSignCert).map(converter::getCertificate).toTypedArray())
|
||||
keyStore.save(tmpKeyStore, "keystorepass")
|
||||
|
||||
// Load the keystore from file and make sure keys are intact.
|
||||
@ -120,7 +119,7 @@ class X509UtilitiesTest {
|
||||
val converter = JcaX509CertificateConverter()
|
||||
val keyStore = KeyStoreUtilities.loadOrCreateKeyStore(tmpKeyStore, "keystorepass")
|
||||
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")
|
||||
|
||||
// Load the keystore from file and make sure keys are intact.
|
||||
@ -360,7 +359,7 @@ class X509UtilitiesTest {
|
||||
keyStore.addOrReplaceKey(X509Utilities.CORDA_INTERMEDIATE_CA,
|
||||
intermediateCAKeyPair.private,
|
||||
keyPass,
|
||||
listOf(intermediateCACert, rootCACert).mapToArray<X509CertificateHolder, Certificate>(converter::getCertificate))
|
||||
Stream.of(intermediateCACert, rootCACert).map(converter::getCertificate).toTypedArray<Certificate>())
|
||||
|
||||
keyStore.save(keyStoreFilePath, storePassword)
|
||||
|
||||
|
@ -5,7 +5,7 @@ import com.nhaarman.mockito_kotlin.eq
|
||||
import com.nhaarman.mockito_kotlin.mock
|
||||
import net.corda.core.crypto.*
|
||||
import net.corda.core.exists
|
||||
import net.corda.core.mapToArray
|
||||
import net.corda.core.toTypedArray
|
||||
import net.corda.core.utilities.ALICE
|
||||
import net.corda.testing.TestNodeConfiguration
|
||||
import net.corda.testing.getTestX509Name
|
||||
@ -32,8 +32,8 @@ class NetworkRegistrationHelperTest {
|
||||
"CORDA_ROOT_CA")
|
||||
.map { getTestX509Name(it) }
|
||||
val converter = JcaX509CertificateConverter()
|
||||
val certs = identities.map { X509Utilities.createSelfSignedCACertificate(it, Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)) }
|
||||
.mapToArray(converter::getCertificate)
|
||||
val certs = identities.stream().map { X509Utilities.createSelfSignedCACertificate(it, Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME)) }
|
||||
.map(converter::getCertificate).toTypedArray()
|
||||
|
||||
val certService: NetworkRegistrationService = mock {
|
||||
on { submitRequest(any()) }.then { id }
|
||||
|
@ -13,13 +13,14 @@ import net.corda.node.utilities.ServiceIdentityGenerator
|
||||
import net.corda.cordform.CordformDefinition
|
||||
import net.corda.cordform.CordformContext
|
||||
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 org.bouncycastle.asn1.x500.X500Name
|
||||
|
||||
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)
|
||||
|
||||
object BFTNotaryCordform : CordformDefinition("build" / "notary-demo-nodes", notaryNames[0]) {
|
||||
@ -38,7 +39,7 @@ object BFTNotaryCordform : CordformDefinition("build" / "notary-demo-nodes", not
|
||||
p2pPort(10005)
|
||||
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 {
|
||||
name(notaryNames[replicaId])
|
||||
advertisedServices(advertisedService)
|
||||
|
@ -14,6 +14,7 @@ import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.utilities.BOB
|
||||
import net.corda.notarydemo.flows.DummyIssueAndMove
|
||||
import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient
|
||||
import kotlin.streams.asSequence
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val address = HostAndPort.fromParts("localhost", 10003)
|
||||
@ -28,7 +29,8 @@ private class NotaryDemoClientApi(val rpc: CordaRPCOps) {
|
||||
private val notary by lazy {
|
||||
val (parties, partyUpdates) = rpc.networkMapUpdates()
|
||||
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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user