diff --git a/buildSrc/src/main/groovy/CanonicalizerPlugin.groovy b/buildSrc/src/main/groovy/CanonicalizerPlugin.groovy index 6b6b87b483..85034e7bbd 100644 --- a/buildSrc/src/main/groovy/CanonicalizerPlugin.groovy +++ b/buildSrc/src/main/groovy/CanonicalizerPlugin.groovy @@ -28,7 +28,7 @@ class CanonicalizerPlugin implements Plugin { output.setMethod(ZipOutputStream.DEFLATED) entries.each { - def newEntry = new ZipEntry( it.name ) + def newEntry = new ZipEntry(it.name) newEntry.setLastModifiedTime(zeroTime) newEntry.setCreationTime(zeroTime) diff --git a/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt b/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt index 809dbc45a9..65465e04bb 100644 --- a/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt +++ b/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt @@ -119,12 +119,14 @@ object JacksonSupport { * match an identity known from the network map. If true, the name is matched more leniently but if the match * is ambiguous a [JsonParseException] is thrown. */ - @JvmStatic @JvmOverloads + @JvmStatic + @JvmOverloads fun createDefaultMapper(rpc: CordaRPCOps, factory: JsonFactory = JsonFactory(), fuzzyIdentityMatch: Boolean = false): ObjectMapper = configureMapper(RpcObjectMapper(rpc, factory, fuzzyIdentityMatch)) /** For testing or situations where deserialising parties is not required */ - @JvmStatic @JvmOverloads + @JvmStatic + @JvmOverloads fun createNonRpcMapper(factory: JsonFactory = JsonFactory()): ObjectMapper = configureMapper(NoPartyObjectMapper(factory)) /** @@ -134,7 +136,8 @@ object JacksonSupport { * match an identity known from the network map. If true, the name is matched more leniently but if the match * is ambiguous a [JsonParseException] is thrown. */ - @JvmStatic @JvmOverloads + @JvmStatic + @JvmOverloads fun createInMemoryMapper(identityService: IdentityService, factory: JsonFactory = JsonFactory(), fuzzyIdentityMatch: Boolean = false) = configureMapper(IdentityObjectMapper(identityService, factory, fuzzyIdentityMatch)) @@ -227,7 +230,7 @@ object JacksonSupport { return try { CordaX500Name.parse(parser.text) - } catch(ex: IllegalArgumentException) { + } catch (ex: IllegalArgumentException) { throw JsonParseException(parser, "Invalid Corda X.500 name ${parser.text}: ${ex.message}", ex) } } @@ -310,7 +313,7 @@ object JacksonSupport { // Attempt parsing as a currency token. TODO: This needs thought about how to extend to other token types. val currency = Currency.getInstance(token) return Amount(quantity, currency) - } catch(e2: Exception) { + } catch (e2: Exception) { throw JsonParseException(parser, "Invalid amount ${parser.text}", e2) } } diff --git a/client/jackson/src/main/kotlin/net/corda/client/jackson/StringToMethodCallParser.kt b/client/jackson/src/main/kotlin/net/corda/client/jackson/StringToMethodCallParser.kt index a49409eca2..a79d14f591 100644 --- a/client/jackson/src/main/kotlin/net/corda/client/jackson/StringToMethodCallParser.kt +++ b/client/jackson/src/main/kotlin/net/corda/client/jackson/StringToMethodCallParser.kt @@ -100,7 +100,7 @@ open class StringToMethodCallParser @JvmOverloads constructor( val methodParamNames: Map> = targetType.declaredMethods.mapNotNull { try { it.name to paramNamesFromMethod(it) - } catch(e: KotlinReflectionInternalError) { + } catch (e: KotlinReflectionInternalError) { // Kotlin reflection doesn't support every method that can exist on an object (in particular, reified // inline methods) so we just ignore those here. null @@ -175,7 +175,7 @@ open class StringToMethodCallParser @JvmOverloads constructor( try { val args = parseArguments(name, paramNamesFromMethod(method).zip(method.parameterTypes), argStr) return ParsedMethodCall(target, method, args) - } catch(e: UnparseableCallException) { + } catch (e: UnparseableCallException) { if (index == methods.size - 1) throw e } @@ -198,7 +198,7 @@ open class StringToMethodCallParser @JvmOverloads constructor( val entry = tree[argName] ?: throw UnparseableCallException.MissingParameter(methodNameHint, argName, args) try { om.readValue(entry.traverse(om), argType) - } catch(e: Exception) { + } catch (e: Exception) { throw UnparseableCallException.FailedParse(e) } } @@ -212,16 +212,17 @@ open class StringToMethodCallParser @JvmOverloads constructor( } /** Returns a string-to-string map of commands to a string describing available parameter types. */ - val availableCommands: Map get() { - return methodMap.entries().map { entry -> - val (name, args) = entry // TODO: Kotlin 1.1 - val argStr = if (args.parameterCount == 0) "" else { - val paramNames = methodParamNames[name]!! - val typeNames = args.parameters.map { it.type.simpleName } - val paramTypes = paramNames.zip(typeNames) - paramTypes.map { "${it.first}: ${it.second}" }.joinToString(", ") - } - Pair(name, argStr) - }.toMap() - } + val availableCommands: Map + get() { + return methodMap.entries().map { entry -> + val (name, args) = entry // TODO: Kotlin 1.1 + val argStr = if (args.parameterCount == 0) "" else { + val paramNames = methodParamNames[name]!! + val typeNames = args.parameters.map { it.type.simpleName } + val paramTypes = paramNames.zip(typeNames) + paramTypes.map { "${it.first}: ${it.second}" }.joinToString(", ") + } + Pair(name, argStr) + }.toMap() + } } diff --git a/client/jackson/src/test/kotlin/net/corda/client/jackson/JacksonSupportTest.kt b/client/jackson/src/test/kotlin/net/corda/client/jackson/JacksonSupportTest.kt index 6f057b2ff5..d8595e6bd9 100644 --- a/client/jackson/src/test/kotlin/net/corda/client/jackson/JacksonSupportTest.kt +++ b/client/jackson/src/test/kotlin/net/corda/client/jackson/JacksonSupportTest.kt @@ -92,10 +92,10 @@ class JacksonSupportTest : TestDependencyInjectionBase() { fun writeTransaction() { val attachmentRef = SecureHash.randomSHA256() whenever(cordappProvider.getContractAttachmentID(DummyContract.PROGRAM_ID)) - .thenReturn(attachmentRef) + .thenReturn(attachmentRef) fun makeDummyTx(): SignedTransaction { val wtx = DummyContract.generateInitial(1, DUMMY_NOTARY, MINI_CORP.ref(1)) - .toWireTransaction(services) + .toWireTransaction(services) val signatures = TransactionSignature( ByteArray(1), ALICE_PUBKEY, diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/ModelsUtils.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/ModelsUtils.kt index 836e046887..868849d56b 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/ModelsUtils.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/ModelsUtils.kt @@ -1,4 +1,5 @@ @file:JvmName("ModelsUtils") + package net.corda.client.jfx.model import javafx.beans.property.ObjectProperty diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt index 9ff83660aa..2213d40bbc 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt @@ -38,7 +38,7 @@ class NetworkIdentityModel { }) val notaries: ObservableList = networkIdentities.map { - it.legalIdentitiesAndCerts.find { it.name.commonName?.let { ServiceType.parse(it).isNotary() } ?: false } + it.legalIdentitiesAndCerts.find { it.name.commonName?.let { ServiceType.parse(it).isNotary() } == true } }.map { it?.party }.filterNotNull() val notaryNodes: ObservableList = notaries.map { rpcProxy.value?.nodeInfoFromParty(it) }.filterNotNull() diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt index 9a4da742b0..0b866332f9 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt @@ -57,8 +57,8 @@ class NodeMonitorModel { */ fun register(nodeHostAndPort: NetworkHostAndPort, username: String, password: String) { val client = CordaRPCClient( - nodeHostAndPort, - CordaRPCClientConfiguration.DEFAULT.copy( + nodeHostAndPort, + CordaRPCClientConfiguration.DEFAULT.copy( connectionMaxRetryInterval = 10.seconds ) ) diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ConcatenatedList.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ConcatenatedList.kt index 9b8a5f45e5..58b602b834 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ConcatenatedList.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ConcatenatedList.kt @@ -253,14 +253,15 @@ class ConcatenatedList(sourceList: ObservableList>) : Trans } } - override val size: Int get() { - recalculateOffsets() - if (nestedIndexOffsets.size > 0) { - return nestedIndexOffsets.last() - } else { - return 0 + override val size: Int + get() { + recalculateOffsets() + if (nestedIndexOffsets.size > 0) { + return nestedIndexOffsets.last() + } else { + return 0 + } } - } override fun getSourceIndex(index: Int): Int { throw UnsupportedOperationException("Source index not supported in concatenation") diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableFold.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableFold.kt index 17c68ac20f..76c75c38de 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableFold.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableFold.kt @@ -1,4 +1,5 @@ @file:JvmName("ObservableFold") + package net.corda.client.jfx.utils import javafx.application.Platform diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableUtilities.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableUtilities.kt index 89366935fa..a863af5ade 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableUtilities.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableUtilities.kt @@ -1,4 +1,5 @@ @file:JvmName("ObservableUtilities") + package net.corda.client.jfx.utils import javafx.application.Platform diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ReadOnlyBackedObservableMapBase.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ReadOnlyBackedObservableMapBase.kt index a751e3ac99..4ee03afc56 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ReadOnlyBackedObservableMapBase.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ReadOnlyBackedObservableMapBase.kt @@ -50,18 +50,19 @@ open class ReadOnlyBackedObservableMapBase : ObservableMap { override fun isEmpty() = backingMap.isEmpty() - override val entries: MutableSet> get() = backingMap.entries.fold(mutableSetOf()) { set, entry -> - set.add(object : MutableMap.MutableEntry { - override var value: A = entry.value.first - override val key = entry.key - override fun setValue(newValue: A): A { - val old = value - value = newValue - return old - } - }) - set - } + override val entries: MutableSet> + get() = backingMap.entries.fold(mutableSetOf()) { set, entry -> + set.add(object : MutableMap.MutableEntry { + override var value: A = entry.value.first + override val key = entry.key + override fun setValue(newValue: A): A { + val old = value + value = newValue + return old + } + }) + set + } override val keys: MutableSet get() = backingMap.keys override val values: MutableCollection get() = ArrayList(backingMap.values.map { it.first }) diff --git a/client/mock/src/main/kotlin/net/corda/client/mock/EventGenerator.kt b/client/mock/src/main/kotlin/net/corda/client/mock/EventGenerator.kt index 1955dff5d2..28e938c843 100644 --- a/client/mock/src/main/kotlin/net/corda/client/mock/EventGenerator.kt +++ b/client/mock/src/main/kotlin/net/corda/client/mock/EventGenerator.kt @@ -50,7 +50,7 @@ open class EventGenerator(val parties: List, val currencies: List, currencies: List, notary: Party): EventGenerator(parties, currencies, notary) { +class ErrorFlowsEventGenerator(parties: List, currencies: List, notary: Party) : EventGenerator(parties, currencies, notary) { enum class IssuerEvents { NORMAL_EXIT, EXIT_ERROR @@ -62,7 +62,7 @@ class ErrorFlowsEventGenerator(parties: List, currencies: List, when (errorType) { IssuerEvents.NORMAL_EXIT -> { println("Normal exit") - if (currencyMap[ccy]!! <= amount) addToMap(ccy, -amount) + if (currencyMap[ccy]!! <= amount) addToMap(ccy, -amount) ExitRequest(Amount(amount, ccy), issueRef) // It may fail at the beginning, but we don't care. } IssuerEvents.EXIT_ERROR -> { diff --git a/client/mock/src/main/kotlin/net/corda/client/mock/Generators.kt b/client/mock/src/main/kotlin/net/corda/client/mock/Generators.kt index dc1315b175..ffd110fbeb 100644 --- a/client/mock/src/main/kotlin/net/corda/client/mock/Generators.kt +++ b/client/mock/src/main/kotlin/net/corda/client/mock/Generators.kt @@ -1,4 +1,5 @@ @file:JvmName("Generators") + package net.corda.client.mock import net.corda.core.contracts.Amount diff --git a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/RPCStabilityTests.kt b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/RPCStabilityTests.kt index 2e83e1f08a..7ccf1913d5 100644 --- a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/RPCStabilityTests.kt +++ b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/RPCStabilityTests.kt @@ -76,10 +76,12 @@ class RPCStabilityTests { rpcDriver { Try.on { startRpcClient(NetworkHostAndPort("localhost", 9999)).get() } val server = startRpcServer(ops = DummyOps) - Try.on { startRpcClient( - server.get().broker.hostAndPort!!, - configuration = RPCClientConfiguration.default.copy(minimumServerProtocolVersion = 1) - ).get() } + Try.on { + startRpcClient( + server.get().broker.hostAndPort!!, + configuration = RPCClientConfiguration.default.copy(minimumServerProtocolVersion = 1) + ).get() + } } } repeat(5) { @@ -173,7 +175,7 @@ class RPCStabilityTests { } } - interface LeakObservableOps: RPCOps { + interface LeakObservableOps : RPCOps { fun leakObservable(): Observable } @@ -249,6 +251,7 @@ class RPCStabilityTests { val trackSubscriberCountObservable = UnicastSubject.create().share(). doOnSubscribe { subscriberCount.incrementAndGet() }. doOnUnsubscribe { subscriberCount.decrementAndGet() } + override fun subscribe(): Observable { return trackSubscriberCountObservable } @@ -261,7 +264,7 @@ class RPCStabilityTests { ).get() val numberOfClients = 4 - val clients = (1 .. numberOfClients).map { + val clients = (1..numberOfClients).map { startRandomRpcClient(server.broker.hostAndPort!!) }.transpose().get() @@ -272,7 +275,7 @@ class RPCStabilityTests { clients[0].destroyForcibly() pollUntilClientNumber(server, numberOfClients - 1) // Kill the rest - (1 .. numberOfClients - 1).forEach { + (1..numberOfClients - 1).forEach { clients[it].destroyForcibly() } pollUntilClientNumber(server, 0) @@ -284,6 +287,7 @@ class RPCStabilityTests { interface SlowConsumerRPCOps : RPCOps { fun streamAtInterval(interval: Duration, size: Int): Observable } + class SlowConsumerRPCOpsImpl : SlowConsumerRPCOps { override val protocolVersion = 0 @@ -292,6 +296,7 @@ class RPCStabilityTests { return Observable.interval(interval.toMillis(), TimeUnit.MILLISECONDS).map { chunk } } } + @Test fun `slow consumers are kicked`() { rpcDriver { diff --git a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt index a777a0c96a..0a89aecc92 100644 --- a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt +++ b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt @@ -79,6 +79,7 @@ class RPCClientProxyHandler( STARTED, FINISHED } + private val lifeCycle = LifeCycle(State.UNSTARTED) private companion object { diff --git a/client/rpc/src/smoke-test/java/net/corda/java/rpc/StandaloneCordaRPCJavaClientTest.java b/client/rpc/src/smoke-test/java/net/corda/java/rpc/StandaloneCordaRPCJavaClientTest.java index e9ebce530f..70ae26e1b6 100644 --- a/client/rpc/src/smoke-test/java/net/corda/java/rpc/StandaloneCordaRPCJavaClientTest.java +++ b/client/rpc/src/smoke-test/java/net/corda/java/rpc/StandaloneCordaRPCJavaClientTest.java @@ -67,7 +67,7 @@ public class StandaloneCordaRPCJavaClientTest { try { connection.close(); } finally { - if(notary != null) { + if (notary != null) { notary.close(); } } diff --git a/client/rpc/src/smoke-test/kotlin/net/corda/kotlin/rpc/StandaloneCordaRPClientTest.kt b/client/rpc/src/smoke-test/kotlin/net/corda/kotlin/rpc/StandaloneCordaRPClientTest.kt index 40ae8c5f16..1d487f762b 100644 --- a/client/rpc/src/smoke-test/kotlin/net/corda/kotlin/rpc/StandaloneCordaRPClientTest.kt +++ b/client/rpc/src/smoke-test/kotlin/net/corda/kotlin/rpc/StandaloneCordaRPClientTest.kt @@ -114,14 +114,14 @@ class StandaloneCordaRPClientTest { @Test fun `test starting flow`() { rpcProxy.startFlow(::CashIssueFlow, 127.POUNDS, OpaqueBytes.of(0), notaryNodeIdentity) - .returnValue.getOrThrow(timeout) + .returnValue.getOrThrow(timeout) } @Test fun `test starting tracked flow`() { var trackCount = 0 val handle = rpcProxy.startTrackedFlow( - ::CashIssueFlow, 429.DOLLARS, OpaqueBytes.of(0), notaryNodeIdentity + ::CashIssueFlow, 429.DOLLARS, OpaqueBytes.of(0), notaryNodeIdentity ) val updateLatch = CountDownLatch(1) handle.progress.subscribe { msg -> @@ -156,7 +156,7 @@ class StandaloneCordaRPClientTest { // Now issue some cash rpcProxy.startFlow(::CashIssueFlow, 513.SWISS_FRANCS, OpaqueBytes.of(0), notaryNodeIdentity) - .returnValue.getOrThrow(timeout) + .returnValue.getOrThrow(timeout) updateLatch.await() assertEquals(1, updateCount.get()) } diff --git a/client/rpc/src/test/kotlin/net/corda/client/rpc/AbstractRPCTest.kt b/client/rpc/src/test/kotlin/net/corda/client/rpc/AbstractRPCTest.kt index c6b5329d8c..35eaa9dfd8 100644 --- a/client/rpc/src/test/kotlin/net/corda/client/rpc/AbstractRPCTest.kt +++ b/client/rpc/src/test/kotlin/net/corda/client/rpc/AbstractRPCTest.kt @@ -20,10 +20,13 @@ open class AbstractRPCTest { } companion object { - @JvmStatic @Parameterized.Parameters(name = "Mode = {0}") + @JvmStatic + @Parameterized.Parameters(name = "Mode = {0}") fun defaultModes() = modes(RPCTestMode.InVm, RPCTestMode.Netty) + fun modes(vararg modes: RPCTestMode) = listOf(*modes).map { arrayOf(it) } } + @Parameterized.Parameter lateinit var mode: RPCTestMode diff --git a/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPerformanceTests.kt b/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPerformanceTests.kt index b9d64a3cab..2923040034 100644 --- a/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPerformanceTests.kt +++ b/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPerformanceTests.kt @@ -26,9 +26,11 @@ import java.util.concurrent.TimeUnit @RunWith(Parameterized::class) class RPCPerformanceTests : AbstractRPCTest() { companion object { - @JvmStatic @Parameterized.Parameters(name = "Mode = {0}") + @JvmStatic + @Parameterized.Parameters(name = "Mode = {0}") fun modes() = modes(RPCTestMode.Netty) } + private interface TestOps : RPCOps { fun simpleReply(input: ByteArray, sizeOfReply: Int): ByteArray } @@ -60,7 +62,7 @@ class RPCPerformanceTests : AbstractRPCTest() { val executor = Executors.newFixedThreadPool(4) val N = 10000 val latch = CountDownLatch(N) - for (i in 1 .. N) { + for (i in 1..N) { executor.submit { proxy.ops.simpleReply(ByteArray(1024), 1024) latch.countDown() @@ -155,10 +157,12 @@ class RPCPerformanceTests : AbstractRPCTest() { data class BigMessagesResult( val Mbps: Double ) + @Test fun `big messages`() { warmup() - measure(listOf(1)) { clientParallelism -> // TODO this hangs with more parallelism + measure(listOf(1)) { clientParallelism -> + // TODO this hangs with more parallelism rpcDriver { val proxy = testProxy( RPCClientConfiguration.default, diff --git a/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPermissionsTests.kt b/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPermissionsTests.kt index 4411bbfd07..cee75881aa 100644 --- a/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPermissionsTests.kt +++ b/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPermissionsTests.kt @@ -79,7 +79,7 @@ class RPCPermissionsTests : AbstractRPCTest() { } @Test - fun `check ALL is implemented the correct way round` () { + fun `check ALL is implemented the correct way round`() { rpcDriver { val joeUser = userOf("joe", setOf(DUMMY_FLOW)) val proxy = testProxyFor(joeUser) diff --git a/client/rpc/src/test/kotlin/net/corda/client/rpc/RepeatingBytesInputStream.kt b/client/rpc/src/test/kotlin/net/corda/client/rpc/RepeatingBytesInputStream.kt index 8887aa2476..b22ed8b506 100644 --- a/client/rpc/src/test/kotlin/net/corda/client/rpc/RepeatingBytesInputStream.kt +++ b/client/rpc/src/test/kotlin/net/corda/client/rpc/RepeatingBytesInputStream.kt @@ -13,6 +13,7 @@ class RepeatingBytesInputStream(val bytesToRepeat: ByteArray, val numberOfBytes: return bytesToRepeat[(numberOfBytes - bytesLeft) % bytesToRepeat.size].toInt() } } + override fun read(byteArray: ByteArray, offset: Int, length: Int): Int { val lastIdx = Math.min(Math.min(offset + length, byteArray.size), offset + bytesLeft) for (i in offset until lastIdx) { diff --git a/core/src/main/kotlin/net/corda/core/concurrent/ConcurrencyUtils.kt b/core/src/main/kotlin/net/corda/core/concurrent/ConcurrencyUtils.kt index dedc468904..f86ca21fce 100644 --- a/core/src/main/kotlin/net/corda/core/concurrent/ConcurrencyUtils.kt +++ b/core/src/main/kotlin/net/corda/core/concurrent/ConcurrencyUtils.kt @@ -1,4 +1,5 @@ @file:JvmName("ConcurrencyUtils") + package net.corda.core.concurrent import net.corda.core.internal.concurrent.openFuture diff --git a/core/src/main/kotlin/net/corda/core/contracts/Amount.kt b/core/src/main/kotlin/net/corda/core/contracts/Amount.kt index 64849d3430..629461a3d7 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/Amount.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/Amount.kt @@ -167,7 +167,7 @@ data class Amount(val quantity: Long, val displayTokenSize: BigDecimal, } } } - } catch(e: Exception) { + } catch (e: Exception) { throw IllegalArgumentException("Could not parse $input as a currency", e) } throw IllegalArgumentException("Did not recognise the currency in $input or could not parse") diff --git a/core/src/main/kotlin/net/corda/core/contracts/ContractsDSL.kt b/core/src/main/kotlin/net/corda/core/contracts/ContractsDSL.kt index d43ae5c001..82a1d348a0 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/ContractsDSL.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/ContractsDSL.kt @@ -34,7 +34,7 @@ inline fun requireThat(body: Requirements.() -> R) = Requirements.body() /** Filters the command list by type, party and public key all at once. */ inline fun Collection>.select(signer: PublicKey? = null, - party: AbstractParty? = null) = + party: AbstractParty? = null) = filter { it.value is T }. filter { if (signer == null) true else signer in it.signers }. filter { if (party == null) true else party in it.signingParties }. @@ -44,7 +44,7 @@ inline fun Collection> /** Filters the command list by type, parties and public keys all at once. */ inline fun Collection>.select(signers: Collection?, - parties: Collection?) = + parties: Collection?) = filter { it.value is T }. filter { if (signers == null) true else it.signers.containsAll(signers) }. filter { if (parties == null) true else it.signingParties.containsAll(parties) }. diff --git a/core/src/main/kotlin/net/corda/core/contracts/TimeWindow.kt b/core/src/main/kotlin/net/corda/core/contracts/TimeWindow.kt index e26ea50cd0..c8c650257d 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/TimeWindow.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/TimeWindow.kt @@ -85,6 +85,7 @@ abstract class TimeWindow { init { require(fromTime < untilTime) { "fromTime must be earlier than untilTime" } } + override val midpoint: Instant get() = fromTime + (fromTime until untilTime) / 2 override fun contains(instant: Instant): Boolean = instant >= fromTime && instant < untilTime override fun toString(): String = "[$fromTime, $untilTime)" diff --git a/core/src/main/kotlin/net/corda/core/crypto/CordaSecurityProvider.kt b/core/src/main/kotlin/net/corda/core/crypto/CordaSecurityProvider.kt index eaae5e2ffb..b9bdd52afb 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/CordaSecurityProvider.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/CordaSecurityProvider.kt @@ -31,6 +31,8 @@ class CordaSecurityProvider : Provider(PROVIDER_NAME, 0.1, "$PROVIDER_NAME secur object CordaObjectIdentifier { // UUID-based OID // TODO: Register for an OID space and issue our own shorter OID. - @JvmField val COMPOSITE_KEY = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791002") - @JvmField val COMPOSITE_SIGNATURE = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791003") + @JvmField + val COMPOSITE_KEY = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791002") + @JvmField + val COMPOSITE_SIGNATURE = ASN1ObjectIdentifier("2.25.30086077608615255153862931087626791003") } diff --git a/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt b/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt index b6df5e2bc9..58b68bb176 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt @@ -774,9 +774,10 @@ object Crypto { // it forms, by itself, the new private key, which in turn is used to compute the new public key. val pointQ = FixedPointCombMultiplier().multiply(parameterSpec.g, deterministicD) // This is unlikely to happen, but we should check for point at infinity. - if (pointQ.isInfinity) + if (pointQ.isInfinity) { // Instead of throwing an exception, we retry with SHA256(seed). return deriveKeyPairECDSA(parameterSpec, privateKey, seed.sha256().bytes) + } val publicKeySpec = ECPublicKeySpec(pointQ, parameterSpec) val publicKeyD = BCECPublicKey(privateKey.algorithm, publicKeySpec, BouncyCastleProvider.CONFIGURATION) @@ -849,6 +850,7 @@ object Crypto { override fun generatePublic(keyInfo: SubjectPublicKeyInfo?): PublicKey? { return keyInfo?.let { decodePublicKey(signatureScheme, it.encoded) } } + override fun generatePrivate(keyInfo: PrivateKeyInfo?): PrivateKey? { return keyInfo?.let { decodePrivateKey(signatureScheme, it.encoded) } } diff --git a/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt b/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt index 2dffd5afda..32b14cffcd 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt @@ -35,6 +35,7 @@ fun PrivateKey.sign(bytesToSign: ByteArray, publicKey: PublicKey) = DigitalSigna */ @Throws(IllegalArgumentException::class, InvalidKeyException::class, SignatureException::class) fun KeyPair.sign(bytesToSign: ByteArray) = private.sign(bytesToSign, public) + fun KeyPair.sign(bytesToSign: OpaqueBytes) = sign(bytesToSign.bytes) /** * Helper function for signing a [SignableData] object. @@ -72,18 +73,18 @@ fun PublicKey.verify(content: ByteArray, signature: DigitalSignature) = Crypto.d * @return whether the signature is correct for this key. */ @Throws(IllegalStateException::class, SignatureException::class, IllegalArgumentException::class) -fun PublicKey.isValid(content: ByteArray, signature: DigitalSignature) : Boolean { +fun PublicKey.isValid(content: ByteArray, signature: DigitalSignature): Boolean { if (this is CompositeKey) throw IllegalStateException("Verification of CompositeKey signatures currently not supported.") // TODO CompositeSignature verification. return Crypto.isValid(this, signature.bytes, content) } /** Render a public key to its hash (in Base58) of its serialised form using the DL prefix. */ -fun PublicKey.toStringShort(): String = "DL" + this.toSHA256Bytes().toBase58() +fun PublicKey.toStringShort(): String = "DL" + this.toSHA256Bytes().toBase58() val PublicKey.keys: Set get() = (this as? CompositeKey)?.leafKeys ?: setOf(this) -fun PublicKey.isFulfilledBy(otherKey: PublicKey): Boolean = isFulfilledBy(setOf(otherKey)) +fun PublicKey.isFulfilledBy(otherKey: PublicKey): Boolean = isFulfilledBy(setOf(otherKey)) fun PublicKey.isFulfilledBy(otherKeys: Iterable): Boolean = (this as? CompositeKey)?.isFulfilledBy(otherKeys) ?: (this in otherKeys) /** Checks whether any of the given [keys] matches a leaf on the [CompositeKey] tree or a single [PublicKey]. */ diff --git a/core/src/main/kotlin/net/corda/core/crypto/DigitalSignature.kt b/core/src/main/kotlin/net/corda/core/crypto/DigitalSignature.kt index 9e28be8a3a..d343913712 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/DigitalSignature.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/DigitalSignature.kt @@ -23,6 +23,7 @@ open class DigitalSignature(bytes: ByteArray) : OpaqueBytes(bytes) { */ @Throws(InvalidKeyException::class, SignatureException::class) fun verify(content: ByteArray) = by.verify(content, this) + /** * Utility to simplify the act of verifying a signature. * @@ -32,6 +33,7 @@ open class DigitalSignature(bytes: ByteArray) : OpaqueBytes(bytes) { */ @Throws(InvalidKeyException::class, SignatureException::class) fun verify(content: OpaqueBytes) = by.verify(content.bytes, this) + /** * Utility to simplify the act of verifying a signature. In comparison to [verify] doesn't throw an * exception, making it more suitable where a boolean is required, but normally you should use the function diff --git a/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt b/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt index f0773a7bac..16bf533550 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt @@ -34,11 +34,18 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) { } } - @JvmStatic fun sha256(bytes: ByteArray) = SHA256(MessageDigest.getInstance("SHA-256").digest(bytes)) - @JvmStatic fun sha256Twice(bytes: ByteArray) = sha256(sha256(bytes).bytes) - @JvmStatic fun sha256(str: String) = sha256(str.toByteArray()) + @JvmStatic + fun sha256(bytes: ByteArray) = SHA256(MessageDigest.getInstance("SHA-256").digest(bytes)) + + @JvmStatic + fun sha256Twice(bytes: ByteArray) = sha256(sha256(bytes).bytes) + + @JvmStatic + fun sha256(str: String) = sha256(str.toByteArray()) + + @JvmStatic + fun randomSHA256() = sha256(newSecureRandom().generateSeed(32)) - @JvmStatic fun randomSHA256() = sha256(newSecureRandom().generateSeed(32)) val zeroHash = SecureHash.SHA256(ByteArray(32, { 0.toByte() })) val allOnesHash = SecureHash.SHA256(ByteArray(32, { 255.toByte() })) } diff --git a/core/src/main/kotlin/net/corda/core/crypto/TransactionSignature.kt b/core/src/main/kotlin/net/corda/core/crypto/TransactionSignature.kt index 28e843a82d..4f5f7eb207 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/TransactionSignature.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/TransactionSignature.kt @@ -11,7 +11,7 @@ import java.util.* * This is similar to [DigitalSignature.WithKey], but targeted to DLT transaction signatures. */ @CordaSerializable -class TransactionSignature(bytes: ByteArray, val by: PublicKey, val signatureMetadata: SignatureMetadata): DigitalSignature(bytes) { +class TransactionSignature(bytes: ByteArray, val by: PublicKey, val signatureMetadata: SignatureMetadata) : DigitalSignature(bytes) { /** * Function to verify a [SignableData] object's signature. * Note that [SignableData] contains the id of the transaction and extra metadata, such as DLT's platform version. diff --git a/core/src/main/kotlin/net/corda/core/flows/AbstractStateReplacementFlow.kt b/core/src/main/kotlin/net/corda/core/flows/AbstractStateReplacementFlow.kt index bcc712df71..82a960cfc7 100644 --- a/core/src/main/kotlin/net/corda/core/flows/AbstractStateReplacementFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/AbstractStateReplacementFlow.kt @@ -136,7 +136,8 @@ abstract class AbstractStateReplacementFlow { // We use Void? instead of Unit? as that's what you'd use in Java. abstract class Acceptor(val initiatingSession: FlowSession, override val progressTracker: ProgressTracker = Acceptor.tracker()) : FlowLogic() { - constructor(initiatingSession: FlowSession) : this(initiatingSession, Acceptor.tracker()) + constructor(initiatingSession: FlowSession) : this(initiatingSession, Acceptor.tracker()) + companion object { object VERIFYING : ProgressTracker.Step("Verifying state replacement proposal") object APPROVING : ProgressTracker.Step("State replacement approved") diff --git a/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt b/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt index cfb232a7ec..8dfe4a69ff 100644 --- a/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt @@ -61,11 +61,12 @@ import java.security.PublicKey * just in the states. If null, the default well known identity of the node is used. */ // TODO: AbstractStateReplacementFlow needs updating to use this flow. -class CollectSignaturesFlow @JvmOverloads constructor (val partiallySignedTx: SignedTransaction, - val sessionsToCollectFrom: Collection, - val myOptionalKeys: Iterable?, - override val progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : FlowLogic() { +class CollectSignaturesFlow @JvmOverloads constructor(val partiallySignedTx: SignedTransaction, + val sessionsToCollectFrom: Collection, + val myOptionalKeys: Iterable?, + override val progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : FlowLogic() { @JvmOverloads constructor(partiallySignedTx: SignedTransaction, sessionsToCollectFrom: Collection, progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : this(partiallySignedTx, sessionsToCollectFrom, null, progressTracker) + companion object { object COLLECTING : ProgressTracker.Step("Collecting signatures from counter-parties.") object VERIFYING : ProgressTracker.Step("Verifying collected signatures.") @@ -134,6 +135,7 @@ class CollectSignaturesFlow @JvmOverloads constructor (val partiallySignedTx: Si class CollectSignatureFlow(val partiallySignedTx: SignedTransaction, val session: FlowSession, val signingKeys: List) : FlowLogic>() { constructor(partiallySignedTx: SignedTransaction, session: FlowSession, vararg signingKeys: PublicKey) : this(partiallySignedTx, session, listOf(*signingKeys)) + @Suspendable override fun call(): List { // SendTransactionFlow allows counterparty to access our data to resolve the transaction. @@ -224,7 +226,7 @@ abstract class SignTransactionFlow(val otherSideSession: FlowSession, // Perform some custom verification over the transaction. try { checkTransaction(stx) - } catch(e: Exception) { + } catch (e: Exception) { if (e is IllegalStateException || e is IllegalArgumentException || e is AssertionError) throw FlowException(e) else diff --git a/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt b/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt index d1217909da..423b6c1fa6 100644 --- a/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt @@ -28,7 +28,7 @@ object ContractUpgradeFlow { val stateAndRef: StateAndRef<*>, private val upgradedContractClass: Class> ) : FlowLogic() { - // DOCEND 1 + // DOCEND 1 @Suspendable override fun call(): Void? { val upgrade = upgradedContractClass.newInstance() @@ -50,7 +50,7 @@ object ContractUpgradeFlow { class Deauthorise(val stateRef: StateRef) : FlowLogic() { @Suspendable override fun call(): Void? { - //DOCEND 2 + //DOCEND 2 serviceHub.contractUpgradeService.removeAuthorisedContractUpgrade(stateRef) return null } diff --git a/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt b/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt index 7b45eb6a73..a08654acb9 100644 --- a/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt @@ -26,8 +26,8 @@ import net.corda.core.utilities.ProgressTracker */ @InitiatingFlow class FinalityFlow(val transaction: SignedTransaction, - private val extraRecipients: Set, - override val progressTracker: ProgressTracker) : FlowLogic() { + private val extraRecipients: Set, + override val progressTracker: ProgressTracker) : FlowLogic() { constructor(transaction: SignedTransaction, extraParticipants: Set) : this(transaction, extraParticipants, tracker()) constructor(transaction: SignedTransaction) : this(transaction, emptySet(), tracker()) constructor(transaction: SignedTransaction, progressTracker: ProgressTracker) : this(transaction, emptySet(), progressTracker) @@ -88,7 +88,7 @@ class FinalityFlow(val transaction: SignedTransaction, private fun hasNoNotarySignature(stx: SignedTransaction): Boolean { val notaryKey = stx.tx.notary?.owningKey val signers = stx.sigs.map { it.by }.toSet() - return !(notaryKey?.isFulfilledBy(signers) ?: false) + return notaryKey?.isFulfilledBy(signers) != true } private fun getPartiesToSend(ltx: LedgerTransaction): Set { diff --git a/core/src/main/kotlin/net/corda/core/flows/FlowInitiator.kt b/core/src/main/kotlin/net/corda/core/flows/FlowInitiator.kt index 549af46dcf..6bc488c162 100644 --- a/core/src/main/kotlin/net/corda/core/flows/FlowInitiator.kt +++ b/core/src/main/kotlin/net/corda/core/flows/FlowInitiator.kt @@ -16,18 +16,22 @@ sealed class FlowInitiator : Principal { data class RPC(val username: String) : FlowInitiator() { override fun getName(): String = username } + /** Started when we get new session initiation request. */ data class Peer(val party: Party) : FlowInitiator() { override fun getName(): String = party.name.toString() } + /** Started by a CordaService. */ data class Service(val serviceClassName: String) : FlowInitiator() { override fun getName(): String = serviceClassName } + /** Started as scheduled activity. */ data class Scheduled(val scheduledState: ScheduledStateRef) : FlowInitiator() { override fun getName(): String = "Scheduler" } + // TODO When proper ssh access enabled, add username/use RPC? object Shell : FlowInitiator() { override fun getName(): String = "Shell User" diff --git a/core/src/main/kotlin/net/corda/core/flows/FlowSession.kt b/core/src/main/kotlin/net/corda/core/flows/FlowSession.kt index 07e4b49d33..f5589f96c4 100644 --- a/core/src/main/kotlin/net/corda/core/flows/FlowSession.kt +++ b/core/src/main/kotlin/net/corda/core/flows/FlowSession.kt @@ -75,6 +75,7 @@ abstract class FlowSession { inline fun sendAndReceive(payload: Any): UntrustworthyData { return sendAndReceive(R::class.java, payload) } + /** * Serializes and queues the given [payload] object for sending to the [counterparty]. Suspends until a response * is received, which must be of the given [receiveType]. Remember that when receiving data from other parties the data @@ -100,6 +101,7 @@ abstract class FlowSession { inline fun receive(): UntrustworthyData { return receive(R::class.java) } + /** * Suspends until [counterparty] sends us a message of type [receiveType]. * diff --git a/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt b/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt index c4d122c649..c59986c61b 100644 --- a/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt @@ -173,5 +173,5 @@ sealed class NotaryError { override fun toString() = cause.toString() } - object WrongNotary: NotaryError() + object WrongNotary : NotaryError() } diff --git a/core/src/main/kotlin/net/corda/core/flows/ReceiveTransactionFlow.kt b/core/src/main/kotlin/net/corda/core/flows/ReceiveTransactionFlow.kt index 35f17c64ea..2e686e8746 100644 --- a/core/src/main/kotlin/net/corda/core/flows/ReceiveTransactionFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/ReceiveTransactionFlow.kt @@ -13,7 +13,7 @@ import java.security.SignatureException * This flow is a combination of [FlowSession.receive], resolve and [SignedTransaction.verify]. This flow will receive the * [SignedTransaction] and perform the resolution back-and-forth required to check the dependencies and download any missing * attachments. The flow will return the [SignedTransaction] after it is resolved and then verified using [SignedTransaction.verify]. - * + * * @param otherSideSession session to the other side which is calling [SendTransactionFlow]. * @param checkSufficientSignatures if true checks all required signatures are present. See [SignedTransaction.verify]. */ diff --git a/core/src/main/kotlin/net/corda/core/identity/AbstractParty.kt b/core/src/main/kotlin/net/corda/core/identity/AbstractParty.kt index 6f6f1a8109..8f03ed640b 100644 --- a/core/src/main/kotlin/net/corda/core/identity/AbstractParty.kt +++ b/core/src/main/kotlin/net/corda/core/identity/AbstractParty.kt @@ -13,6 +13,7 @@ import java.security.PublicKey abstract class AbstractParty(val owningKey: PublicKey) { /** Anonymised parties do not include any detail apart from owning key, so equality is dependent solely on the key */ override fun equals(other: Any?): Boolean = other === this || other is AbstractParty && other.owningKey == owningKey + override fun hashCode(): Int = owningKey.hashCode() abstract fun nameOrNull(): CordaX500Name? diff --git a/core/src/main/kotlin/net/corda/core/identity/CordaX500Name.kt b/core/src/main/kotlin/net/corda/core/identity/CordaX500Name.kt index a563ebb1ca..37e872d562 100644 --- a/core/src/main/kotlin/net/corda/core/identity/CordaX500Name.kt +++ b/core/src/main/kotlin/net/corda/core/identity/CordaX500Name.kt @@ -81,7 +81,7 @@ data class CordaX500Name(val commonName: String?, private val countryCodes: Set = ImmutableSet.copyOf(Locale.getISOCountries()) @JvmStatic - fun build(principal: X500Principal) : CordaX500Name { + fun build(principal: X500Principal): CordaX500Name { val x500Name = X500Name.getInstance(principal.encoded) val attrsMap: Map = x500Name.rdNs .flatMap { it.typesAndValues.asList() } @@ -109,7 +109,7 @@ data class CordaX500Name(val commonName: String?, } @JvmStatic - fun parse(name: String) : CordaX500Name = build(X500Principal(name)) + fun parse(name: String): CordaX500Name = build(X500Principal(name)) } @Transient diff --git a/core/src/main/kotlin/net/corda/core/identity/Party.kt b/core/src/main/kotlin/net/corda/core/identity/Party.kt index 78f36ca543..9316391ae7 100644 --- a/core/src/main/kotlin/net/corda/core/identity/Party.kt +++ b/core/src/main/kotlin/net/corda/core/identity/Party.kt @@ -29,6 +29,7 @@ import java.security.cert.X509Certificate class Party(val name: CordaX500Name, owningKey: PublicKey) : AbstractParty(owningKey) { constructor(certificate: X509Certificate) : this(CordaX500Name.build(certificate.subjectX500Principal), Crypto.toSupportedPublicKey(certificate.publicKey)) + override fun nameOrNull(): CordaX500Name = name fun anonymise(): AnonymousParty = AnonymousParty(owningKey) override fun ref(bytes: OpaqueBytes): PartyAndReference = PartyAndReference(this, bytes) diff --git a/core/src/main/kotlin/net/corda/core/identity/PartyAndCertificate.kt b/core/src/main/kotlin/net/corda/core/identity/PartyAndCertificate.kt index f158138b84..12661d2881 100644 --- a/core/src/main/kotlin/net/corda/core/identity/PartyAndCertificate.kt +++ b/core/src/main/kotlin/net/corda/core/identity/PartyAndCertificate.kt @@ -11,7 +11,9 @@ import java.security.cert.* */ @CordaSerializable class PartyAndCertificate(val certPath: CertPath) { - @Transient val certificate: X509Certificate + @Transient + val certificate: X509Certificate + init { require(certPath.type == "X.509") { "Only X.509 certificates supported" } val certs = certPath.certificates @@ -19,7 +21,8 @@ class PartyAndCertificate(val certPath: CertPath) { certificate = certs[0] as X509Certificate } - @Transient val party: Party = Party(certificate) + @Transient + val party: Party = Party(certificate) val owningKey: PublicKey get() = party.owningKey val name: CordaX500Name get() = party.name diff --git a/core/src/main/kotlin/net/corda/core/internal/Emoji.kt b/core/src/main/kotlin/net/corda/core/internal/Emoji.kt index 7c7e5202f5..eb057cfe30 100644 --- a/core/src/main/kotlin/net/corda/core/internal/Emoji.kt +++ b/core/src/main/kotlin/net/corda/core/internal/Emoji.kt @@ -13,22 +13,38 @@ object Emoji { (System.getenv("TERM_PROGRAM") == "JediTerm" && System.getProperty("java.vendor") == "JetBrains s.r.o") } - @JvmStatic val CODE_SANTA_CLAUS: String = codePointsString(0x1F385) - @JvmStatic val CODE_DIAMOND: String = codePointsString(0x1F537) - @JvmStatic val CODE_BAG_OF_CASH: String = codePointsString(0x1F4B0) - @JvmStatic val CODE_NEWSPAPER: String = codePointsString(0x1F4F0) - @JvmStatic val CODE_RIGHT_ARROW: String = codePointsString(0x27A1, 0xFE0F) - @JvmStatic val CODE_LEFT_ARROW: String = codePointsString(0x2B05, 0xFE0F) - @JvmStatic val CODE_GREEN_TICK: String = codePointsString(0x2705) - @JvmStatic val CODE_PAPERCLIP: String = codePointsString(0x1F4CE) - @JvmStatic val CODE_COOL_GUY: String = codePointsString(0x1F60E) - @JvmStatic val CODE_NO_ENTRY: String = codePointsString(0x1F6AB) - @JvmStatic val CODE_SKULL_AND_CROSSBONES: String = codePointsString(0x2620) - @JvmStatic val CODE_BOOKS: String = codePointsString(0x1F4DA) - @JvmStatic val CODE_SLEEPING_FACE: String = codePointsString(0x1F634) - @JvmStatic val CODE_LIGHTBULB: String = codePointsString(0x1F4A1) - @JvmStatic val CODE_FREE: String = codePointsString(0x1F193) - @JvmStatic val CODE_SOON: String = codePointsString(0x1F51C) + @JvmStatic + val CODE_SANTA_CLAUS: String = codePointsString(0x1F385) + @JvmStatic + val CODE_DIAMOND: String = codePointsString(0x1F537) + @JvmStatic + val CODE_BAG_OF_CASH: String = codePointsString(0x1F4B0) + @JvmStatic + val CODE_NEWSPAPER: String = codePointsString(0x1F4F0) + @JvmStatic + val CODE_RIGHT_ARROW: String = codePointsString(0x27A1, 0xFE0F) + @JvmStatic + val CODE_LEFT_ARROW: String = codePointsString(0x2B05, 0xFE0F) + @JvmStatic + val CODE_GREEN_TICK: String = codePointsString(0x2705) + @JvmStatic + val CODE_PAPERCLIP: String = codePointsString(0x1F4CE) + @JvmStatic + val CODE_COOL_GUY: String = codePointsString(0x1F60E) + @JvmStatic + val CODE_NO_ENTRY: String = codePointsString(0x1F6AB) + @JvmStatic + val CODE_SKULL_AND_CROSSBONES: String = codePointsString(0x2620) + @JvmStatic + val CODE_BOOKS: String = codePointsString(0x1F4DA) + @JvmStatic + val CODE_SLEEPING_FACE: String = codePointsString(0x1F634) + @JvmStatic + val CODE_LIGHTBULB: String = codePointsString(0x1F4A1) + @JvmStatic + val CODE_FREE: String = codePointsString(0x1F193) + @JvmStatic + val CODE_SOON: String = codePointsString(0x1F51C) /** diff --git a/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt b/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt index ccc6cee84c..3996dee1de 100644 --- a/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt +++ b/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt @@ -49,6 +49,7 @@ operator fun Duration.times(multiplicand: Long): Duration = multipliedBy(multipl * separator problems. */ operator fun Path.div(other: String): Path = resolve(other) + operator fun String.div(other: String): Path = Paths.get(this) / other /** @@ -104,6 +105,7 @@ fun Path.copyToDirectory(targetDir: Path, vararg options: CopyOption): Path { Files.copy(this, targetFile, *options) return targetFile } + fun Path.moveTo(target: Path, vararg options: CopyOption): Path = Files.move(this, target, *options) fun Path.isRegularFile(vararg options: LinkOption): Boolean = Files.isRegularFile(this, *options) fun Path.isDirectory(vararg options: LinkOption): Boolean = Files.isDirectory(this, *options) @@ -238,10 +240,13 @@ fun Class.castIfPossible(obj: Any): T? = if (isInstance(obj)) cast(obj) e /** Returns a [DeclaredField] wrapper around the declared (possibly non-public) static field of the receiver [Class]. */ fun Class<*>.staticField(name: String): DeclaredField = DeclaredField(this, name, null) + /** Returns a [DeclaredField] wrapper around the declared (possibly non-public) static field of the receiver [KClass]. */ fun KClass<*>.staticField(name: String): DeclaredField = DeclaredField(java, name, null) + /** @suppress Returns a [DeclaredField] wrapper around the declared (possibly non-public) instance field of the receiver object. */ fun Any.declaredField(name: String): DeclaredField = DeclaredField(javaClass, name, this) + /** * Returns a [DeclaredField] wrapper around the (possibly non-public) instance field of the receiver object, but declared * in its superclass [clazz]. @@ -250,7 +255,7 @@ fun Any.declaredField(name: String): DeclaredField = DeclaredField(javaCl fun Any.declaredField(clazz: KClass<*>, name: String): DeclaredField = DeclaredField(clazz.java, name, this) /** creates a new instance if not a Kotlin object */ -fun KClass.objectOrNewInstance(): T { +fun KClass.objectOrNewInstance(): T { return this.objectInstance ?: this.createInstance() } diff --git a/core/src/main/kotlin/net/corda/core/internal/LazyPool.kt b/core/src/main/kotlin/net/corda/core/internal/LazyPool.kt index 3e4e3a526d..edbb545d20 100644 --- a/core/src/main/kotlin/net/corda/core/internal/LazyPool.kt +++ b/core/src/main/kotlin/net/corda/core/internal/LazyPool.kt @@ -27,6 +27,7 @@ class LazyPool( STARTED, FINISHED } + private val lifeCycle = LifeCycle(State.STARTED) private fun clearIfNeeded(instance: A): A { diff --git a/core/src/main/kotlin/net/corda/core/internal/LazyStickyPool.kt b/core/src/main/kotlin/net/corda/core/internal/LazyStickyPool.kt index 6746989291..5974f97f8e 100644 --- a/core/src/main/kotlin/net/corda/core/internal/LazyStickyPool.kt +++ b/core/src/main/kotlin/net/corda/core/internal/LazyStickyPool.kt @@ -18,6 +18,7 @@ class LazyStickyPool( private class InstanceBox { var instance: LinkedBlockingQueue? = null } + private val random = Random() private val boxes = Array(size) { InstanceBox() } diff --git a/core/src/main/kotlin/net/corda/core/internal/ResolveTransactionsFlow.kt b/core/src/main/kotlin/net/corda/core/internal/ResolveTransactionsFlow.kt index c38368aaf6..e0fec0f7ac 100644 --- a/core/src/main/kotlin/net/corda/core/internal/ResolveTransactionsFlow.kt +++ b/core/src/main/kotlin/net/corda/core/internal/ResolveTransactionsFlow.kt @@ -28,6 +28,7 @@ class ResolveTransactionsFlow(private val txHashes: Set, constructor(signedTransaction: SignedTransaction, otherSide: FlowSession) : this(dependencyIDs(signedTransaction), otherSide) { this.signedTransaction = signedTransaction } + companion object { private fun dependencyIDs(stx: SignedTransaction) = stx.inputs.map { it.txhash }.toSet() diff --git a/core/src/main/kotlin/net/corda/core/internal/WriteOnceProperty.kt b/core/src/main/kotlin/net/corda/core/internal/WriteOnceProperty.kt index ad0ae9bc39..ae815be6ca 100644 --- a/core/src/main/kotlin/net/corda/core/internal/WriteOnceProperty.kt +++ b/core/src/main/kotlin/net/corda/core/internal/WriteOnceProperty.kt @@ -6,7 +6,7 @@ import kotlin.reflect.KProperty * A write-once property to be used as delegate for Kotlin var properties. The expectation is that this is initialised * prior to the spawning of any threads that may access it and so there's no need for it to be volatile. */ -class WriteOnceProperty(private val defaultValue:T? = null) { +class WriteOnceProperty(private val defaultValue: T? = null) { private var v: T? = defaultValue operator fun getValue(thisRef: Any?, property: KProperty<*>) = v ?: throw IllegalStateException("Write-once property $property not set.") diff --git a/core/src/main/kotlin/net/corda/core/internal/X509EdDSAEngine.kt b/core/src/main/kotlin/net/corda/core/internal/X509EdDSAEngine.kt index 0bebc73130..cd5fac1ee1 100644 --- a/core/src/main/kotlin/net/corda/core/internal/X509EdDSAEngine.kt +++ b/core/src/main/kotlin/net/corda/core/internal/X509EdDSAEngine.kt @@ -46,6 +46,7 @@ class X509EdDSAEngine : Signature { override fun engineSetParameter(params: AlgorithmParameterSpec) = engine.setParameter(params) @Suppress("DEPRECATION") override fun engineGetParameter(param: String): Any = engine.getParameter(param) + @Suppress("DEPRECATION") override fun engineSetParameter(param: String, value: Any?) = engine.setParameter(param, value) } diff --git a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt index 9fddfead5d..d29cc7a193 100644 --- a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt +++ b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt @@ -104,12 +104,15 @@ interface CordaRPCOps : RPCOps { fun vaultQuery(contractStateType: Class): Vault.Page { return vaultQueryBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractStateType) } + fun vaultQueryByCriteria(criteria: QueryCriteria, contractStateType: Class): Vault.Page { return vaultQueryBy(criteria, PageSpecification(), Sort(emptySet()), contractStateType) } + fun vaultQueryByWithPagingSpec(contractStateType: Class, criteria: QueryCriteria, paging: PageSpecification): Vault.Page { return vaultQueryBy(criteria, paging, Sort(emptySet()), contractStateType) } + fun vaultQueryByWithSorting(contractStateType: Class, criteria: QueryCriteria, sorting: Sort): Vault.Page { return vaultQueryBy(criteria, PageSpecification(), sorting, contractStateType) } @@ -142,12 +145,15 @@ interface CordaRPCOps : RPCOps { fun vaultTrack(contractStateType: Class): DataFeed, Vault.Update> { return vaultTrackBy(QueryCriteria.VaultQueryCriteria(), PageSpecification(), Sort(emptySet()), contractStateType) } + fun vaultTrackByCriteria(contractStateType: Class, criteria: QueryCriteria): DataFeed, Vault.Update> { return vaultTrackBy(criteria, PageSpecification(), Sort(emptySet()), contractStateType) } + fun vaultTrackByWithPagingSpec(contractStateType: Class, criteria: QueryCriteria, paging: PageSpecification): DataFeed, Vault.Update> { return vaultTrackBy(criteria, paging, Sort(emptySet()), contractStateType) } + fun vaultTrackByWithSorting(contractStateType: Class, criteria: QueryCriteria, sorting: Sort): DataFeed, Vault.Update> { return vaultTrackBy(criteria, PageSpecification(), sorting, contractStateType) } @@ -250,6 +256,7 @@ interface CordaRPCOps : RPCOps { * @return well known identity, if found. */ fun wellKnownPartyFromAnonymous(party: AbstractParty): Party? + /** Returns the [Party] corresponding to the given key, if found. */ fun partyFromKey(key: PublicKey): Party? @@ -310,7 +317,7 @@ inline fun > CordaRPCOps.startFlow( flowConstructor: () -> R ): FlowHandle = startFlowDynamic(R::class.java) -inline fun > CordaRPCOps.startFlow( +inline fun > CordaRPCOps.startFlow( @Suppress("UNUSED_PARAMETER") flowConstructor: (A) -> R, arg0: A diff --git a/core/src/main/kotlin/net/corda/core/messaging/FlowHandle.kt b/core/src/main/kotlin/net/corda/core/messaging/FlowHandle.kt index 9cd9776061..166825de0c 100644 --- a/core/src/main/kotlin/net/corda/core/messaging/FlowHandle.kt +++ b/core/src/main/kotlin/net/corda/core/messaging/FlowHandle.kt @@ -43,7 +43,7 @@ data class FlowHandleImpl( override val id: StateMachineRunId, override val returnValue: CordaFuture) : FlowHandle { - // Remember to add @Throws to FlowHandle.close() if this throws an exception. + // Remember to add @Throws to FlowHandle.close() if this throws an exception. override fun close() { returnValue.cancel(false) } diff --git a/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt b/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt index d5ef1df776..cf3e5aed2e 100644 --- a/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt +++ b/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt @@ -35,9 +35,10 @@ data class NodeInfo(val addresses: List, * are porting code from earlier versions of Corda that expected a single party per node, just use the first item * in the returned list. */ - val legalIdentities: List get() { - return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it } - } + val legalIdentities: List + get() { + return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it } + } /** Returns true if [party] is one of the identities of this node, else false. */ fun isLegalIdentity(party: Party): Boolean = party in legalIdentities diff --git a/core/src/main/kotlin/net/corda/core/node/services/PartyInfo.kt b/core/src/main/kotlin/net/corda/core/node/services/PartyInfo.kt index 2db0543618..998c846c20 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/PartyInfo.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/PartyInfo.kt @@ -8,6 +8,7 @@ import net.corda.core.utilities.NetworkHostAndPort */ sealed class PartyInfo { abstract val party: Party - data class SingleNode(override val party: Party, val addresses: List): PartyInfo() - data class DistributedNode(override val party: Party): PartyInfo() + + data class SingleNode(override val party: Party, val addresses: List) : PartyInfo() + data class DistributedNode(override val party: Party) : PartyInfo() } diff --git a/core/src/main/kotlin/net/corda/core/node/services/VaultService.kt b/core/src/main/kotlin/net/corda/core/node/services/VaultService.kt index a16243a7db..38545ac754 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/VaultService.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/VaultService.kt @@ -99,7 +99,7 @@ class Vault(val states: Iterable>) { companion object { val NoUpdate = Update(emptySet(), emptySet(), type = Vault.UpdateType.GENERAL) - val NoNotaryUpdate = Vault.Update(emptySet(), emptySet(), type = Vault.UpdateType.NOTARY_CHANGE) + val NoNotaryUpdate = Vault.Update(emptySet(), emptySet(), type = Vault.UpdateType.NOTARY_CHANGE) } @CordaSerializable diff --git a/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteria.kt b/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteria.kt index 6f15271057..1e5eeb858f 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteria.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteria.kt @@ -49,12 +49,12 @@ sealed class QueryCriteria { /** * VaultQueryCriteria: provides query by attributes defined in [VaultSchema.VaultStates] */ - data class VaultQueryCriteria @JvmOverloads constructor (override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - override val contractStateTypes: Set>? = null, - val stateRefs: List? = null, - val notary: List? = null, - val softLockingCondition: SoftLockingCondition? = null, - val timeCondition: TimeCondition? = null) : CommonQueryCriteria() { + data class VaultQueryCriteria @JvmOverloads constructor(override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, + override val contractStateTypes: Set>? = null, + val stateRefs: List? = null, + val notary: List? = null, + val softLockingCondition: SoftLockingCondition? = null, + val timeCondition: TimeCondition? = null) : CommonQueryCriteria() { override fun visit(parser: IQueryCriteriaParser): Collection { super.visit(parser) return parser.parseCriteria(this) @@ -69,10 +69,10 @@ sealed class QueryCriteria { val externalId: List? = null, override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, override val contractStateTypes: Set>? = null) : CommonQueryCriteria() { - constructor(participants: List? = null, - linearId: List? = null, - status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - contractStateTypes: Set>? = null) : this(participants, linearId?.map { it.id }, linearId?.mapNotNull { it.externalId }, status, contractStateTypes) + constructor(participants: List? = null, + linearId: List? = null, + status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, + contractStateTypes: Set>? = null) : this(participants, linearId?.map { it.id }, linearId?.mapNotNull { it.externalId }, status, contractStateTypes) override fun visit(parser: IQueryCriteriaParser): Collection { super.visit(parser) @@ -80,13 +80,13 @@ sealed class QueryCriteria { } } - /** - * FungibleStateQueryCriteria: provides query by attributes defined in [VaultSchema.VaultFungibleState] - * - * Valid TokenType implementations defined by Amount are - * [Currency] as used in [Cash] contract state - * [Commodity] as used in [CommodityContract] state - */ + /** + * FungibleStateQueryCriteria: provides query by attributes defined in [VaultSchema.VaultFungibleState] + * + * Valid TokenType implementations defined by Amount are + * [Currency] as used in [Cash] contract state + * [Commodity] as used in [CommodityContract] state + */ data class FungibleAssetQueryCriteria @JvmOverloads constructor(val participants: List? = null, val owner: List? = null, val quantity: ColumnPredicate? = null, @@ -94,11 +94,11 @@ sealed class QueryCriteria { val issuerRef: List? = null, override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, override val contractStateTypes: Set>? = null) : CommonQueryCriteria() { - override fun visit(parser: IQueryCriteriaParser): Collection { - super.visit(parser) - return parser.parseCriteria(this) - } - } + override fun visit(parser: IQueryCriteriaParser): Collection { + super.visit(parser) + return parser.parseCriteria(this) + } + } /** * VaultCustomQueryCriteria: provides query by custom attributes defined in a contracts @@ -111,9 +111,9 @@ sealed class QueryCriteria { * Refer to [CommercialPaper.State] for a concrete example. */ data class VaultCustomQueryCriteria @JvmOverloads constructor - (val expression: CriteriaExpression, - override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, - override val contractStateTypes: Set>? = null) : CommonQueryCriteria() { + (val expression: CriteriaExpression, + override val status: Vault.StateStatus = Vault.StateStatus.UNCONSUMED, + override val contractStateTypes: Set>? = null) : CommonQueryCriteria() { override fun visit(parser: IQueryCriteriaParser): Collection { super.visit(parser) return parser.parseCriteria(this) @@ -121,13 +121,13 @@ sealed class QueryCriteria { } // enable composition of [QueryCriteria] - private data class AndComposition(val a: QueryCriteria, val b: QueryCriteria): QueryCriteria() { + private data class AndComposition(val a: QueryCriteria, val b: QueryCriteria) : QueryCriteria() { override fun visit(parser: IQueryCriteriaParser): Collection { return parser.parseAnd(this.a, this.b) } } - private data class OrComposition(val a: QueryCriteria, val b: QueryCriteria): QueryCriteria() { + private data class OrComposition(val a: QueryCriteria, val b: QueryCriteria) : QueryCriteria() { override fun visit(parser: IQueryCriteriaParser): Collection { return parser.parseOr(this.a, this.b) } @@ -148,9 +148,9 @@ interface IQueryCriteriaParser { fun parseCriteria(criteria: QueryCriteria.CommonQueryCriteria): Collection fun parseCriteria(criteria: QueryCriteria.FungibleAssetQueryCriteria): Collection fun parseCriteria(criteria: QueryCriteria.LinearStateQueryCriteria): Collection - fun parseCriteria(criteria: QueryCriteria.VaultCustomQueryCriteria): Collection + fun parseCriteria(criteria: QueryCriteria.VaultCustomQueryCriteria): Collection fun parseCriteria(criteria: QueryCriteria.VaultQueryCriteria): Collection fun parseOr(left: QueryCriteria, right: QueryCriteria): Collection fun parseAnd(left: QueryCriteria, right: QueryCriteria): Collection - fun parse(criteria: QueryCriteria, sorting: Sort? = null) : Collection + fun parse(criteria: QueryCriteria, sorting: Sort? = null): Collection } diff --git a/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteriaUtils.kt b/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteriaUtils.kt index 1ee9ab89d4..85d7292061 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteriaUtils.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/vault/QueryCriteriaUtils.kt @@ -170,8 +170,8 @@ data class Sort(val columns: Collection) { @CordaSerializable data class SortColumn( - val sortAttribute: SortAttribute, - val direction: Sort.Direction = Sort.Direction.ASC) + val sortAttribute: SortAttribute, + val direction: Sort.Direction = Sort.Direction.ASC) } @CordaSerializable @@ -199,8 +199,9 @@ object Builder { fun Field.predicate(predicate: ColumnPredicate) = CriteriaExpression.ColumnPredicateExpression(Column(this), predicate) - fun KProperty1.functionPredicate(predicate: ColumnPredicate, groupByColumns: List>? = null, orderBy: Sort.Direction? = null) + fun KProperty1.functionPredicate(predicate: ColumnPredicate, groupByColumns: List>? = null, orderBy: Sort.Direction? = null) = CriteriaExpression.AggregateFunctionExpression(Column(this), predicate, groupByColumns, orderBy) + fun Field.functionPredicate(predicate: ColumnPredicate, groupByColumns: List>? = null, orderBy: Sort.Direction? = null) = CriteriaExpression.AggregateFunctionExpression(Column(this), predicate, groupByColumns, orderBy) @@ -217,15 +218,32 @@ object Builder { fun > KProperty1.`in`(collection: Collection) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.IN, collection)) fun > KProperty1.notIn(collection: Collection) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection)) - @JvmStatic fun Field.equal(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value)) - @JvmStatic fun Field.notEqual(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value)) - @JvmStatic fun > Field.lessThan(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN, value) - @JvmStatic fun > Field.lessThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN_OR_EQUAL, value) - @JvmStatic fun > Field.greaterThan(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN, value) - @JvmStatic fun > Field.greaterThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL, value) - @JvmStatic fun > Field.between(from: R, to: R) = predicate(ColumnPredicate.Between(from, to)) - @JvmStatic fun > Field.`in`(collection: Collection) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.IN, collection)) - @JvmStatic fun > Field.notIn(collection: Collection) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection)) + @JvmStatic + fun Field.equal(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value)) + + @JvmStatic + fun Field.notEqual(value: R) = predicate(ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value)) + + @JvmStatic + fun > Field.lessThan(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN, value) + + @JvmStatic + fun > Field.lessThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.LESS_THAN_OR_EQUAL, value) + + @JvmStatic + fun > Field.greaterThan(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN, value) + + @JvmStatic + fun > Field.greaterThanOrEqual(value: R) = comparePredicate(BinaryComparisonOperator.GREATER_THAN_OR_EQUAL, value) + + @JvmStatic + fun > Field.between(from: R, to: R) = predicate(ColumnPredicate.Between(from, to)) + + @JvmStatic + fun > Field.`in`(collection: Collection) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.IN, collection)) + + @JvmStatic + fun > Field.notIn(collection: Collection) = predicate(ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection)) fun equal(value: R) = ColumnPredicate.EqualityComparison(EqualityComparisonOperator.EQUAL, value) fun notEqual(value: R) = ColumnPredicate.EqualityComparison(EqualityComparisonOperator.NOT_EQUAL, value) @@ -238,45 +256,57 @@ object Builder { fun > notIn(collection: Collection) = ColumnPredicate.CollectionExpression(CollectionOperator.NOT_IN, collection) fun KProperty1.like(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.LIKE, string)) - @JvmStatic fun Field.like(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.LIKE, string)) + @JvmStatic + fun Field.like(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.LIKE, string)) + fun KProperty1.notLike(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.NOT_LIKE, string)) - @JvmStatic fun Field.notLike(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.NOT_LIKE, string)) + @JvmStatic + fun Field.notLike(string: String) = predicate(ColumnPredicate.Likeness(LikenessOperator.NOT_LIKE, string)) fun KProperty1.isNull() = predicate(ColumnPredicate.NullExpression(NullOperator.IS_NULL)) - @JvmStatic fun Field.isNull() = predicate(ColumnPredicate.NullExpression(NullOperator.IS_NULL)) + @JvmStatic + fun Field.isNull() = predicate(ColumnPredicate.NullExpression(NullOperator.IS_NULL)) + fun KProperty1.notNull() = predicate(ColumnPredicate.NullExpression(NullOperator.NOT_NULL)) - @JvmStatic fun Field.notNull() = predicate(ColumnPredicate.NullExpression(NullOperator.NOT_NULL)) + @JvmStatic + fun Field.notNull() = predicate(ColumnPredicate.NullExpression(NullOperator.NOT_NULL)) /** aggregate functions */ fun KProperty1.sum(groupByColumns: List>? = null, orderBy: Sort.Direction? = null) = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.SUM), groupByColumns?.map { Column(it) }, orderBy) - @JvmStatic @JvmOverloads + + @JvmStatic + @JvmOverloads fun Field.sum(groupByColumns: List? = null, orderBy: Sort.Direction? = null) = - functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.SUM), groupByColumns?.map { Column(it) }, orderBy) + functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.SUM), groupByColumns?.map { Column(it) }, orderBy) fun KProperty1.count() = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.COUNT)) - @JvmStatic fun Field.count() = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.COUNT)) + @JvmStatic + fun Field.count() = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.COUNT)) fun KProperty1.avg(groupByColumns: List>? = null, orderBy: Sort.Direction? = null) = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.AVG), groupByColumns?.map { Column(it) }, orderBy) + @JvmStatic @JvmOverloads fun Field.avg(groupByColumns: List? = null, orderBy: Sort.Direction? = null) = - functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.AVG), groupByColumns?.map { Column(it) }, orderBy) + functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.AVG), groupByColumns?.map { Column(it) }, orderBy) fun KProperty1.min(groupByColumns: List>? = null, orderBy: Sort.Direction? = null) = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MIN), groupByColumns?.map { Column(it) }, orderBy) + @JvmStatic @JvmOverloads fun Field.min(groupByColumns: List? = null, orderBy: Sort.Direction? = null) = - functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MIN), groupByColumns?.map { Column(it) }, orderBy) + functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MIN), groupByColumns?.map { Column(it) }, orderBy) fun KProperty1.max(groupByColumns: List>? = null, orderBy: Sort.Direction? = null) = functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MAX), groupByColumns?.map { Column(it) }, orderBy) + @JvmStatic @JvmOverloads fun Field.max(groupByColumns: List? = null, orderBy: Sort.Direction? = null) = - functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MAX), groupByColumns?.map { Column(it) }, orderBy) + functionPredicate(ColumnPredicate.AggregateFunction(AggregateFunctionType.MAX), groupByColumns?.map { Column(it) }, orderBy) } inline fun builder(block: Builder.() -> A) = block(Builder) diff --git a/core/src/main/kotlin/net/corda/core/schemas/CommonSchema.kt b/core/src/main/kotlin/net/corda/core/schemas/CommonSchema.kt index 0f9d985791..1d5559d45d 100644 --- a/core/src/main/kotlin/net/corda/core/schemas/CommonSchema.kt +++ b/core/src/main/kotlin/net/corda/core/schemas/CommonSchema.kt @@ -38,9 +38,9 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers ) : PersistentState() { constructor(uid: UniqueIdentifier, _participants: Set) - : this(participants = _participants.toMutableSet(), - externalId = uid.externalId, - uuid = uid.id) + : this(participants = _participants.toMutableSet(), + externalId = uid.externalId, + uuid = uid.id) } @MappedSuperclass diff --git a/core/src/main/kotlin/net/corda/core/schemas/NodeInfoSchema.kt b/core/src/main/kotlin/net/corda/core/schemas/NodeInfoSchema.kt index 8e019d7b5b..a0e6c80f49 100644 --- a/core/src/main/kotlin/net/corda/core/schemas/NodeInfoSchema.kt +++ b/core/src/main/kotlin/net/corda/core/schemas/NodeInfoSchema.kt @@ -31,8 +31,8 @@ object NodeInfoSchemaV1 : MappedSchema( @Column(name = "legal_identities_certs") @ManyToMany(cascade = arrayOf(CascadeType.ALL)) @JoinTable(name = "link_nodeinfo_party", - joinColumns = arrayOf(JoinColumn(name="node_info_id")), - inverseJoinColumns = arrayOf(JoinColumn(name="party_name"))) + joinColumns = arrayOf(JoinColumn(name = "node_info_id")), + inverseJoinColumns = arrayOf(JoinColumn(name = "party_name"))) val legalIdentitiesAndCerts: List, @Column(name = "platform_version") @@ -64,14 +64,15 @@ object NodeInfoSchemaV1 : MappedSchema( @Entity data class DBHostAndPort( - @EmbeddedId - private val pk: PKHostAndPort + @EmbeddedId + private val pk: PKHostAndPort ) { companion object { fun fromHostAndPort(hostAndPort: NetworkHostAndPort) = DBHostAndPort( PKHostAndPort(hostAndPort.host, hostAndPort.port) ) } + fun toHostAndPort(): NetworkHostAndPort { return NetworkHostAndPort(this.pk.host!!, this.pk.port!!) } diff --git a/core/src/main/kotlin/net/corda/core/schemas/PersistentTypes.kt b/core/src/main/kotlin/net/corda/core/schemas/PersistentTypes.kt index a02241aae2..cd55da4982 100644 --- a/core/src/main/kotlin/net/corda/core/schemas/PersistentTypes.kt +++ b/core/src/main/kotlin/net/corda/core/schemas/PersistentTypes.kt @@ -49,7 +49,8 @@ open class MappedSchema(schemaFamily: Class<*>, * A super class for all mapped states exported to a schema that ensures the [StateRef] appears on the database row. The * [StateRef] will be set to the correct value by the framework (there's no need to set during mapping generation by the state itself). */ -@MappedSuperclass @CordaSerializable open class PersistentState(@EmbeddedId var stateRef: PersistentStateRef? = null) : StatePersistable +@MappedSuperclass +@CordaSerializable open class PersistentState(@EmbeddedId var stateRef: PersistentStateRef? = null) : StatePersistable /** * Embedded [StateRef] representation used in state mapping. diff --git a/core/src/main/kotlin/net/corda/core/serialization/SerializationAPI.kt b/core/src/main/kotlin/net/corda/core/serialization/SerializationAPI.kt index 131578482e..b0499938ef 100644 --- a/core/src/main/kotlin/net/corda/core/serialization/SerializationAPI.kt +++ b/core/src/main/kotlin/net/corda/core/serialization/SerializationAPI.kt @@ -115,6 +115,7 @@ interface SerializationContext { * The use case we are serializing or deserializing for. See [UseCase]. */ val useCase: UseCase + /** * Helper method to return a new context based on this context with the property added. */ diff --git a/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt index d62b1c0e6e..1881431114 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/LedgerTransaction.kt @@ -57,7 +57,7 @@ data class LedgerTransaction( } private val contracts: Map> = (inputs.map { it.state.contract } + outputs.map { it.contract }) - .toSet().map { it to createContractFor(it) }.toMap() + .toSet().map { it to createContractFor(it) }.toMap() val inputStates: List get() = inputs.map { it.state.data } @@ -79,8 +79,7 @@ data class LedgerTransaction( // TODO: make contract upgrade transactions have a separate type if (commands.any { it.value is UpgradeCommand }) { verifyContractUpgrade() - } - else { + } else { verifyContracts() } } diff --git a/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt index 4cd1332659..8f2c476004 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt @@ -48,7 +48,7 @@ abstract class TraversableTransaction(open val componentGroups: List> get() { val result = mutableListOf(inputs, outputs, commands, attachments) @@ -138,7 +138,7 @@ class FilteredTransaction private constructor( fun updateFilteredComponents() { wtx.inputs.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.INPUTS_GROUP.ordinal, internalIndex) } wtx.outputs.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.OUTPUTS_GROUP.ordinal, internalIndex) } - wtx.commands.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.COMMANDS_GROUP.ordinal, internalIndex) } + wtx.commands.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.COMMANDS_GROUP.ordinal, internalIndex) } wtx.attachments.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.ATTACHMENTS_GROUP.ordinal, internalIndex) } if (wtx.notary != null) filter(wtx.notary, ComponentGroupEnum.NOTARY_GROUP.ordinal, 0) if (wtx.timeWindow != null) filter(wtx.timeWindow, ComponentGroupEnum.TIMEWINDOW_GROUP.ordinal, 0) @@ -147,7 +147,7 @@ class FilteredTransaction private constructor( // we decide to filter and attach this field to a FilteredTransaction. // An example would be to redact certain contract state types, but otherwise leave a transaction alone, // including the unknown new components. - wtx.componentGroups.filter { it.groupIndex >= ComponentGroupEnum.values().size }.forEach { componentGroup -> componentGroup.components.forEachIndexed { internalIndex, component-> filter(component, componentGroup.groupIndex, internalIndex) }} + wtx.componentGroups.filter { it.groupIndex >= ComponentGroupEnum.values().size }.forEach { componentGroup -> componentGroup.components.forEachIndexed { internalIndex, component -> filter(component, componentGroup.groupIndex, internalIndex) } } } fun createPartialMerkleTree(componentGroupIndex: Int) = PartialMerkleTree.build(MerkleTree.getMerkleTree(wtx.availableComponentHashes[componentGroupIndex]!!), filteredComponentHashes[componentGroupIndex]!!) @@ -156,7 +156,7 @@ class FilteredTransaction private constructor( updateFilteredComponents() val filteredComponentGroups: MutableList = mutableListOf() filteredSerialisedComponents.forEach { (groupIndex, value) -> - filteredComponentGroups.add(FilteredComponentGroup(groupIndex, value, filteredComponentNonces[groupIndex]!!, createPartialMerkleTree(groupIndex) )) + filteredComponentGroups.add(FilteredComponentGroup(groupIndex, value, filteredComponentNonces[groupIndex]!!, createPartialMerkleTree(groupIndex))) } return filteredComponentGroups } @@ -183,7 +183,7 @@ class FilteredTransaction private constructor( // Compute partial Merkle roots for each filtered component and verify each of the partial Merkle trees. filteredComponentGroups.forEach { (groupIndex, components, nonces, groupPartialTree) -> - verificationCheck(groupIndex < groupHashes.size ) { "There is no matching component group hash for group $groupIndex" } + verificationCheck(groupIndex < groupHashes.size) { "There is no matching component group hash for group $groupIndex" } val groupMerkleRoot = groupHashes[groupIndex] verificationCheck(groupMerkleRoot == PartialMerkleTree.rootAndUsedHashes(groupPartialTree.root, mutableListOf())) { "Partial Merkle tree root and advertised full Merkle tree root for component group $groupIndex do not match" } verificationCheck(groupPartialTree.verify(groupMerkleRoot, components.mapIndexed { index, component -> componentHash(nonces[index], component) })) { "Visible components in group $groupIndex cannot be verified against their partial Merkle tree" } @@ -226,7 +226,7 @@ class FilteredTransaction private constructor( "Did not receive components for group ${componentGroupEnum.ordinal} and cannot verify they didn't exist in the original wire transaction" } } else { - visibilityCheck(group.groupIndex < groupHashes.size ) { "There is no matching component group hash for group ${group.groupIndex}" } + visibilityCheck(group.groupIndex < groupHashes.size) { "There is no matching component group hash for group ${group.groupIndex}" } val groupPartialRoot = groupHashes[group.groupIndex] val groupFullRoot = MerkleTree.getMerkleTree(group.components.mapIndexed { index, component -> componentHash(group.nonces[index], component) }).hash visibilityCheck(groupPartialRoot == groupFullRoot) { "The partial Merkle tree root does not match with the received root for group ${group.groupIndex}" } @@ -253,7 +253,7 @@ class FilteredTransaction private constructor( * This is similar to [ComponentGroup], but it also includes the corresponding nonce per component. */ @CordaSerializable -data class FilteredComponentGroup(override val groupIndex: Int, override val components: List, val nonces: List, val partialMerkleTree: PartialMerkleTree): ComponentGroup(groupIndex, components) { +data class FilteredComponentGroup(override val groupIndex: Int, override val components: List, val nonces: List, val partialMerkleTree: PartialMerkleTree) : ComponentGroup(groupIndex, components) { init { check(components.size == nonces.size) { "Size of transaction components and nonces do not match" } } diff --git a/core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt b/core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt index 935ddfdd8d..725e75da0f 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt @@ -12,4 +12,4 @@ import net.corda.core.serialization.CordaSerializable */ @CordaSerializable class MissingContractAttachments(val states: List>) - : FlowException("Cannot find contract attachments for ${states.map { it.contract }.distinct() }") \ No newline at end of file + : FlowException("Cannot find contract attachments for ${states.map { it.contract }.distinct()}") \ No newline at end of file diff --git a/core/src/main/kotlin/net/corda/core/transactions/SignedTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/SignedTransaction.kt index 4e8602daf6..d583a5f386 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/SignedTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/SignedTransaction.kt @@ -47,7 +47,8 @@ data class SignedTransaction(val txBits: SerializedBytes, } /** Cache the deserialized form of the transaction. This is useful when building a transaction or collecting signatures. */ - @Volatile @Transient private var cachedTransaction: CoreTransaction? = null + @Volatile + @Transient private var cachedTransaction: CoreTransaction? = null /** Lazily calculated access to the deserialised/hashed transaction data. */ private val transaction: CoreTransaction get() = cachedTransaction ?: txBits.deserialize().apply { cachedTransaction = this } diff --git a/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt b/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt index ad6c538451..847bdfc31b 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt @@ -38,8 +38,8 @@ open class TransactionBuilder( protected val commands: MutableList> = arrayListOf(), protected var window: TimeWindow? = null, protected var privacySalt: PrivacySalt = PrivacySalt() - ) { - constructor(notary: Party) : this (notary, (Strand.currentStrand() as? FlowStateMachine<*>)?.id?.uuid ?: UUID.randomUUID()) +) { + constructor(notary: Party) : this(notary, (Strand.currentStrand() as? FlowStateMachine<*>)?.id?.uuid ?: UUID.randomUUID()) /** * Creates a copy of the builder. @@ -179,6 +179,7 @@ open class TransactionBuilder( // Accessors that yield immutable snapshots. fun inputStates(): List = ArrayList(inputs) + fun attachments(): List = ArrayList(attachments) fun outputStates(): List> = ArrayList(outputs) fun commands(): List> = ArrayList(commands) diff --git a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt index 3bba0b8ae6..2325344286 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt @@ -63,15 +63,16 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr override val id: SecureHash get() = merkleTree.hash /** Public keys that need to be fulfilled by signatures in order for the transaction to be valid. */ - val requiredSigningKeys: Set get() { - val commandKeys = commands.flatMap { it.signers }.toSet() - // TODO: prevent notary field from being set if there are no inputs and no timestamp. - return if (notary != null && (inputs.isNotEmpty() || timeWindow != null)) { - commandKeys + notary.owningKey - } else { - commandKeys + val requiredSigningKeys: Set + get() { + val commandKeys = commands.flatMap { it.signers }.toSet() + // TODO: prevent notary field from being set if there are no inputs and no timestamp. + return if (notary != null && (inputs.isNotEmpty() || timeWindow != null)) { + commandKeys + notary.owningKey + } else { + commandKeys + } } - } /** * Looks up identities and attachments from storage to generate a [LedgerTransaction]. A transaction is expected to @@ -84,7 +85,7 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr fun toLedgerTransaction(services: ServicesForResolution): LedgerTransaction { return toLedgerTransaction( resolveIdentity = { services.identityService.partyFromKey(it) }, - resolveAttachment = { services.attachments.openAttachment(it)}, + resolveAttachment = { services.attachments.openAttachment(it) }, resolveStateRef = { services.loadState(it) }, resolveContractAttachment = { services.cordappProvider.getContractAttachmentID(it.contract) } ) @@ -123,7 +124,7 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr * Build filtered transaction using provided filtering functions. */ fun buildFilteredTransaction(filtering: Predicate): FilteredTransaction = - FilteredTransaction.buildFilteredTransaction(this, filtering) + FilteredTransaction.buildFilteredTransaction(this, filtering) /** * Builds whole Merkle tree for a transaction. @@ -236,7 +237,7 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr ): List { val contractAttachments = (outputs + resolvedInputs.map { it.state }).map { Pair(it, resolveContractAttachment(it)) } val missingAttachments = contractAttachments.filter { it.second == null } - return if(missingAttachments.isEmpty()) { + return if (missingAttachments.isEmpty()) { contractAttachments.map { ContractAttachment(resolveAttachment(it.second!!) ?: throw AttachmentResolutionException(it.second!!), it.first.contract) } } else { throw MissingContractAttachments(missingAttachments.map { it.first }) diff --git a/core/src/main/kotlin/net/corda/core/utilities/ByteArrays.kt b/core/src/main/kotlin/net/corda/core/utilities/ByteArrays.kt index 23eb6d86e5..a2b74a11ff 100644 --- a/core/src/main/kotlin/net/corda/core/utilities/ByteArrays.kt +++ b/core/src/main/kotlin/net/corda/core/utilities/ByteArrays.kt @@ -25,6 +25,7 @@ sealed class ByteSequence : Comparable { * The start position of the sequence within the byte array. */ abstract val offset: Int + /** Returns a [ByteArrayInputStream] of the bytes */ fun open() = ByteArrayInputStream(bytes, offset, size) diff --git a/core/src/main/kotlin/net/corda/core/utilities/EncodingUtils.kt b/core/src/main/kotlin/net/corda/core/utilities/EncodingUtils.kt index 1cc4e53807..2c1854c897 100644 --- a/core/src/main/kotlin/net/corda/core/utilities/EncodingUtils.kt +++ b/core/src/main/kotlin/net/corda/core/utilities/EncodingUtils.kt @@ -66,5 +66,6 @@ fun String.hexToBase64(): String = hexToByteArray().toBase64() // TODO: follow the crypto-conditions ASN.1 spec, some changes are needed to be compatible with the condition // structure, e.g. mapping a PublicKey to a condition with the specific feature (ED25519). fun parsePublicKeyBase58(base58String: String): PublicKey = base58String.base58ToByteArray().deserialize() + fun PublicKey.toBase58String(): String = this.serialize().bytes.toBase58() fun PublicKey.toSHA256Bytes(): ByteArray = this.serialize().bytes.sha256().bytes // TODO: decide on the format of hashed key (encoded Vs serialised). diff --git a/core/src/main/kotlin/net/corda/core/utilities/NetworkHostAndPort.kt b/core/src/main/kotlin/net/corda/core/utilities/NetworkHostAndPort.kt index 8866e79e1b..6153c1c5d2 100644 --- a/core/src/main/kotlin/net/corda/core/utilities/NetworkHostAndPort.kt +++ b/core/src/main/kotlin/net/corda/core/utilities/NetworkHostAndPort.kt @@ -27,7 +27,7 @@ data class NetworkHostAndPort(val host: String, val port: Int) { fun parse(str: String): NetworkHostAndPort { val uri = try { URI(null, str, null, null, null) - } catch(ex: URISyntaxException) { + } catch (ex: URISyntaxException) { throw IllegalArgumentException("Host and port syntax is invalid, expected host:port") } require(uri.host != null) { NetworkHostAndPort.UNPARSEABLE_ADDRESS_FORMAT.format(str) } diff --git a/core/src/main/kotlin/net/corda/core/utilities/NonEmptySet.kt b/core/src/main/kotlin/net/corda/core/utilities/NonEmptySet.kt index 9e364769e2..ab5f0b86d7 100644 --- a/core/src/main/kotlin/net/corda/core/utilities/NonEmptySet.kt +++ b/core/src/main/kotlin/net/corda/core/utilities/NonEmptySet.kt @@ -48,11 +48,13 @@ class NonEmptySet private constructor(private val elements: Set) : Set /** Returns the first element of the set. */ fun head(): T = elements.iterator().next() + override fun isEmpty(): Boolean = false override fun iterator() = object : Iterator by elements.iterator() {} // Following methods are not delegated by Kotlin's Class delegation override fun forEach(action: Consumer) = elements.forEach(action) + override fun stream(): Stream = elements.stream() override fun parallelStream(): Stream = elements.parallelStream() override fun spliterator(): Spliterator = elements.spliterator() diff --git a/core/src/test/kotlin/net/corda/core/contracts/CompatibleTransactionTests.kt b/core/src/test/kotlin/net/corda/core/contracts/CompatibleTransactionTests.kt index 79d06b3ab4..7ed31d3d38 100644 --- a/core/src/test/kotlin/net/corda/core/contracts/CompatibleTransactionTests.kt +++ b/core/src/test/kotlin/net/corda/core/contracts/CompatibleTransactionTests.kt @@ -45,11 +45,11 @@ class CompatibleTransactionTests : TestDependencyInjectionBase() { // Do not add attachments (empty list). private val componentGroupsA by lazy { listOf( - inputGroup, - outputGroup, - commandGroup, - notaryGroup, - timeWindowGroup + inputGroup, + outputGroup, + commandGroup, + notaryGroup, + timeWindowGroup ) } private val wireTransactionA by lazy { WireTransaction(componentGroups = componentGroupsA, privacySalt = privacySalt) } @@ -199,6 +199,7 @@ class CompatibleTransactionTests : TestDependencyInjectionBase() { else -> false } } + val ftxInputs = wireTransactionA.buildFilteredTransaction(Predicate(::filtering)) // Inputs only filtered. ftxInputs.verify() ftxInputs.checkAllComponentsVisible(INPUTS_GROUP) @@ -210,6 +211,7 @@ class CompatibleTransactionTests : TestDependencyInjectionBase() { // Filter one input only. fun filteringOneInput(elem: Any) = elem == inputs[0] + val ftxOneInput = wireTransactionA.buildFilteredTransaction(Predicate(::filteringOneInput)) // First input only filtered. ftxOneInput.verify() assertFailsWith { ftxOneInput.checkAllComponentsVisible(INPUTS_GROUP) } diff --git a/core/src/test/kotlin/net/corda/core/crypto/X509NameConstraintsTest.kt b/core/src/test/kotlin/net/corda/core/crypto/X509NameConstraintsTest.kt index 33e060453f..88854550a4 100644 --- a/core/src/test/kotlin/net/corda/core/crypto/X509NameConstraintsTest.kt +++ b/core/src/test/kotlin/net/corda/core/crypto/X509NameConstraintsTest.kt @@ -20,7 +20,7 @@ class X509NameConstraintsTest { private fun makeKeyStores(subjectName: X500Name, nameConstraints: NameConstraints): Pair { val rootKeys = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) - val rootCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Root CA", organisation = "R3 Ltd", locality= "London", country = "GB"), rootKeys) + val rootCACert = X509Utilities.createSelfSignedCACertificate(CordaX500Name(commonName = "Corda Root CA", organisation = "R3 Ltd", locality = "London", country = "GB"), rootKeys) val intermediateCAKeyPair = Crypto.generateKeyPair(X509Utilities.DEFAULT_TLS_SIGNATURE_SCHEME) val intermediateCACert = X509Utilities.createCertificate(CertificateType.INTERMEDIATE_CA, rootCACert, rootKeys, CordaX500Name(commonName = "Corda Intermediate CA", organisation = "R3 Ltd", locality = "London", country = "GB"), intermediateCAKeyPair.public) diff --git a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt index 197f8ca00c..0720557b1f 100644 --- a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt +++ b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt @@ -161,14 +161,14 @@ class ContractUpgradeFlowTest { assertFailsWith(UnexpectedFlowEndException::class) { rejectedFuture.getOrThrow() } // Party B authorise the contract state upgrade, and immediately deauthorise the same. - rpcB.startFlow( { stateAndRef, upgrade -> ContractUpgradeFlow.Authorise(stateAndRef, upgrade ) }, + rpcB.startFlow({ stateAndRef, upgrade -> ContractUpgradeFlow.Authorise(stateAndRef, upgrade) }, btx!!.tx.outRef(0), DummyContractV2::class.java).returnValue - rpcB.startFlow( { stateRef -> ContractUpgradeFlow.Deauthorise(stateRef) }, + rpcB.startFlow({ stateRef -> ContractUpgradeFlow.Deauthorise(stateRef) }, btx.tx.outRef(0).ref).returnValue // The request is expected to be rejected because party B has subsequently deauthorised and a previously authorised upgrade. - val deauthorisedFuture = rpcA.startFlow( {stateAndRef, upgrade -> ContractUpgradeFlow.Initiate(stateAndRef, upgrade) }, + val deauthorisedFuture = rpcA.startFlow({ stateAndRef, upgrade -> ContractUpgradeFlow.Initiate(stateAndRef, upgrade) }, atx.tx.outRef(0), DummyContractV2::class.java).returnValue @@ -176,7 +176,7 @@ class ContractUpgradeFlowTest { assertFailsWith(UnexpectedFlowEndException::class) { deauthorisedFuture.getOrThrow() } // Party B authorise the contract state upgrade. - rpcB.startFlow( { stateAndRef, upgrade -> ContractUpgradeFlow.Authorise(stateAndRef, upgrade ) }, + rpcB.startFlow({ stateAndRef, upgrade -> ContractUpgradeFlow.Authorise(stateAndRef, upgrade) }, btx.tx.outRef(0), DummyContractV2::class.java).returnValue diff --git a/core/src/test/kotlin/net/corda/core/internal/X509EdDSAEngineTest.kt b/core/src/test/kotlin/net/corda/core/internal/X509EdDSAEngineTest.kt index 3f79a6ce36..c4cca75b83 100644 --- a/core/src/test/kotlin/net/corda/core/internal/X509EdDSAEngineTest.kt +++ b/core/src/test/kotlin/net/corda/core/internal/X509EdDSAEngineTest.kt @@ -15,11 +15,11 @@ import kotlin.test.assertFailsWith import kotlin.test.assertTrue class TestX509Key(algorithmId: AlgorithmId, key: BitArray) : X509Key() { - init { - this.algid = algorithmId - this.setKey(key) - this.encode() - } + init { + this.algid = algorithmId + this.setKey(key) + this.encode() + } } class X509EdDSAEngineTest { diff --git a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt index db7d27d06a..4b14705669 100644 --- a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt +++ b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt @@ -45,6 +45,7 @@ private fun Attachment.extractContent() = ByteArrayOutputStream().apply { extrac private fun StartedNode<*>.saveAttachment(content: String) = database.transaction { attachments.importAttachment(createAttachmentData(content).inputStream()) } + private fun StartedNode<*>.hackAttachment(attachmentId: SecureHash, content: String) = database.transaction { updateAttachment(attachmentId, createAttachmentData(content)) } diff --git a/experimental/quasar-hook/src/main/kotlin/net/corda/quasarhook/QuasarInstrumentationHook.kt b/experimental/quasar-hook/src/main/kotlin/net/corda/quasarhook/QuasarInstrumentationHook.kt index c32328ba4a..acd586fa31 100644 --- a/experimental/quasar-hook/src/main/kotlin/net/corda/quasarhook/QuasarInstrumentationHook.kt +++ b/experimental/quasar-hook/src/main/kotlin/net/corda/quasarhook/QuasarInstrumentationHook.kt @@ -32,7 +32,7 @@ fun recordUsedInstrumentedCallStack() { val throwable = Throwable() var index = 0 while (true) { - require (index < throwable.stackTrace.size) { "Can't find getStack call" } + require(index < throwable.stackTrace.size) { "Can't find getStack call" } val stackElement = throwable.stackTrace[index] if (stackElement.className == "co.paralleluniverse.fibers.Stack" && stackElement.methodName == "getStack") { break @@ -129,7 +129,7 @@ class QuasarInstrumentationHookAgent { // The separator append is a hack, it causes a package with an empty name to be added to the exclude tree, // which practically causes that level of the tree to be always expanded in the output globs. val expand = arguments.expand?.let { PackageTree.fromStrings(it.map { "$it${arguments.separator}" }, arguments.separator) } - val truncatedTree = truncate?.let { scannedTree.truncate(it)} ?: scannedTree + val truncatedTree = truncate?.let { scannedTree.truncate(it) } ?: scannedTree val expandedTree = expand?.let { alwaysExcludedTree.merge(it) } ?: alwaysExcludedTree val globs = truncatedTree.toGlobs(expandedTree) globs.forEach { @@ -152,7 +152,7 @@ object QuasarInstrumentationHook : ClassFileTransformer { val instrumentMap = mapOf Unit>( "co/paralleluniverse/fibers/Stack" to { clazz -> // This is called on each suspend, we hook into it to get the stack trace of actually used Suspendables - val getStackMethod = clazz.methods.single { it.name == "getStack" } + val getStackMethod = clazz.methods.single { it.name == "getStack" } getStackMethod.insertBefore( "$hookClassName.${::recordUsedInstrumentedCallStack.name}();" ) @@ -194,7 +194,7 @@ object QuasarInstrumentationHook : ClassFileTransformer { throwable.printStackTrace(System.out) classfileBuffer } - } + } } data class Glob(val parts: List, val isFull: Boolean) { @@ -271,6 +271,7 @@ data class PackageTree(val branches: Map) { val exclude: PackageTree, val globSoFar: List ) + val toExpandList = LinkedList(listOf(State(this, excludeTree, emptyList()))) val globs = ArrayList() while (true) { diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/CandidacyStatus.java b/experimental/sandbox/src/main/java/net/corda/sandbox/CandidacyStatus.java index 7bcaf86684..f0fd4bf668 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/CandidacyStatus.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/CandidacyStatus.java @@ -43,7 +43,6 @@ public class CandidacyStatus { } /** - * * @param signature * @return true if the input was absent from the underlying map */ @@ -52,7 +51,6 @@ public class CandidacyStatus { } /** - * * @param methodSignature * @return true if the input was absent from the underlying map */ @@ -62,7 +60,7 @@ public class CandidacyStatus { /** * Static factory method - * + * * @param startingSet * @return a candidacy status based on the starting set */ @@ -81,7 +79,7 @@ public class CandidacyStatus { /** * Static factory method - * + * * @return a candidacy status based on the starting set */ public static CandidacyStatus of() { @@ -90,8 +88,8 @@ public class CandidacyStatus { /** * Add additional methods that are known to be deterministic - * - * @param methodNames + * + * @param methodNames */ public void addKnownDeterministicMethods(final Set methodNames) { for (String known : methodNames) { @@ -101,7 +99,7 @@ public class CandidacyStatus { /** * Getter method for candidate methods - * + * * @param methodSignature * @return the candidate method corresponding to a method signature */ @@ -149,10 +147,10 @@ public class CandidacyStatus { } /** - * Increases the recursive depth of this classloading process, throwing a + * Increases the recursive depth of this classloading process, throwing a * ClassNotFoundException if it becomes too high - * - * @throws ClassNotFoundException + * + * @throws ClassNotFoundException */ public void incRecursiveCount() throws ClassNotFoundException { if (recursiveDepth >= MAX_CLASSLOADING_RECURSIVE_DEPTH - 1) { @@ -174,7 +172,7 @@ public class CandidacyStatus { out.add(candidateName); } } - + return out; } diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/CandidateMethod.java b/experimental/sandbox/src/main/java/net/corda/sandbox/CandidateMethod.java index 49e5091fbe..b806d58b65 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/CandidateMethod.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/CandidateMethod.java @@ -6,15 +6,14 @@ import java.util.Set; /** * A candidate method that is under evaluation. Candidate methods have one of the following states: - * + *

*

    - *
  • {@link CandidateMethod.State#DETERMINISTIC} - It's deterministic and therefore is allowed to be loaded.
  • - *
  • {@link CandidateMethod.State#DISALLOWED} - It's not deterministic and won't be allowed to be loaded.
  • - *
  • {@link CandidateMethod.State#SCANNED} - We're not sure if it's deterministic or not.
  • + *
  • {@link CandidateMethod.State#DETERMINISTIC} - It's deterministic and therefore is allowed to be loaded.
  • + *
  • {@link CandidateMethod.State#DISALLOWED} - It's not deterministic and won't be allowed to be loaded.
  • + *
  • {@link CandidateMethod.State#SCANNED} - We're not sure if it's deterministic or not.
  • *
- * + *

* CandidateMethods themselves reference other CandidateMethods which are be checked for their deterministic state - * */ public final class CandidateMethod { @@ -43,7 +42,7 @@ public final class CandidateMethod { private final Set referencedCandidateMethods = new HashSet<>(); - + public State getCurrentState() { return currentState; } @@ -59,7 +58,7 @@ public final class CandidateMethod { public void deterministic() { if (currentState == State.DISALLOWED) { - throw new IllegalArgumentException("Method "+ internalMethodName +" attempted to transition from DISALLOWED to DETERMINISTIC"); + throw new IllegalArgumentException("Method " + internalMethodName + " attempted to transition from DISALLOWED to DETERMINISTIC"); } currentState = State.DETERMINISTIC; } @@ -79,7 +78,7 @@ public final class CandidateMethod { public String getInternalMethodName() { return internalMethodName; } - + public void addReferencedCandidateMethod(final CandidateMethod referenceCandidateMethod) { referencedCandidateMethods.add(referenceCandidateMethod); } @@ -94,8 +93,9 @@ public final class CandidateMethod { /** * This factory constructor is only called for methods that are known to be deterministic in advance + * * @param methodSignature - * @return + * @return */ public static CandidateMethod proven(String methodSignature) { final CandidateMethod provenCandidateMethod = new CandidateMethod(methodSignature); diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/SandboxAwareClassWriter.java b/experimental/sandbox/src/main/java/net/corda/sandbox/SandboxAwareClassWriter.java index 03e3cf9d56..f5e742b95c 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/SandboxAwareClassWriter.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/SandboxAwareClassWriter.java @@ -1,11 +1,11 @@ package net.corda.sandbox; import static net.corda.sandbox.Utils.*; + import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; /** - * * @author ben */ public final class SandboxAwareClassWriter extends ClassWriter { @@ -25,17 +25,15 @@ public final class SandboxAwareClassWriter extends ClassWriter { * without actually loading any class, or to take into account the class * that is currently being generated by this ClassWriter, which can of * course not be loaded since it is under construction. - * - * @param type1 - * the internal name of a class. - * @param type2 - * the internal name of another class. + * + * @param type1 the internal name of a class. + * @param type2 the internal name of another class. * @return the internal name of the common super class of the two given - * classes. + * classes. */ @Override public String getCommonSuperClass(final String type1, final String type2) { - if (OBJECT.equals(type1) || OBJECT.equals(type2) + if (OBJECT.equals(type1) || OBJECT.equals(type2) || OBJECT.equals(unsandboxNameIfNeedBe(type1)) || OBJECT.equals(unsandboxNameIfNeedBe(type2))) { return OBJECT; } @@ -58,7 +56,7 @@ public final class SandboxAwareClassWriter extends ClassWriter { c = Class.forName(type1.replace('/', '.'), false, loader); d = Class.forName(type2.replace('/', '.'), false, loader); } catch (Exception e) { - + c = Class.forName(unsandboxNameIfNeedBe(type1).replace('/', '.'), false, loader); d = Class.forName(unsandboxNameIfNeedBe(type2).replace('/', '.'), false, loader); diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/SandboxRemapper.java b/experimental/sandbox/src/main/java/net/corda/sandbox/SandboxRemapper.java index 2f55c4edb6..32157b6ff5 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/SandboxRemapper.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/SandboxRemapper.java @@ -3,7 +3,6 @@ package net.corda.sandbox; import org.objectweb.asm.commons.Remapper; /** - * * @author ben */ public final class SandboxRemapper extends Remapper { diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/Utils.java b/experimental/sandbox/src/main/java/net/corda/sandbox/Utils.java index 85fa4fc078..08cbbd794b 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/Utils.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/Utils.java @@ -4,7 +4,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * * @author ben */ public final class Utils { @@ -12,7 +11,7 @@ public final class Utils { public final static String SANDBOX_PREFIX_INTERNAL = "sandbox/"; public final static String CLASSFILE_NAME_SUFFIX = "^(.*)\\.class$"; - + public static final Pattern JAVA_LANG_PATTERN_INTERNAL = Pattern.compile("^java/lang/(.*)"); public static final Pattern SANDBOX_PATTERN_INTERNAL = Pattern.compile("^" + SANDBOX_PREFIX_INTERNAL + "(.*)"); @@ -28,13 +27,13 @@ public final class Utils { public static final Pattern CLASSNAME_PATTERN_QUALIFIED = Pattern.compile("([^\\.]+)\\."); public static final String OBJECT = "java/lang/Object"; - + public static final String THROWABLE = "java/lang/Throwable"; - + public static final String ERROR = "java/lang/Error"; - + public static final String THREAD_DEATH = "java/lang/ThreadDeath"; - + // Hide constructor private Utils() { } @@ -43,6 +42,7 @@ public final class Utils { * Helper method that converts from the internal class name format (as used in the * Constant Pool) to a fully-qualified class name. No obvious library method to do this * appears to exist, hence this code. If one exists, rip this out. + * * @param classInternalName * @return */ @@ -52,12 +52,11 @@ public final class Utils { } /** - * This method takes in an internal method name but needs to return a qualified + * This method takes in an internal method name but needs to return a qualified * classname (suitable for loading) - * - * + * * @param internalMethodName - * @return + * @return */ public static String convertInternalMethodNameToQualifiedClassName(final String internalMethodName) { final Matcher classMatch = CLASSNAME_PATTERN_QUALIFIED.matcher(internalMethodName); @@ -72,6 +71,7 @@ public final class Utils { * Helper method that converts from a fully-qualified class name to the internal class * name format (as used in the Constant Pool). No obvious library method to do this * appears to exist, hence this code. If one exists, rip this out. + * * @param qualifiedClassName * @return */ @@ -81,7 +81,7 @@ public final class Utils { } /** - * This method potentially rewrites the classname. + * This method potentially rewrites the classname. * * @param internalClassname - specified in internal form * @return @@ -102,9 +102,8 @@ public final class Utils { } /** - * * @param qualifiedTypeName - * @return + * @return */ public static String sandboxQualifiedTypeName(final String qualifiedTypeName) { final String internal = convertQualifiedClassNameToInternalForm(qualifiedTypeName); @@ -118,7 +117,7 @@ public final class Utils { /** * This method removes the sandboxing prefix from a method or type name, if it has * one, otherwise it returns the input string. - * + * * @param internalClassname * @return the internal classname, unsandboxed if that was required */ @@ -131,7 +130,6 @@ public final class Utils { } /** - * * @param desc - internal * @return the rewritten desc string */ @@ -169,9 +167,9 @@ public final class Utils { * loading. This should not attempt to load a classname that starts with java. as * the only permissable classes have already been transformed into sandboxed * methods - * + * * @param qualifiedClassName - * @return + * @return */ public static boolean shouldAttemptToTransitivelyLoad(final String qualifiedClassName) { return !JAVA_PATTERN_QUALIFIED.asPredicate().test(qualifiedClassName); @@ -179,7 +177,7 @@ public final class Utils { /** * Helper method that determines whether this class requires sandboxing - * + * * @param clazzName - specified in internal form * @return true if the class should be sandboxed */ diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/WhitelistClassLoader.java b/experimental/sandbox/src/main/java/net/corda/sandbox/WhitelistClassLoader.java index 171c2770f9..2a99ffbdca 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/WhitelistClassLoader.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/WhitelistClassLoader.java @@ -2,6 +2,7 @@ package net.corda.sandbox; import net.corda.sandbox.visitors.CostInstrumentingMethodVisitor; import net.corda.sandbox.visitors.WhitelistCheckingClassVisitor; + import java.io.IOException; import java.io.InputStream; import java.net.URI; @@ -9,13 +10,13 @@ import java.net.URISyntaxException; import java.net.URL; import java.nio.file.*; import java.util.*; + import org.objectweb.asm.*; import org.objectweb.asm.commons.ClassRemapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * * @author ben */ public final class WhitelistClassLoader extends ClassLoader { @@ -61,8 +62,8 @@ public final class WhitelistClassLoader extends ClassLoader { } /** - * Static factory method. Throws URISyntaxException currently, as this method is - * called with user data, so a checked exception is not unreasonable. Could use a + * Static factory method. Throws URISyntaxException currently, as this method is + * called with user data, so a checked exception is not unreasonable. Could use a * runtime exception instead. * * @param auxiliaryClassPath @@ -70,7 +71,7 @@ public final class WhitelistClassLoader extends ClassLoader { * methods to be deterministic, instead the classloader * will remove all non-deterministic methods. * @return a suitably constructed whitelisting classloader - * @throws URISyntaxException + * @throws URISyntaxException */ public static WhitelistClassLoader of(final String auxiliaryClassPath, final boolean stripNonDeterministic) throws URISyntaxException { final WhitelistClassLoader out = new WhitelistClassLoader(stripNonDeterministic); @@ -96,10 +97,10 @@ public final class WhitelistClassLoader extends ClassLoader { /** * Static factory method. Used for recursive classloading - * + * * @param other * @return a suitably constructed whitelisting classloader based on the state - * of the passed classloader + * of the passed classloader */ public static WhitelistClassLoader of(final WhitelistClassLoader other) { final WhitelistClassLoader out = new WhitelistClassLoader(other); @@ -110,7 +111,7 @@ public final class WhitelistClassLoader extends ClassLoader { /** * Helper method that adds a jar to the path to be searched * - * @param knownGoodJar + * @param knownGoodJar */ void addJarToSandbox(final Path knownGoodJar) { fileSystemSearchPath.add(knownGoodJar); @@ -120,9 +121,9 @@ public final class WhitelistClassLoader extends ClassLoader { * Setup the auxiliary classpath so that classes that are not on the original * classpath can be scanned for. * Note that this this method hardcodes Unix conventions, so won't work on e.g. Windows - * + * * @param auxiliaryClassPath - * @throws URISyntaxException + * @throws URISyntaxException */ void setupClasspath(final String auxiliaryClassPath) throws URISyntaxException { for (String entry : auxiliaryClassPath.split(":")) { @@ -136,11 +137,10 @@ public final class WhitelistClassLoader extends ClassLoader { } /** - * * @param qualifiedClassName * @return a class object that has been whitelist checked and is known to be - * deterministic - * @throws ClassNotFoundException + * deterministic + * @throws ClassNotFoundException */ @Override public Class findClass(final String qualifiedClassName) throws ClassNotFoundException { @@ -244,10 +244,10 @@ public final class WhitelistClassLoader extends ClassLoader { * around a limitation of the ASM library that does not integrate cleanly with Java 7 * NIO.2 Path APIs. This method also performs a couple of basic sanity check on the * class file (e.g. that it exists, is a regular file and is readable). - * + * * @param internalClassName * @return a path object that corresponds to a class that has been found - * @throws ClassNotFoundException + * @throws ClassNotFoundException */ Path locateClassfileDir(final String internalClassName) throws ClassNotFoundException { // Check the primaryClasspathSearchPath @@ -300,7 +300,7 @@ public final class WhitelistClassLoader extends ClassLoader { /** * Creates a jar archive of all the transformed classes that this classloader * has loaded. - * + * * @return true on success, false on failure * @throws java.io.IOException * @throws java.net.URISyntaxException @@ -328,7 +328,8 @@ public final class WhitelistClassLoader extends ClassLoader { /** * Getter method for the reason for failure - * @return + * + * @return */ public WhitelistClassloadingException reason() { return candidacyStatus.getReason(); @@ -336,7 +337,8 @@ public final class WhitelistClassLoader extends ClassLoader { /** * Getter method for the method candidacy status - * @return + * + * @return */ public CandidacyStatus getCandidacyStatus() { return candidacyStatus; diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/WhitelistClassloadingException.java b/experimental/sandbox/src/main/java/net/corda/sandbox/WhitelistClassloadingException.java index 5f6c13ca9f..9705d4bf0e 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/WhitelistClassloadingException.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/WhitelistClassloadingException.java @@ -4,7 +4,7 @@ package net.corda.sandbox; * */ public class WhitelistClassloadingException extends Exception { - + public WhitelistClassloadingException() { super(); } @@ -22,10 +22,10 @@ public class WhitelistClassloadingException extends Exception { } protected WhitelistClassloadingException(String message, Throwable cause, - boolean enableSuppression, - boolean writableStackTrace) { + boolean enableSuppression, + boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } - + } diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/costing/Contract.java b/experimental/sandbox/src/main/java/net/corda/sandbox/costing/Contract.java index ec098ecfbd..f20aaa0b79 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/costing/Contract.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/costing/Contract.java @@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory; /** * This class is the runtime representation of a running contract. - * + * * @author ben */ public class Contract { diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/costing/ContractExecutor.java b/experimental/sandbox/src/main/java/net/corda/sandbox/costing/ContractExecutor.java index 243a3ddf11..5b719978a4 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/costing/ContractExecutor.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/costing/ContractExecutor.java @@ -3,17 +3,17 @@ package net.corda.sandbox.costing; /** * This interface is to decouple the actual executable code from the entry point and * how vetted deterministic code will be used inside the sandbox - * + * * @author ben */ public interface ContractExecutor { /** * Executes a smart contract - * + * * @param contract the contract to be executed */ void execute(Contract contract); - + /** * Checks to see if the supplied Contract is suitable * diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/costing/RuntimeCostAccounter.java b/experimental/sandbox/src/main/java/net/corda/sandbox/costing/RuntimeCostAccounter.java index f00c39defa..7274d914c7 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/costing/RuntimeCostAccounter.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/costing/RuntimeCostAccounter.java @@ -4,7 +4,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * * @author ben */ public class RuntimeCostAccounter { diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/tools/SandboxCreator.java b/experimental/sandbox/src/main/java/net/corda/sandbox/tools/SandboxCreator.java index 01b0906dc2..33ab308a2e 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/tools/SandboxCreator.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/tools/SandboxCreator.java @@ -2,6 +2,7 @@ package net.corda.sandbox.tools; import net.corda.sandbox.WhitelistClassLoader; import net.corda.sandbox.visitors.SandboxPathVisitor; + import java.io.FileInputStream; import java.io.IOException; import java.net.URISyntaxException; @@ -18,7 +19,6 @@ import joptsimple.OptionSet; * This class takes in an exploded set of JRE classes, and a whitelist, and rewrites all * classes (note: not methods) that have at least one whitelisted method to create a * sandboxed version of the class. - * */ // java8.scan.java.lang_and_util java8.interfaces_for_compat java8 sandbox public final class SandboxCreator { @@ -30,7 +30,7 @@ public final class SandboxCreator { private final String outputJarName; private final WhitelistClassLoader wlcl; private final boolean hasInputJar; - + private final static OptionParser parser = new OptionParser(); private static void usage() { @@ -53,7 +53,7 @@ public final class SandboxCreator { static String unpackJar(final String zipFilePath) throws IOException { final Path tmpDir = Files.createTempDirectory(Paths.get("/tmp"), "wlcl-extract"); - + try (final ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath))) { ZipEntry entry = zipIn.getNextEntry(); @@ -68,13 +68,13 @@ public final class SandboxCreator { entry = zipIn.getNextEntry(); } } - + return tmpDir.toString(); } - + void cleanup() { if (hasInputJar) { - + } } @@ -107,10 +107,9 @@ public final class SandboxCreator { } /** - * * @param basePath * @param packageName - * @throws IOException + * @throws IOException */ void walk() throws IOException { final Path scanDir = Paths.get(basePathName); diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/CostInstrumentingMethodVisitor.java b/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/CostInstrumentingMethodVisitor.java index 5f7dc3fdea..8b108fed89 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/CostInstrumentingMethodVisitor.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/CostInstrumentingMethodVisitor.java @@ -9,7 +9,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * * @author ben */ public final class CostInstrumentingMethodVisitor extends GeneratorAdapter { @@ -34,9 +33,10 @@ public final class CostInstrumentingMethodVisitor extends GeneratorAdapter { } /** - * This method replaces MONITORENTER / MONITOREXIT opcodes with POP - basically + * This method replaces MONITORENTER / MONITOREXIT opcodes with POP - basically * stripping the synchronization out of any sandboxed code. - * @param opcode + * + * @param opcode */ @Override public void visitInsn(final int opcode) { @@ -60,7 +60,7 @@ public final class CostInstrumentingMethodVisitor extends GeneratorAdapter { * For our purposes this is a NEWARRAY opcode. * * @param opcode - * @param operand + * @param operand */ @Override public void visitIntInsn(final int opcode, final int operand) { @@ -103,11 +103,11 @@ public final class CostInstrumentingMethodVisitor extends GeneratorAdapter { /** * This method is called when visiting an opcode with a single operand, that * is a type (represented here as a String). - * + *

* For our purposes this is either a NEW opcode or a ANEWARRAY * - * @param opcode - * @param type + * @param opcode + * @param type */ @Override public void visitTypeInsn(final int opcode, final String type) { diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/DefinitelyDisallowedMethodVisitor.java b/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/DefinitelyDisallowedMethodVisitor.java index 62b882f269..d4ade3415a 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/DefinitelyDisallowedMethodVisitor.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/DefinitelyDisallowedMethodVisitor.java @@ -11,5 +11,5 @@ class DefinitelyDisallowedMethodVisitor extends MethodVisitor { DefinitelyDisallowedMethodVisitor(MethodVisitor baseMethodVisitor) { super(Opcodes.ASM5, baseMethodVisitor); } - + } diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/SandboxPathVisitor.java b/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/SandboxPathVisitor.java index bdc81bf995..e5528acbd9 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/SandboxPathVisitor.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/SandboxPathVisitor.java @@ -2,15 +2,17 @@ package net.corda.sandbox.visitors; import net.corda.sandbox.Utils; import net.corda.sandbox.WhitelistClassLoader; + import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This helper class visits each file (represented as a Path) in some directory * tree containing classes to be sandboxed. - * + * * @author ben */ public final class SandboxPathVisitor extends SimpleFileVisitor { @@ -30,10 +32,10 @@ public final class SandboxPathVisitor extends SimpleFileVisitor { public FileVisitResult visitFile(final Path path, final BasicFileAttributes attr) { // Check that this is a class file if (!path.toString().matches(Utils.CLASSFILE_NAME_SUFFIX)) { - System.out.println("Skipping: "+ path); + System.out.println("Skipping: " + path); return FileVisitResult.CONTINUE; } - + // Check to see if this path corresponds to an allowedClass final String classFileName = startFrom.relativize(path).toString().replace(".class", ""); diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/WhitelistCheckingClassVisitor.java b/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/WhitelistCheckingClassVisitor.java index 5994b445a6..534c89bc6b 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/WhitelistCheckingClassVisitor.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/WhitelistCheckingClassVisitor.java @@ -2,10 +2,12 @@ package net.corda.sandbox.visitors; import net.corda.sandbox.WhitelistClassLoader; import net.corda.sandbox.CandidacyStatus; + import java.util.Arrays; import net.corda.sandbox.CandidateMethod; import net.corda.sandbox.Utils; + import java.util.HashSet; import java.util.Set; @@ -14,6 +16,7 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import static org.objectweb.asm.Opcodes.*; /** @@ -57,7 +60,7 @@ public final class WhitelistCheckingClassVisitor extends ClassVisitor { /** * We initially take the method passed in and store an internal representation of * the method signature in the our CandidacyStatus working set. - * + *

* We then get an ASM MethodVisitor (which can read the byte code of the method) and pass that to our * custom method visitor which perform additional checks. * @@ -66,7 +69,7 @@ public final class WhitelistCheckingClassVisitor extends ClassVisitor { * @param desc * @param signature * @param exceptions - * @return + * @return */ @Override public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { @@ -77,7 +80,7 @@ public final class WhitelistCheckingClassVisitor extends ClassVisitor { // Force new access control flags - for now just strictfp for deterministic // compliance to IEEE 754 final int maskedAccess = access | ACC_STRICT; - + final String internalName = classname + "." + name + ":" + desc; internalMethodNames.add(internalName); candidacyStatus.putIfAbsent(internalName); @@ -151,10 +154,10 @@ public final class WhitelistCheckingClassVisitor extends ClassVisitor { } /** - * Take the name of a class and attempts to load it using a WLCL. - * + * Take the name of a class and attempts to load it using a WLCL. + * * @param qualifiedClassname - * @return + * @return */ CandidateMethod.State resolveState(final String qualifiedClassname) { Class clz = null; diff --git a/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/WhitelistCheckingMethodVisitor.java b/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/WhitelistCheckingMethodVisitor.java index 28338f5285..0d392f342b 100644 --- a/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/WhitelistCheckingMethodVisitor.java +++ b/experimental/sandbox/src/main/java/net/corda/sandbox/visitors/WhitelistCheckingMethodVisitor.java @@ -13,7 +13,6 @@ import org.objectweb.asm.Label; /** * A MethodVisitor which checks method instructions in order to determine if this * method is deterministic or not - * */ final class WhitelistCheckingMethodVisitor extends MethodVisitor { @@ -29,7 +28,7 @@ final class WhitelistCheckingMethodVisitor extends MethodVisitor { } /** - * Visits a method instruction. A method instruction is an instruction that + * Visits a method instruction. A method instruction is an instruction that * invokes a method. *

* Some method instructions are by their nature un-deterministic, so we set those methods to have a @@ -84,15 +83,15 @@ final class WhitelistCheckingMethodVisitor extends MethodVisitor { } /** - * Currently a no-op. - * + * Currently a no-op. + *

* The JVMspec seems to permit the possibility of using a backwards branch in a - * tableswitch to try to create an infinite loop. However, it seems to be + * tableswitch to try to create an infinite loop. However, it seems to be * impossible in practice - the specification of StackMapFrame seems to prevent * it in modern classfile formats, and even by explicitly generating a version * 49 (Java 5) classfile, the verifier seems to be specifically resistant to a - * backwards branch from a tableswitch. - * + * backwards branch from a tableswitch. + *

* We could still add a belt-and-braces static instrumentation to protect * against this but it currently seems unnecessary - at worse it is a branch that * should count against the branch limit, or an explicit disallow of a backwards @@ -102,7 +101,7 @@ final class WhitelistCheckingMethodVisitor extends MethodVisitor { * @param min * @param max * @param dflt - * @param labels + * @param labels */ @Override public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { @@ -112,11 +111,11 @@ final class WhitelistCheckingMethodVisitor extends MethodVisitor { /** * Visits an invokedynamic instruction - which is specifically disallowed for * deterministic apps. - * + * * @param name * @param desc * @param bsm - * @param bsmArgs + * @param bsmArgs */ @Override public void visitInvokeDynamicInsn(final String name, final String desc, final Handle bsm, final Object... bsmArgs) { diff --git a/experimental/sandbox/src/main/java/sandbox/net/corda/sandbox/costing/RuntimeCostAccounter.java b/experimental/sandbox/src/main/java/sandbox/net/corda/sandbox/costing/RuntimeCostAccounter.java index 7acc1f445d..22e895c41b 100644 --- a/experimental/sandbox/src/main/java/sandbox/net/corda/sandbox/costing/RuntimeCostAccounter.java +++ b/experimental/sandbox/src/main/java/sandbox/net/corda/sandbox/costing/RuntimeCostAccounter.java @@ -4,7 +4,7 @@ package sandbox.net.corda.sandbox.costing; * A helper class that just forwards any static sandboxed calls to the real runtime * cost accounting class. This removes the need to special case the accounting * method calls during rewriting of method names - * + * * @author ben */ public class RuntimeCostAccounter { diff --git a/experimental/sandbox/src/test/java/net/corda/sandbox/TestUtils.java b/experimental/sandbox/src/test/java/net/corda/sandbox/TestUtils.java index d8e0fd0007..16cbda6e84 100644 --- a/experimental/sandbox/src/test/java/net/corda/sandbox/TestUtils.java +++ b/experimental/sandbox/src/test/java/net/corda/sandbox/TestUtils.java @@ -22,7 +22,7 @@ public class TestUtils { // Copy resource jar to tmp dir tmpdir = Files.createTempDirectory("wlcl-tmp-test"); Path copiedJar = tmpdir.resolve("tmp-resource.jar"); - try(final InputStream in = TestUtils.class.getResourceAsStream(resourcePathToJar)) { + try (final InputStream in = TestUtils.class.getResourceAsStream(resourcePathToJar)) { Files.copy(in, copiedJar, StandardCopyOption.REPLACE_EXISTING); } final FileSystem fs = FileSystems.newFileSystem(copiedJar, null); @@ -33,20 +33,20 @@ public class TestUtils { public static Path copySandboxJarToTmpDir(final String resourcePathToJar) throws IOException { Path sandboxJar = tmpdir.resolve("tmp-sandbox.jar"); - try(final InputStream in = TestUtils.class.getResourceAsStream(resourcePathToJar)) { + try (final InputStream in = TestUtils.class.getResourceAsStream(resourcePathToJar)) { Files.copy(in, sandboxJar, StandardCopyOption.REPLACE_EXISTING); } final FileSystem sandboxFs = FileSystems.newFileSystem(sandboxJar, null); tmpFileSystems.add(sandboxFs); return sandboxFs.getRootDirectories().iterator().next(); } - + public static Path getJarFSRoot() { return jarFSDir; } public static void cleanupTmpJar() throws IOException { - for (FileSystem fs: tmpFileSystems) { + for (FileSystem fs : tmpFileSystems) { fs.close(); } tmpFileSystems.clear(); @@ -92,15 +92,15 @@ public class TestUtils { // Helper for finding the correct offsets if they change public static void printBytes(byte[] data) { byte[] datum = new byte[1]; - for (int i=0; i < data.length; i++) { + for (int i = 0; i < data.length; i++) { datum[0] = data[i]; - System.out.println(i +" : "+ DatatypeConverter.printHexBinary(datum)); + System.out.println(i + " : " + DatatypeConverter.printHexBinary(datum)); } } public static int findOffset(byte[] classBytes, byte[] originalSeq) { int offset = 0; - for (int i=415; i < classBytes.length; i++) { + for (int i = 415; i < classBytes.length; i++) { if (classBytes[i] != originalSeq[offset]) { offset = 0; continue; @@ -110,7 +110,7 @@ public class TestUtils { } offset++; } - + return -1; } @@ -119,7 +119,7 @@ public class TestUtils { return wlcl.instrumentWithCosts(basic, hashSet); } - + public static final class MyClassloader extends ClassLoader { public Class byPath(Path p) throws IOException { diff --git a/experimental/sandbox/src/test/java/net/corda/sandbox/WhitelistClassLoaderTest.java b/experimental/sandbox/src/test/java/net/corda/sandbox/WhitelistClassLoaderTest.java index 91d455b0d2..bcc5e94172 100644 --- a/experimental/sandbox/src/test/java/net/corda/sandbox/WhitelistClassLoaderTest.java +++ b/experimental/sandbox/src/test/java/net/corda/sandbox/WhitelistClassLoaderTest.java @@ -1,10 +1,13 @@ package net.corda.sandbox; import static org.junit.Assert.*; + import org.junit.Test; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.concurrent.atomic.AtomicBoolean; + import org.junit.*; public class WhitelistClassLoaderTest { @@ -123,8 +126,8 @@ public class WhitelistClassLoaderTest { final Class clz = wlcl.loadClass("resource.ThrowExceptions"); assertNotNull("ThrowExceptions class could not be transformed and loaded", clz); } - - + + // TODO Test cases that terminate when other resource limits are broken @Test public void when_too_much_memory_is_allocated_then_thread_dies() throws Exception { diff --git a/experimental/sandbox/src/test/java/net/corda/sandbox/costing/DeterministicClassInstrumenterTest.java b/experimental/sandbox/src/test/java/net/corda/sandbox/costing/DeterministicClassInstrumenterTest.java index c276907870..15130086d3 100644 --- a/experimental/sandbox/src/test/java/net/corda/sandbox/costing/DeterministicClassInstrumenterTest.java +++ b/experimental/sandbox/src/test/java/net/corda/sandbox/costing/DeterministicClassInstrumenterTest.java @@ -11,7 +11,6 @@ import java.util.*; import static org.junit.Assert.*; /** - * * @author ben */ public class DeterministicClassInstrumenterTest { @@ -66,7 +65,7 @@ public class DeterministicClassInstrumenterTest { // TestUtils.printBytes(basic); final int origOffset = TestUtils.findOffset(basic, originalSeq); final int tmfdOffset = TestUtils.findOffset(tfmd, tfmdSeq); - + for (int i = 0; i < originalSeq.length; i++) { assertEquals(originalSeq[i], basic[origOffset + i]); assertEquals(tfmdSeq[i], tfmd[tmfdOffset + i]); diff --git a/experimental/sandbox/src/test/java/net/corda/sandbox/costing/SandboxedRewritingTest.java b/experimental/sandbox/src/test/java/net/corda/sandbox/costing/SandboxedRewritingTest.java index 15bd7dafe2..16b3972390 100644 --- a/experimental/sandbox/src/test/java/net/corda/sandbox/costing/SandboxedRewritingTest.java +++ b/experimental/sandbox/src/test/java/net/corda/sandbox/costing/SandboxedRewritingTest.java @@ -1,19 +1,24 @@ package net.corda.sandbox.costing; import net.corda.sandbox.TestUtils; + import static net.corda.sandbox.TestUtils.*; + import net.corda.sandbox.Utils; + import java.io.IOException; import java.lang.reflect.Method; import java.net.URISyntaxException; + import org.junit.AfterClass; import org.junit.Test; + import static org.junit.Assert.*; + import org.junit.Before; import org.junit.BeforeClass; /** - * * @author ben */ public class SandboxedRewritingTest { diff --git a/experimental/sandbox/src/test/java/sandbox/greymalkin/StringReturner.java b/experimental/sandbox/src/test/java/sandbox/greymalkin/StringReturner.java index e0aee3b576..d34132570e 100644 --- a/experimental/sandbox/src/test/java/sandbox/greymalkin/StringReturner.java +++ b/experimental/sandbox/src/test/java/sandbox/greymalkin/StringReturner.java @@ -1,7 +1,6 @@ package sandbox.greymalkin; /** - * * @author ben */ // Simple hack for now, generalise to lambdas later... diff --git a/finance/src/main/java/net/corda/finance/contracts/JavaCommercialPaper.java b/finance/src/main/java/net/corda/finance/contracts/JavaCommercialPaper.java index 02bf2bbd45..221e02427c 100644 --- a/finance/src/main/java/net/corda/finance/contracts/JavaCommercialPaper.java +++ b/finance/src/main/java/net/corda/finance/contracts/JavaCommercialPaper.java @@ -101,9 +101,7 @@ public class JavaCommercialPaper implements Contract { if (issuance != null ? !issuance.equals(state.issuance) : state.issuance != null) return false; if (owner != null ? !owner.equals(state.owner) : state.owner != null) return false; if (faceValue != null ? !faceValue.equals(state.faceValue) : state.faceValue != null) return false; - if (maturityDate != null ? !maturityDate.equals(state.maturityDate) : state.maturityDate != null) - return false; - return true; + return maturityDate != null ? maturityDate.equals(state.maturityDate) : state.maturityDate == null; } @Override diff --git a/finance/src/main/kotlin/net/corda/finance/Currencies.kt b/finance/src/main/kotlin/net/corda/finance/Currencies.kt index 906e01d8af..75bb50cd83 100644 --- a/finance/src/main/kotlin/net/corda/finance/Currencies.kt +++ b/finance/src/main/kotlin/net/corda/finance/Currencies.kt @@ -8,12 +8,18 @@ import net.corda.core.contracts.PartyAndReference import java.math.BigDecimal import java.util.* -@JvmField val USD: Currency = Currency.getInstance("USD") -@JvmField val GBP: Currency = Currency.getInstance("GBP") -@JvmField val EUR: Currency = Currency.getInstance("EUR") -@JvmField val CHF: Currency = Currency.getInstance("CHF") -@JvmField val JPY: Currency = Currency.getInstance("JPY") -@JvmField val RUB: Currency = Currency.getInstance("RUB") +@JvmField +val USD: Currency = Currency.getInstance("USD") +@JvmField +val GBP: Currency = Currency.getInstance("GBP") +@JvmField +val EUR: Currency = Currency.getInstance("EUR") +@JvmField +val CHF: Currency = Currency.getInstance("CHF") +@JvmField +val JPY: Currency = Currency.getInstance("JPY") +@JvmField +val RUB: Currency = Currency.getInstance("RUB") fun AMOUNT(amount: Int, token: T): Amount = AMOUNT(amount.toLong(), token) fun AMOUNT(amount: Long, token: T): Amount = Amount.fromDecimal(BigDecimal.valueOf(amount), token) diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/CommercialPaper.kt b/finance/src/main/kotlin/net/corda/finance/contracts/CommercialPaper.kt index f7fcdc3e69..1c302480f3 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/CommercialPaper.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/CommercialPaper.kt @@ -49,6 +49,7 @@ class CommercialPaper : Contract { companion object { const val CP_PROGRAM_ID: ContractClassName = "net.corda.finance.contracts.CommercialPaper" } + data class State( val issuance: PartyAndReference, override val owner: AbstractParty, @@ -89,7 +90,8 @@ class CommercialPaper : Contract { } } - /** @suppress */ infix fun `owned by`(owner: AbstractParty) = copy(owner = owner) + /** @suppress */ + infix fun `owned by`(owner: AbstractParty) = copy(owner = owner) } interface Commands : CommandData { diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/FinanceTypes.kt b/finance/src/main/kotlin/net/corda/finance/contracts/FinanceTypes.kt index 1079beeccc..be6ada5492 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/FinanceTypes.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/FinanceTypes.kt @@ -202,7 +202,7 @@ enum class Frequency(val annualCompoundCount: Int, val offset: LocalDate.(Long) * no staff are around to handle problems. */ @CordaSerializable -open class BusinessCalendar (val holidayDates: List) { +open class BusinessCalendar(val holidayDates: List) { @CordaSerializable class UnknownCalendar(name: String) : FlowException("$name not found") diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/Cash.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/Cash.kt index 9a578b7ff2..13e1725c09 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/Cash.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/Cash.kt @@ -401,10 +401,17 @@ class Cash : OnLedgerAsset() { // Small DSL extensions. -/** @suppress */ infix fun Cash.State.`owned by`(owner: AbstractParty) = ownedBy(owner) -/** @suppress */ infix fun Cash.State.`issued by`(party: AbstractParty) = issuedBy(party) -/** @suppress */ infix fun Cash.State.`issued by`(deposit: PartyAndReference) = issuedBy(deposit) -/** @suppress */ infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State = withDeposit(deposit) +/** @suppress */ +infix fun Cash.State.`owned by`(owner: AbstractParty) = ownedBy(owner) + +/** @suppress */ +infix fun Cash.State.`issued by`(party: AbstractParty) = issuedBy(party) + +/** @suppress */ +infix fun Cash.State.`issued by`(deposit: PartyAndReference) = issuedBy(deposit) + +/** @suppress */ +infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State = withDeposit(deposit) // Unit testing helpers. These could go in a separate file but it's hardly worth it for just a few functions. diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/CommodityContract.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/CommodityContract.kt index bf31292c69..052223b7e4 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/CommodityContract.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/CommodityContract.kt @@ -44,6 +44,7 @@ class CommodityContract : OnLedgerAsset { constructor(deposit: PartyAndReference, amount: Amount, owner: AbstractParty) : this(Amount(amount.quantity, Issued(deposit, amount.token)), owner) + override val exitKeys: Set = Collections.singleton(owner.owningKey) override val participants = listOf(owner) @@ -91,7 +92,7 @@ class CommodityContract : OnLedgerAsset().firstOrNull() @@ -107,7 +108,7 @@ class CommodityContract : OnLedgerAsset : Contract { companion object { const val PROGRAM_ID: ContractClassName = "net.corda.finance.contracts.asset.Obligation" } + /** * Represents where in its lifecycle a contract state is, which in turn controls the commands that can be applied * to the state. Most states will not leave the [NORMAL] lifecycle. Note that settled (as an end lifecycle) is @@ -191,7 +192,7 @@ class Obligation

: Contract { */ data class Move(override val contract: Class? = null) : MoveCommand - /** + /** * Allows new obligation states to be issued into existence. */ class Issue : TypeOnlyCommandData() @@ -453,7 +454,7 @@ class Obligation

: Contract { requireThat { "there is a time-window from the authority" using (timeWindow != null) - "the due date has passed" using (timeWindow!!.fromTime?.isAfter(deadline) ?: false) + "the due date has passed" using (timeWindow!!.fromTime?.isAfter(deadline) == true) "input state lifecycle is correct" using (input.lifecycle == expectedInputLifecycle) "output state corresponds exactly to input state, with lifecycle changed" using (expectedOutput == actualOutput) } @@ -785,9 +786,11 @@ infix fun Obligation.State.between(parties: Pair Obligation.State.`owned by`(owner: AbstractParty) = copy(beneficiary = owner) infix fun Obligation.State.`issued by`(party: AbstractParty) = copy(obligor = party) // For Java users: -@Suppress("unused") fun Obligation.State.ownedBy(owner: AbstractParty) = copy(beneficiary = owner) +@Suppress("unused") +fun Obligation.State.ownedBy(owner: AbstractParty) = copy(beneficiary = owner) -@Suppress("unused") fun Obligation.State.issuedBy(party: AnonymousParty) = copy(obligor = party) +@Suppress("unused") +fun Obligation.State.issuedBy(party: AnonymousParty) = copy(obligor = party) /** A randomly generated key. */ val DUMMY_OBLIGATION_ISSUER_KEY by lazy { entropyToKeyPair(BigInteger.valueOf(10)) } diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/OnLedgerAsset.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/OnLedgerAsset.kt index 7042f3a94f..9f93a80a8c 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/OnLedgerAsset.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/OnLedgerAsset.kt @@ -55,13 +55,13 @@ abstract class OnLedgerAsset> : C */ @Throws(InsufficientBalanceException::class) @JvmStatic - fun , T: Any> generateSpend(tx: TransactionBuilder, - amount: Amount, - to: AbstractParty, - acceptableStates: List>, - payChangeTo: AbstractParty, - deriveState: (TransactionState, Amount>, AbstractParty) -> TransactionState, - generateMoveCommand: () -> CommandData): Pair> { + fun , T : Any> generateSpend(tx: TransactionBuilder, + amount: Amount, + to: AbstractParty, + acceptableStates: List>, + payChangeTo: AbstractParty, + deriveState: (TransactionState, Amount>, AbstractParty) -> TransactionState, + generateMoveCommand: () -> CommandData): Pair> { return generateSpend(tx, listOf(PartyAndAmount(to, amount)), acceptableStates, payChangeTo, deriveState, generateMoveCommand) } @@ -91,12 +91,12 @@ abstract class OnLedgerAsset> : C */ @Throws(InsufficientBalanceException::class) @JvmStatic - fun , T: Any> generateSpend(tx: TransactionBuilder, - payments: List>, - acceptableStates: List>, - payChangeTo: AbstractParty, - deriveState: (TransactionState, Amount>, AbstractParty) -> TransactionState, - generateMoveCommand: () -> CommandData): Pair> { + fun , T : Any> generateSpend(tx: TransactionBuilder, + payments: List>, + acceptableStates: List>, + payChangeTo: AbstractParty, + deriveState: (TransactionState, Amount>, AbstractParty) -> TransactionState, + generateMoveCommand: () -> CommandData): Pair> { // Discussion // // This code is analogous to the Wallet.send() set of methods in bitcoinj, and has the same general outline. @@ -230,11 +230,11 @@ abstract class OnLedgerAsset> : C */ @Throws(InsufficientBalanceException::class) @JvmStatic - fun , T: Any> generateExit(tx: TransactionBuilder, amountIssued: Amount>, - assetStates: List>, - deriveState: (TransactionState, Amount>, AbstractParty) -> TransactionState, - generateMoveCommand: () -> CommandData, - generateExitCommand: (Amount>) -> CommandData): Set { + fun , T : Any> generateExit(tx: TransactionBuilder, amountIssued: Amount>, + assetStates: List>, + deriveState: (TransactionState, Amount>, AbstractParty) -> TransactionState, + generateMoveCommand: () -> CommandData, + generateExitCommand: (Amount>) -> CommandData): Set { val owner = assetStates.map { it.state.data.owner }.toSet().singleOrNull() ?: throw InsufficientBalanceException(amountIssued) val currency = amountIssued.token.product val amount = Amount(amountIssued.quantity, currency) @@ -272,9 +272,9 @@ abstract class OnLedgerAsset> : C * wrappers around this function, which build the state for you, and those should be used in preference. */ @JvmStatic - fun , T: Any> generateIssue(tx: TransactionBuilder, - transactionState: TransactionState, - issueCommand: CommandData): Set { + fun , T : Any> generateIssue(tx: TransactionBuilder, + transactionState: TransactionState, + issueCommand: CommandData): Set { check(tx.inputStates().isEmpty()) check(tx.outputStates().map { it.data }.filterIsInstance(transactionState.javaClass).isEmpty()) require(transactionState.data.amount.quantity > 0) diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt index 7c18981857..a447827205 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt @@ -54,11 +54,11 @@ class CashSelectionH2Impl : CashSelection { */ @Suspendable override fun unconsumedCashStatesForSpending(services: ServiceHub, - amount: Amount, - onlyFromIssuerParties: Set, - notary: Party?, - lockId: UUID, - withIssuerRefs: Set): List> { + amount: Amount, + onlyFromIssuerParties: Set, + notary: Party?, + lockId: UUID, + withIssuerRefs: Set): List> { val issuerKeysStr = onlyFromIssuerParties.fold("") { left, right -> left + "('${right.owningKey.toBase58String()}')," }.dropLast(1) val issuerRefsStr = withIssuerRefs.fold("") { left, right -> left + "('${right.bytes.toHexString()}')," }.dropLast(1) diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionMySQLImpl.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionMySQLImpl.kt index 73a49e8a18..1a0eac0169 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionMySQLImpl.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionMySQLImpl.kt @@ -29,4 +29,4 @@ class CashSelectionMySQLImpl : CashSelection { withIssuerRefs: Set): List> { TODO("MySQL cash selection not implemented") } - } \ No newline at end of file +} \ No newline at end of file diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt index f0084fb169..c978ded6f0 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt @@ -60,7 +60,7 @@ class CashExitFlow(private val amount: Amount, // Work out who the owners of the burnt states were (specify page size so we don't silently drop any if > DEFAULT_PAGE_SIZE) val inputStates = serviceHub.vaultService.queryBy(VaultQueryCriteria(stateRefs = builder.inputStates()), - PageSpecification(pageNumber = DEFAULT_PAGE_NUM, pageSize = builder.inputStates().size)).states + PageSpecification(pageNumber = DEFAULT_PAGE_NUM, pageSize = builder.inputStates().size)).states // TODO: Is it safe to drop participants we don't know how to contact? Does not knowing how to contact them // count as a reason to fail? diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashIssueAndPaymentFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashIssueAndPaymentFlow.kt index 48f0f43c4a..95a58e8cfb 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/CashIssueAndPaymentFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashIssueAndPaymentFlow.kt @@ -32,6 +32,7 @@ class CashIssueAndPaymentFlow(val amount: Amount, recipient: Party, anonymous: Boolean, notary: Party) : this(amount, issueRef, recipient, anonymous, notary, tracker()) + constructor(request: IssueAndPaymentRequest) : this(request.amount, request.issueRef, request.recipient, request.anonymous, request.notary, tracker()) @Suspendable diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt index 56f071783a..39ef76823b 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt @@ -31,6 +31,7 @@ class CashIssueFlow(private val amount: Amount, constructor(amount: Amount, issuerBankPartyRef: OpaqueBytes, notary: Party) : this(amount, issuerBankPartyRef, notary, tracker()) + constructor(request: IssueRequest) : this(request.amount, request.issueRef, request.notary, tracker()) @Suspendable diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt index 8857835da2..dc71e54884 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt @@ -31,8 +31,10 @@ open class CashPaymentFlow( val issuerConstraint: Set = emptySet()) : AbstractCashFlow(progressTracker) { /** A straightforward constructor that constructs spends using cash states of any issuer. */ constructor(amount: Amount, recipient: Party) : this(amount, recipient, true, tracker()) + /** A straightforward constructor that constructs spends using cash states of any issuer. */ constructor(amount: Amount, recipient: Party, anonymous: Boolean) : this(amount, recipient, anonymous, tracker()) + constructor(request: PaymentRequest) : this(request.amount, request.recipient, request.anonymous, tracker(), request.issuerConstraint) @Suspendable diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt index 0525cead6a..b1dd0137aa 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt @@ -43,6 +43,7 @@ object TwoPartyDealFlow { companion object { object GENERATING_ID : ProgressTracker.Step("Generating anonymous identities") object SENDING_PROPOSAL : ProgressTracker.Step("Handshaking and awaiting transaction proposal.") + fun tracker() = ProgressTracker(GENERATING_ID, SENDING_PROPOSAL) } @@ -57,7 +58,7 @@ object TwoPartyDealFlow { val txIdentities = subFlow(SwapIdentitiesFlow(otherSideSession.counterparty)) val anonymousMe = txIdentities[ourIdentity] ?: ourIdentity.anonymise() val anonymousCounterparty = txIdentities[otherSideSession.counterparty] ?: otherSideSession.counterparty.anonymise() - // DOCEND 2 + // DOCEND 2 progressTracker.currentStep = SENDING_PROPOSAL // Make the first message we'll send to kick off the flow. val hello = Handshake(payload, anonymousMe, anonymousCounterparty) @@ -148,6 +149,7 @@ object TwoPartyDealFlow { @Suspendable protected abstract fun validateHandshake(handshake: Handshake): Handshake + @Suspendable protected abstract fun assembleSharedTX(handshake: Handshake): Triple, List> } diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt index d243792253..2d5093a583 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt @@ -136,6 +136,7 @@ object TwoPartyTradeFlow { private val anonymous: Boolean) : FlowLogic() { constructor(otherSideSession: FlowSession, notary: Party, acceptablePrice: Amount, typeToBuy: Class) : this(otherSideSession, notary, acceptablePrice, typeToBuy, true) + // DOCSTART 2 object RECEIVING : ProgressTracker.Step("Waiting for seller trading info") diff --git a/finance/src/main/kotlin/net/corda/finance/schemas/CashSchemaV1.kt b/finance/src/main/kotlin/net/corda/finance/schemas/CashSchemaV1.kt index 6ae8d9a9a0..5fdfc58492 100644 --- a/finance/src/main/kotlin/net/corda/finance/schemas/CashSchemaV1.kt +++ b/finance/src/main/kotlin/net/corda/finance/schemas/CashSchemaV1.kt @@ -22,8 +22,8 @@ object CashSchema object CashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCashState::class.java)) { @Entity @Table(name = "contract_cash_states", - indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"), - Index(name = "pennies_idx", columnList = "pennies"))) + indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"), + Index(name = "pennies_idx", columnList = "pennies"))) class PersistentCashState( /** X500Name of owner party **/ @Column(name = "owner_name") diff --git a/finance/src/main/kotlin/net/corda/finance/schemas/CommercialPaperSchemaV1.kt b/finance/src/main/kotlin/net/corda/finance/schemas/CommercialPaperSchemaV1.kt index b1d58a5c8c..f8c1b46b0e 100644 --- a/finance/src/main/kotlin/net/corda/finance/schemas/CommercialPaperSchemaV1.kt +++ b/finance/src/main/kotlin/net/corda/finance/schemas/CommercialPaperSchemaV1.kt @@ -22,9 +22,9 @@ object CommercialPaperSchema object CommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCommercialPaperState::class.java)) { @Entity @Table(name = "cp_states", - indexes = arrayOf(Index(name = "ccy_code_index", columnList = "ccy_code"), - Index(name = "maturity_index", columnList = "maturity_instant"), - Index(name = "face_value_index", columnList = "face_value"))) + indexes = arrayOf(Index(name = "ccy_code_index", columnList = "ccy_code"), + Index(name = "maturity_index", columnList = "maturity_instant"), + Index(name = "face_value_index", columnList = "face_value"))) class PersistentCommercialPaperState( @Column(name = "issuance_key") var issuanceParty: String, diff --git a/finance/src/main/kotlin/net/corda/finance/utils/StateSummingUtilities.kt b/finance/src/main/kotlin/net/corda/finance/utils/StateSummingUtilities.kt index 75d6c072f9..5f3d7c8f37 100644 --- a/finance/src/main/kotlin/net/corda/finance/utils/StateSummingUtilities.kt +++ b/finance/src/main/kotlin/net/corda/finance/utils/StateSummingUtilities.kt @@ -1,4 +1,5 @@ @file:JvmName("StateSumming") + package net.corda.finance.utils import net.corda.core.contracts.Amount diff --git a/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java b/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java index 59ba1ad99c..455472503f 100644 --- a/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java +++ b/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java @@ -34,7 +34,7 @@ public class CashTestsJava { }); tx.tweak(tw -> { - tw.output(Cash.PROGRAM_ID, () -> outState ); + tw.output(Cash.PROGRAM_ID, () -> outState); tw.command(getMEGA_CORP_PUBKEY(), DummyCommandData.INSTANCE); // Invalid command return tw.failsWith("required net.corda.finance.contracts.asset.Cash.Commands.Move command"); diff --git a/finance/src/test/kotlin/net/corda/finance/contracts/CommercialPaperTests.kt b/finance/src/test/kotlin/net/corda/finance/contracts/CommercialPaperTests.kt index 73bdd6d4aa..a1a296eb05 100644 --- a/finance/src/test/kotlin/net/corda/finance/contracts/CommercialPaperTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/contracts/CommercialPaperTests.kt @@ -80,7 +80,8 @@ class KotlinCommercialPaperLegacyTest : ICommercialPaperTestTemplate { @RunWith(Parameterized::class) class CommercialPaperTestsGeneric { companion object { - @Parameterized.Parameters @JvmStatic + @Parameterized.Parameters + @JvmStatic fun data() = listOf(JavaCommercialPaperTest(), KotlinCommercialPaperTest(), KotlinCommercialPaperLegacyTest()) } @@ -227,7 +228,7 @@ class CommercialPaperTestsGeneric { private lateinit var moveTX: SignedTransaction -// @Test + // @Test @Ignore fun `issue move and then redeem`() { setCordappPackages("net.corda.finance.contracts") diff --git a/finance/src/test/kotlin/net/corda/finance/contracts/asset/CashTests.kt b/finance/src/test/kotlin/net/corda/finance/contracts/asset/CashTests.kt index f30507ec3f..952aa3d9df 100644 --- a/finance/src/test/kotlin/net/corda/finance/contracts/asset/CashTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/contracts/asset/CashTests.kt @@ -590,9 +590,9 @@ class CashTests : TestDependencyInjectionBase() { fun generateSimpleDirectSpend() { initialiseTestSerialization() val wtx = - database.transaction { - makeSpend(100.DOLLARS, THEIR_IDENTITY_1) - } + database.transaction { + makeSpend(100.DOLLARS, THEIR_IDENTITY_1) + } database.transaction { val vaultState = vaultStatesUnconsumed.elementAt(0) assertEquals(vaultState.ref, wtx.inputs[0]) @@ -617,9 +617,9 @@ class CashTests : TestDependencyInjectionBase() { fun generateSimpleSpendWithChange() { initialiseTestSerialization() val wtx = - database.transaction { - makeSpend(10.DOLLARS, THEIR_IDENTITY_1) - } + database.transaction { + makeSpend(10.DOLLARS, THEIR_IDENTITY_1) + } database.transaction { val vaultState = vaultStatesUnconsumed.elementAt(0) val changeAmount = 90.DOLLARS `issued by` defaultIssuer @@ -643,9 +643,9 @@ class CashTests : TestDependencyInjectionBase() { fun generateSpendWithTwoInputs() { initialiseTestSerialization() val wtx = - database.transaction { - makeSpend(500.DOLLARS, THEIR_IDENTITY_1) - } + database.transaction { + makeSpend(500.DOLLARS, THEIR_IDENTITY_1) + } database.transaction { val vaultState0 = vaultStatesUnconsumed.elementAt(0) val vaultState1 = vaultStatesUnconsumed.elementAt(1) @@ -660,11 +660,11 @@ class CashTests : TestDependencyInjectionBase() { fun generateSpendMixedDeposits() { initialiseTestSerialization() val wtx = - database.transaction { - val wtx = makeSpend(580.DOLLARS, THEIR_IDENTITY_1) - assertEquals(3, wtx.inputs.size) - wtx - } + database.transaction { + val wtx = makeSpend(580.DOLLARS, THEIR_IDENTITY_1) + assertEquals(3, wtx.inputs.size) + wtx + } database.transaction { val vaultState0: StateAndRef = vaultStatesUnconsumed.elementAt(0) val vaultState1: StateAndRef = vaultStatesUnconsumed.elementAt(1) @@ -796,7 +796,7 @@ class CashTests : TestDependencyInjectionBase() { transaction { attachment(Cash.PROGRAM_ID) input("MEGA_CORP cash") - output(Cash.PROGRAM_ID, "MEGA_CORP cash 2", "MEGA_CORP cash".output().copy(owner = AnonymousParty(ALICE_PUBKEY)) ) + output(Cash.PROGRAM_ID, "MEGA_CORP cash 2", "MEGA_CORP cash".output().copy(owner = AnonymousParty(ALICE_PUBKEY))) command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } this.verifies() } diff --git a/finance/src/test/kotlin/net/corda/finance/contracts/asset/ObligationTests.kt b/finance/src/test/kotlin/net/corda/finance/contracts/asset/ObligationTests.kt index 3b053c212b..8a293c4009 100644 --- a/finance/src/test/kotlin/net/corda/finance/contracts/asset/ObligationTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/contracts/asset/ObligationTests.kt @@ -286,7 +286,7 @@ class ObligationTests { assertEquals(expected, actual) } - private inline fun getStateAndRef(state: T, contractClassName: ContractClassName): StateAndRef { + private inline fun getStateAndRef(state: T, contractClassName: ContractClassName): StateAndRef { val txState = TransactionState(state, contractClassName, DUMMY_NOTARY) return StateAndRef(txState, StateRef(SecureHash.randomSHA256(), 0)) @@ -418,7 +418,7 @@ class ObligationTests { @Test fun `payment netting`() { // Try netting out two obligations - ledger(mockService) { + ledger(mockService) { cashObligationTestRoots(this) transaction("Issuance") { attachments(Obligation.PROGRAM_ID) diff --git a/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt b/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt index 515480760a..c8c92fad91 100644 --- a/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt @@ -18,7 +18,7 @@ import kotlin.test.assertEquals import kotlin.test.assertFailsWith class CashExitFlowTests { - private lateinit var mockNet : MockNetwork + private lateinit var mockNet: MockNetwork private val initialBalance = 2000.DOLLARS private val ref = OpaqueBytes.of(0x01) private lateinit var bankOfCordaNode: StartedNode diff --git a/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt b/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt index 791dc0d9da..3aeb782a1d 100644 --- a/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt @@ -22,7 +22,7 @@ import kotlin.test.assertEquals import kotlin.test.assertFailsWith class CashIssueFlowTests { - private lateinit var mockNet : MockNetwork + private lateinit var mockNet: MockNetwork private lateinit var bankOfCordaNode: StartedNode private lateinit var bankOfCorda: Party private lateinit var notaryNode: StartedNode diff --git a/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt b/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt index 9304425778..a9b1352646 100644 --- a/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt @@ -21,7 +21,7 @@ import kotlin.test.assertEquals import kotlin.test.assertFailsWith class CashPaymentFlowTests { - private lateinit var mockNet : MockNetwork + private lateinit var mockNet: MockNetwork private val initialBalance = 2000.DOLLARS private val ref = OpaqueBytes.of(0x01) private lateinit var bankOfCordaNode: StartedNode diff --git a/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV1.kt b/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV1.kt index f9395c1adb..b94d6ac700 100644 --- a/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV1.kt +++ b/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV1.kt @@ -19,8 +19,8 @@ object CashSchema object SampleCashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCashState::class.java)) { @Entity @Table(name = "contract_cash_states", - indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"), - Index(name = "pennies_idx", columnList = "pennies"))) + indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"), + Index(name = "pennies_idx", columnList = "pennies"))) class PersistentCashState( @Column(name = "owner_key") var owner: String, diff --git a/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV2.kt b/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV2.kt index 7a5e0da89c..95108eddfa 100644 --- a/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV2.kt +++ b/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV2.kt @@ -13,25 +13,25 @@ import javax.persistence.Table * [VaultFungibleState] abstract schema */ object SampleCashSchemaV2 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 2, - mappedTypes = listOf(PersistentCashState::class.java)) { + mappedTypes = listOf(PersistentCashState::class.java)) { @Entity @Table(name = "cash_states_v2", - indexes = arrayOf(Index(name = "ccy_code_idx2", columnList = "ccy_code"))) - class PersistentCashState ( - /** product type */ - @Column(name = "ccy_code", length = 3) - var currency: String, + indexes = arrayOf(Index(name = "ccy_code_idx2", columnList = "ccy_code"))) + class PersistentCashState( + /** product type */ + @Column(name = "ccy_code", length = 3) + var currency: String, - /** parent attributes */ - @Transient - val _participants: Set, - @Transient - val _owner: AbstractParty, - @Transient - val _quantity: Long, - @Transient - val _issuerParty: AbstractParty, - @Transient - val _issuerRef: ByteArray + /** parent attributes */ + @Transient + val _participants: Set, + @Transient + val _owner: AbstractParty, + @Transient + val _quantity: Long, + @Transient + val _issuerParty: AbstractParty, + @Transient + val _issuerRef: ByteArray ) : CommonSchemaV1.FungibleState(_participants.toMutableSet(), _owner, _quantity, _issuerParty, _issuerRef) } diff --git a/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV3.kt b/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV3.kt index f6288c0591..eaae33410f 100644 --- a/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV3.kt +++ b/finance/src/test/kotlin/net/corda/finance/schemas/SampleCashSchemaV3.kt @@ -13,7 +13,7 @@ import javax.persistence.Table * at the time of writing. */ object SampleCashSchemaV3 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 3, - mappedTypes = listOf(PersistentCashState::class.java)) { + mappedTypes = listOf(PersistentCashState::class.java)) { @Entity @Table(name = "cash_states_v3") class PersistentCashState( diff --git a/finance/src/test/kotlin/net/corda/finance/schemas/SampleCommercialPaperSchemaV1.kt b/finance/src/test/kotlin/net/corda/finance/schemas/SampleCommercialPaperSchemaV1.kt index 9b4c91b179..4da37b7143 100644 --- a/finance/src/test/kotlin/net/corda/finance/schemas/SampleCommercialPaperSchemaV1.kt +++ b/finance/src/test/kotlin/net/corda/finance/schemas/SampleCommercialPaperSchemaV1.kt @@ -20,9 +20,9 @@ object CommercialPaperSchema object SampleCommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCommercialPaperState::class.java)) { @Entity @Table(name = "cp_states", - indexes = arrayOf(Index(name = "ccy_code_index", columnList = "ccy_code"), - Index(name = "maturity_index", columnList = "maturity_instant"), - Index(name = "face_value_index", columnList = "face_value"))) + indexes = arrayOf(Index(name = "ccy_code_index", columnList = "ccy_code"), + Index(name = "maturity_index", columnList = "maturity_instant"), + Index(name = "face_value_index", columnList = "face_value"))) class PersistentCommercialPaperState( @Column(name = "issuance_key") var issuanceParty: String, diff --git a/finance/src/test/kotlin/net/corda/finance/schemas/SampleCommercialPaperSchemaV2.kt b/finance/src/test/kotlin/net/corda/finance/schemas/SampleCommercialPaperSchemaV2.kt index ead55b4b1e..a3b855fe25 100644 --- a/finance/src/test/kotlin/net/corda/finance/schemas/SampleCommercialPaperSchemaV2.kt +++ b/finance/src/test/kotlin/net/corda/finance/schemas/SampleCommercialPaperSchemaV2.kt @@ -14,11 +14,11 @@ import javax.persistence.Table * [VaultFungibleState] abstract schema */ object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1, - mappedTypes = listOf(PersistentCommercialPaperState::class.java)) { + mappedTypes = listOf(PersistentCommercialPaperState::class.java)) { @Entity @Table(name = "cp_states_v2", - indexes = arrayOf(Index(name = "ccy_code_index2", columnList = "ccy_code"), - Index(name = "maturity_index2", columnList = "maturity_instant"))) + indexes = arrayOf(Index(name = "ccy_code_index2", columnList = "ccy_code"), + Index(name = "maturity_index2", columnList = "maturity_instant"))) class PersistentCommercialPaperState( @Column(name = "maturity_instant") var maturity: Instant, diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/RPCApi.kt b/node-api/src/main/kotlin/net/corda/nodeapi/RPCApi.kt index d2de3777f6..aa062e3195 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/RPCApi.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/RPCApi.kt @@ -68,7 +68,7 @@ object RPCApi { val RPC_CLIENT_BINDING_REMOVAL_FILTER_EXPRESSION = "${ManagementHelper.HDR_NOTIFICATION_TYPE} = '${CoreNotificationType.BINDING_REMOVED.name}' AND " + - "${ManagementHelper.HDR_ROUTING_NAME} LIKE '$RPC_CLIENT_QUEUE_NAME_PREFIX.%'" + "${ManagementHelper.HDR_ROUTING_NAME} LIKE '$RPC_CLIENT_QUEUE_NAME_PREFIX.%'" val RPC_CLIENT_BINDING_ADDITION_FILTER_EXPRESSION = "${ManagementHelper.HDR_NOTIFICATION_TYPE} = '${CoreNotificationType.BINDING_ADDED.name}' AND " + "${ManagementHelper.HDR_ROUTING_NAME} LIKE '$RPC_CLIENT_QUEUE_NAME_PREFIX.%'" @@ -141,7 +141,7 @@ object RPCApi { val ids = ArrayList() val buffer = message.bodyBuffer val numberOfIds = buffer.readInt() - for (i in 1 .. numberOfIds) { + for (i in 1..numberOfIds) { ids.add(ObservableId(buffer.readLong())) } ObservablesClosed(ids) diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/config/ConfigUtilities.kt b/node-api/src/main/kotlin/net/corda/nodeapi/config/ConfigUtilities.kt index 78283ea654..a67a55db37 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/config/ConfigUtilities.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/config/ConfigUtilities.kt @@ -1,4 +1,5 @@ @file:JvmName("ConfigUtilities") + package net.corda.nodeapi.config import com.typesafe.config.Config diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoader.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoader.kt index 749c82b7ef..20d2efca63 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoader.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoader.kt @@ -72,7 +72,7 @@ class AttachmentsClassLoader(attachments: List, parent: ClassLoader val stream = ByteArrayOutputStream() try { attachment.extractFile(path, stream) - } catch(e: FileNotFoundException) { + } catch (e: FileNotFoundException) { throw ClassNotFoundException(name) } val bytes = stream.toByteArray() @@ -99,7 +99,7 @@ class AttachmentsClassLoader(attachments: List, parent: ClassLoader val stream = ByteArrayOutputStream() attachment.extractFile(path, stream) return ByteArrayInputStream(stream.toByteArray()) - } catch(e: FileNotFoundException) { + } catch (e: FileNotFoundException) { return null } } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/ClientContexts.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/ClientContexts.kt index add6b1465e..bd6135522a 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/ClientContexts.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/ClientContexts.kt @@ -1,4 +1,5 @@ @file:JvmName("ClientContexts") + package net.corda.nodeapi.internal.serialization import net.corda.core.serialization.SerializationContext diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolver.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolver.kt index afcdcbf0c8..04c43122ec 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolver.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolver.kt @@ -31,9 +31,9 @@ class CordaClassResolver(serializationContext: SerializationContext) : DefaultCl * The point is that we do not want to send Kotlin types "over the wire" via RPC. */ private val javaAliases: Map, Class<*>> = mapOf( - listOf().javaClass to Collections.emptyList().javaClass, - setOf().javaClass to Collections.emptySet().javaClass, - mapOf().javaClass to Collections.emptyMap().javaClass + listOf().javaClass to Collections.emptyList().javaClass, + setOf().javaClass to Collections.emptySet().javaClass, + mapOf().javaClass to Collections.emptyMap().javaClass ) private fun typeForSerializationOf(type: Class<*>): Class<*> = javaAliases[type] ?: type @@ -194,7 +194,7 @@ class LoggingWhitelist(val delegate: ClassWhitelist, val global: Boolean = true) if (fileName != null && fileName.isNotEmpty()) { try { return PrintWriter(Files.newBufferedWriter(Paths.get(fileName), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND, StandardOpenOption.WRITE), true) - } catch(ioEx: Exception) { + } catch (ioEx: Exception) { log.error("Could not open/create whitelist journal file for append: $fileName", ioEx) } } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/DefaultKryoCustomizer.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/DefaultKryoCustomizer.kt index 04104533ee..7532ecffe9 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/DefaultKryoCustomizer.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/DefaultKryoCustomizer.kt @@ -140,6 +140,7 @@ object DefaultKryoCustomizer { // Use this to allow construction of objects using a JVM backdoor that skips invoking the constructors, if there // is no no-arg constructor available. private val defaultStrategy = Kryo.DefaultInstantiatorStrategy(fallbackStrategy) + override fun newInstantiatorOf(type: Class): ObjectInstantiator { // However this doesn't work for non-public classes in the java. namespace val strat = if (type.name.startsWith("java.") && !isPublic(type.modifiers)) fallbackStrategy else defaultStrategy @@ -151,6 +152,7 @@ object DefaultKryoCustomizer { override fun write(kryo: Kryo, output: Output, obj: PartyAndCertificate) { kryo.writeClassAndObject(output, obj.certPath) } + override fun read(kryo: Kryo, input: Input, type: Class): PartyAndCertificate { return PartyAndCertificate(kryo.readClassAndObject(input) as CertPath) } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/Kryo.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/Kryo.kt index 7b998d5cd7..b4d0dc9c8c 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/Kryo.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/Kryo.kt @@ -546,7 +546,7 @@ class ThrowableSerializer(kryo: Kryo, type: Class) : Serializer override fun read(kryo: Kryo, input: Input, type: Class): Throwable { val throwableRead = delegate.read(kryo, input, type) - if(throwableRead.suppressed.isEmpty()) { + if (throwableRead.suppressed.isEmpty()) { throwableRead.setSuppressedToSentinel() } return throwableRead diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/SerializationScheme.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/SerializationScheme.kt index ca6c4c5292..1e7c257a1d 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/SerializationScheme.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/SerializationScheme.kt @@ -52,7 +52,7 @@ data class SerializationContextImpl(override val preferredSerializationVersion: * We need to cache the AttachmentClassLoaders to avoid too many contexts, since the class loader is part of cache key for the context. */ override fun withAttachmentsClassLoader(attachmentHashes: List): SerializationContext { - properties[attachmentsClassLoaderEnabledPropertyName] as? Boolean ?: false || return this + properties[attachmentsClassLoaderEnabledPropertyName] as? Boolean == true || return this val serializationContext = properties[serializationContextKey] as? SerializeAsTokenContextImpl ?: return this // Some tests don't set one. try { return withClassLoader(cache.get(attachmentHashes) { @@ -142,8 +142,8 @@ open class SerializationFactoryImpl : SerializationFactory() { private object AutoCloseableSerialisationDetector : Serializer() { override fun write(kryo: Kryo, output: Output, closeable: AutoCloseable) { val message = "${closeable.javaClass.name}, which is a closeable resource, has been detected during flow checkpointing. " + - "Restoring such resources across node restarts is not supported. Make sure code accessing it is " + - "confined to a private method or the reference is nulled out." + "Restoring such resources across node restarts is not supported. Make sure code accessing it is " + + "confined to a private method or the reference is nulled out." throw UnsupportedOperationException(message) } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/ServerContexts.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/ServerContexts.kt index 89dd6b524d..baab649669 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/ServerContexts.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/ServerContexts.kt @@ -1,4 +1,5 @@ @file:JvmName("ServerContexts") + package net.corda.nodeapi.internal.serialization import net.corda.core.serialization.ClassWhitelist diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/UseCaseAwareness.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/UseCaseAwareness.kt index fdf57d28be..7f1d8c17b4 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/UseCaseAwareness.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/UseCaseAwareness.kt @@ -6,7 +6,7 @@ import java.util.* internal fun checkUseCase(allowedUseCases: EnumSet) { val currentContext: SerializationContext = SerializationFactory.currentFactory?.currentContext ?: throw IllegalStateException("Current context is not set") - if(!allowedUseCases.contains(currentContext.useCase)) { + if (!allowedUseCases.contains(currentContext.useCase)) { throw IllegalStateException("UseCase '${currentContext.useCase}' is not within '$allowedUseCases'") } } \ No newline at end of file diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/ArraySerializer.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/ArraySerializer.kt index e49eafaa96..10f320a55a 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/ArraySerializer.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/ArraySerializer.kt @@ -23,14 +23,13 @@ open class ArraySerializer(override val type: Type, factory: SerializerFactory) // // We *need* to retain knowledge for AMQP deserialisation weather that lowest primitive // was boxed or unboxed so just infer it recursively - private fun calcTypeName(type: Type) : String = - if (type.componentType().isArray()) { - val typeName = calcTypeName(type.componentType()); "$typeName[]" - } - else { - val arrayType = if (type.asClass()!!.componentType.isPrimitive) "[p]" else "[]" - "${type.componentType().typeName}$arrayType" - } + private fun calcTypeName(type: Type): String = + if (type.componentType().isArray()) { + val typeName = calcTypeName(type.componentType()); "$typeName[]" + } else { + val arrayType = if (type.asClass()!!.componentType.isPrimitive) "[p]" else "[]" + "${type.componentType().typeName}$arrayType" + } override val typeDescriptor by lazy { Symbol.valueOf("$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}") } internal val elementType: Type by lazy { type.componentType() } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/CollectionSerializer.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/CollectionSerializer.kt index 43a0234f95..fc176cfda7 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/CollectionSerializer.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/CollectionSerializer.kt @@ -35,11 +35,10 @@ class CollectionSerializer(val declaredType: ParameterizedType, factory: Seriali } fun deriveParameterizedType(declaredType: Type, declaredClass: Class<*>, actualClass: Class<*>?): ParameterizedType { - if(supportedTypes.containsKey(declaredClass)) { + if (supportedTypes.containsKey(declaredClass)) { // Simple case - it is already known to be a collection. return deriveParametrizedType(declaredType, uncheckedCast(declaredClass)) - } - else if (actualClass != null && Collection::class.java.isAssignableFrom(actualClass)) { + } else if (actualClass != null && Collection::class.java.isAssignableFrom(actualClass)) { // Declared class is not collection, but [actualClass] is - represent it accordingly. val collectionClass = findMostSuitableCollectionType(actualClass) return deriveParametrizedType(declaredType, collectionClass) @@ -49,11 +48,11 @@ class CollectionSerializer(val declaredType: ParameterizedType, factory: Seriali } private fun deriveParametrizedType(declaredType: Type, collectionClass: Class>): ParameterizedType = - (declaredType as? ParameterizedType) ?: DeserializedParameterizedType(collectionClass, arrayOf(SerializerFactory.AnyType)) + (declaredType as? ParameterizedType) ?: DeserializedParameterizedType(collectionClass, arrayOf(SerializerFactory.AnyType)) private fun findMostSuitableCollectionType(actualClass: Class<*>): Class> = - supportedTypes.keys.findLast { it.isAssignableFrom(actualClass) }!! + supportedTypes.keys.findLast { it.isAssignableFrom(actualClass) }!! } @@ -61,13 +60,13 @@ class CollectionSerializer(val declaredType: ParameterizedType, factory: Seriali private val typeNotation: TypeNotation = RestrictedType(SerializerFactory.nameForType(declaredType), null, emptyList(), "list", Descriptor(typeDescriptor), emptyList()) - override fun writeClassInfo(output: SerializationOutput) = ifThrowsAppend({declaredType.typeName}) { + override fun writeClassInfo(output: SerializationOutput) = ifThrowsAppend({ declaredType.typeName }) { if (output.writeTypeNotations(typeNotation)) { output.requireSerializer(declaredType.actualTypeArguments[0]) } } - override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) = ifThrowsAppend({declaredType.typeName}) { + override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) = ifThrowsAppend({ declaredType.typeName }) { // Write described data.withDescribed(typeNotation.descriptor) { withList { @@ -78,7 +77,7 @@ class CollectionSerializer(val declaredType: ParameterizedType, factory: Seriali } } - override fun readObject(obj: Any, schema: Schema, input: DeserializationInput): Any = ifThrowsAppend({declaredType.typeName}) { + override fun readObject(obj: Any, schema: Schema, input: DeserializationInput): Any = ifThrowsAppend({ declaredType.typeName }) { // TODO: Can we verify the entries in the list? concreteBuilder((obj as List<*>).map { input.readObjectOrNull(it, schema, declaredType.actualTypeArguments[0]) }) } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/CustomSerializer.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/CustomSerializer.kt index 242f829511..e039911ec0 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/CustomSerializer.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/CustomSerializer.kt @@ -102,9 +102,9 @@ abstract class CustomSerializer : AMQPSerializer { * custom serializers. */ abstract class Proxy(clazz: Class, - protected val proxyClass: Class

, - protected val factory: SerializerFactory, - withInheritance: Boolean = true) : CustomSerializerImp(clazz, withInheritance) { + protected val proxyClass: Class

, + protected val factory: SerializerFactory, + withInheritance: Boolean = true) : CustomSerializerImp(clazz, withInheritance) { override fun isSerializerFor(clazz: Class<*>): Boolean = if (withInheritance) this.clazz.isAssignableFrom(clazz) else this.clazz == clazz private val proxySerializer: ObjectSerializer by lazy { ObjectSerializer(proxyClass, factory) } @@ -151,11 +151,10 @@ abstract class CustomSerializer : AMQPSerializer { * @param unmake A lambda that extracts the string value for an instance, that defaults to the [toString] method. */ abstract class ToString(clazz: Class, withInheritance: Boolean = false, - private val maker: (String) -> T = clazz.getConstructor(String::class.java).let { - `constructor` -> - { string -> `constructor`.newInstance(string) } - }, - private val unmaker: (T) -> String = { obj -> obj.toString() }) + private val maker: (String) -> T = clazz.getConstructor(String::class.java).let { `constructor` -> + { string -> `constructor`.newInstance(string) } + }, + private val unmaker: (T) -> String = { obj -> obj.toString() }) : CustomSerializerImp(clazz, withInheritance) { override val schemaForDocumentation = Schema( diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializationInput.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializationInput.kt index 648f11eeae..7269aa8c40 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializationInput.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializationInput.kt @@ -80,9 +80,9 @@ class DeserializationInput(internal val serializerFactory: SerializerFactory) { private fun des(generator: () -> R): R { try { return generator() - } catch(nse: NotSerializableException) { + } catch (nse: NotSerializableException) { throw nse - } catch(t: Throwable) { + } catch (t: Throwable) { throw NotSerializableException("Unexpected throwable: ${t.message} ${t.getStackTraceAsString()}") } finally { objectHistory.clear() @@ -152,10 +152,10 @@ class DeserializationInput(internal val serializerFactory: SerializerFactory) { * In the future tighter control might be needed */ private fun Type.materiallyEquivalentTo(that: Type): Boolean = - when(that) { - is ParameterizedType -> asClass() == that.asClass() - is TypeVariable<*> -> isSubClassOf(that.bounds.first()) - is WildcardType -> isSubClassOf(that.upperBounds.first()) - else -> false - } + when (that) { + is ParameterizedType -> asClass() == that.asClass() + is TypeVariable<*> -> isSubClassOf(that.bounds.first()) + is WildcardType -> isSubClassOf(that.upperBounds.first()) + else -> false + } } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/MapSerializer.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/MapSerializer.kt index 1fa710d59a..932b641ad2 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/MapSerializer.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/MapSerializer.kt @@ -42,11 +42,10 @@ class MapSerializer(private val declaredType: ParameterizedType, factory: Serial fun deriveParameterizedType(declaredType: Type, declaredClass: Class<*>, actualClass: Class<*>?): ParameterizedType { declaredClass.checkSupportedMapType() - if(supportedTypes.containsKey(declaredClass)) { + if (supportedTypes.containsKey(declaredClass)) { // Simple case - it is already known to be a map. return deriveParametrizedType(declaredType, uncheckedCast(declaredClass)) - } - else if (actualClass != null && Map::class.java.isAssignableFrom(actualClass)) { + } else if (actualClass != null && Map::class.java.isAssignableFrom(actualClass)) { // Declared class is not map, but [actualClass] is - represent it accordingly. val mapClass = findMostSuitableMapType(actualClass) return deriveParametrizedType(declaredType, mapClass) @@ -67,14 +66,14 @@ class MapSerializer(private val declaredType: ParameterizedType, factory: Serial private val typeNotation: TypeNotation = RestrictedType(SerializerFactory.nameForType(declaredType), null, emptyList(), "map", Descriptor(typeDescriptor), emptyList()) - override fun writeClassInfo(output: SerializationOutput) = ifThrowsAppend({declaredType.typeName}) { + override fun writeClassInfo(output: SerializationOutput) = ifThrowsAppend({ declaredType.typeName }) { if (output.writeTypeNotations(typeNotation)) { output.requireSerializer(declaredType.actualTypeArguments[0]) output.requireSerializer(declaredType.actualTypeArguments[1]) } } - override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) = ifThrowsAppend({declaredType.typeName}) { + override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) = ifThrowsAppend({ declaredType.typeName }) { obj.javaClass.checkSupportedMapType() // Write described data.withDescribed(typeNotation.descriptor) { @@ -89,7 +88,7 @@ class MapSerializer(private val declaredType: ParameterizedType, factory: Serial } } - override fun readObject(obj: Any, schema: Schema, input: DeserializationInput): Any = ifThrowsAppend({declaredType.typeName}) { + override fun readObject(obj: Any, schema: Schema, input: DeserializationInput): Any = ifThrowsAppend({ declaredType.typeName }) { // TODO: General generics question. Do we need to validate that entries in Maps and Collections match the generic type? Is it a security hole? val entries: Iterable> = (obj as Map<*, *>).map { readEntry(schema, input, it) } concreteBuilder(entries.toMap()) @@ -108,13 +107,11 @@ internal fun Class<*>.checkSupportedMapType() { if (HashMap::class.java.isAssignableFrom(this) && !LinkedHashMap::class.java.isAssignableFrom(this)) { throw IllegalArgumentException( "Map type $this is unstable under iteration. Suggested fix: use java.util.LinkedHashMap instead.") - } - else if (WeakHashMap::class.java.isAssignableFrom(this)) { - throw IllegalArgumentException ("Weak references with map types not supported. Suggested fix: " - + "use java.util.LinkedHashMap instead.") - } - else if (Dictionary::class.java.isAssignableFrom(this)) { - throw IllegalArgumentException ( + } else if (WeakHashMap::class.java.isAssignableFrom(this)) { + throw IllegalArgumentException("Weak references with map types not supported. Suggested fix: " + + "use java.util.LinkedHashMap instead.") + } else if (Dictionary::class.java.isAssignableFrom(this)) { + throw IllegalArgumentException( "Unable to serialise deprecated type $this. Suggested fix: prefer java.util.map implementations") } } \ No newline at end of file diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/ObjectSerializer.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/ObjectSerializer.kt index c483e8e126..7dcb450803 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/ObjectSerializer.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/ObjectSerializer.kt @@ -41,7 +41,7 @@ open class ObjectSerializer(val clazz: Type, factory: SerializerFactory) : AMQPS } } - override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) = ifThrowsAppend({clazz.typeName}) { + override fun writeObject(obj: Any, data: Data, type: Type, output: SerializationOutput) = ifThrowsAppend({ clazz.typeName }) { // Write described data.withDescribed(typeNotation.descriptor) { // Write list @@ -53,7 +53,7 @@ open class ObjectSerializer(val clazz: Type, factory: SerializerFactory) : AMQPS } } - override fun readObject(obj: Any, schema: Schema, input: DeserializationInput): Any = ifThrowsAppend({clazz.typeName}) { + override fun readObject(obj: Any, schema: Schema, input: DeserializationInput): Any = ifThrowsAppend({ clazz.typeName }) { if (obj is List<*>) { if (obj.size > propertySerializers.size) throw NotSerializableException("Too many properties in described type $typeName") val params = obj.zip(propertySerializers).map { it.second.readProperty(it.first, schema, input) } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/PropertySerializer.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/PropertySerializer.kt index 7c7714b9e9..3d9fa8b0a5 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/PropertySerializer.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/PropertySerializer.kt @@ -21,8 +21,8 @@ sealed class PropertySerializer(val name: String, val readMethod: Method?, val r val default: String? = generateDefault() val mandatory: Boolean = generateMandatory() - private val isInterface: Boolean get() = resolvedType.asClass()?.isInterface ?: false - private val isJVMPrimitive: Boolean get() = resolvedType.asClass()?.isPrimitive ?: false + private val isInterface: Boolean get() = resolvedType.asClass()?.isInterface == true + private val isJVMPrimitive: Boolean get() = resolvedType.asClass()?.isPrimitive == true private fun generateType(): String { return if (isInterface || resolvedType == Any::class.java) "*" else SerializerFactory.nameForType(resolvedType) @@ -45,14 +45,14 @@ sealed class PropertySerializer(val name: String, val readMethod: Method?, val r } private fun generateMandatory(): Boolean { - return isJVMPrimitive || !(readMethod?.returnsNullable() ?: true) + return isJVMPrimitive || readMethod?.returnsNullable() == false } private fun Method.returnsNullable(): Boolean { try { val returnTypeString = this.declaringClass.kotlin.memberProperties.firstOrNull { it.javaGetter == this }?.returnType?.toString() ?: "?" return returnTypeString.endsWith('?') || returnTypeString.endsWith('!') - } catch(e: kotlin.reflect.jvm.internal.KotlinReflectionInternalError) { + } catch (e: kotlin.reflect.jvm.internal.KotlinReflectionInternalError) { // This might happen for some types, e.g. kotlin.Throwable? - the root cause of the issue is: https://youtrack.jetbrains.com/issue/KT-13077 // TODO: Revisit this when Kotlin issue is fixed. logger.error("Unexpected internal Kotlin error", e) @@ -66,7 +66,7 @@ sealed class PropertySerializer(val name: String, val readMethod: Method?, val r fun make(name: String, readMethod: Method?, resolvedType: Type, factory: SerializerFactory): PropertySerializer { readMethod?.isAccessible = true if (SerializerFactory.isPrimitive(resolvedType)) { - return when(resolvedType) { + return when (resolvedType) { Char::class.java, Character::class.java -> AMQPCharPropertySerializer(name, readMethod) else -> AMQPPrimitivePropertySerializer(name, readMethod, resolvedType) } @@ -86,17 +86,17 @@ sealed class PropertySerializer(val name: String, val readMethod: Method?, val r // This is lazy so we don't get an infinite loop when a method returns an instance of the class. private val typeSerializer: AMQPSerializer<*> by lazy { lazyTypeSerializer() } - override fun writeClassInfo(output: SerializationOutput) = ifThrowsAppend({nameForDebug}) { + override fun writeClassInfo(output: SerializationOutput) = ifThrowsAppend({ nameForDebug }) { if (resolvedType != Any::class.java) { typeSerializer.writeClassInfo(output) } } - override fun readProperty(obj: Any?, schema: Schema, input: DeserializationInput): Any? = ifThrowsAppend({nameForDebug}) { + override fun readProperty(obj: Any?, schema: Schema, input: DeserializationInput): Any? = ifThrowsAppend({ nameForDebug }) { input.readObjectOrNull(obj, schema, resolvedType) } - override fun writeProperty(obj: Any?, data: Data, output: SerializationOutput) = ifThrowsAppend({nameForDebug}) { + override fun writeProperty(obj: Any?, data: Data, output: SerializationOutput) = ifThrowsAppend({ nameForDebug }) { output.writeObjectOrNull(readMethod!!.invoke(obj), data, resolvedType) } @@ -133,7 +133,7 @@ sealed class PropertySerializer(val name: String, val readMethod: Method?, val r override fun writeClassInfo(output: SerializationOutput) {} override fun readProperty(obj: Any?, schema: Schema, input: DeserializationInput): Any? { - return if(obj == null) null else (obj as Short).toChar() + return if (obj == null) null else (obj as Short).toChar() } override fun writeProperty(obj: Any?, data: Data, output: SerializationOutput) { diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutput.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutput.kt index 5379b5ab84..87a19376c9 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutput.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutput.kt @@ -82,14 +82,13 @@ open class SerializationOutput(internal val serializerFactory: SerializerFactory } val retrievedRefCount = objectHistory[obj] - if(retrievedRefCount == null) { + if (retrievedRefCount == null) { serializer.writeObject(obj, data, type, this) // Important to do it after serialization such that dependent object will have preceding reference numbers // assigned to them first as they will be first read from the stream on receiving end. // Skip for primitive types as they are too small and overhead of referencing them will be much higher than their content if (suitableForObjectReference(obj.javaClass)) objectHistory.put(obj, objectHistory.size) - } - else { + } else { data.writeReferencedObject(ReferencedObject(retrievedRefCount)) } } diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/custom/ThrowableSerializer.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/custom/ThrowableSerializer.kt index ad8394db2d..8697cd98c7 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/custom/ThrowableSerializer.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/custom/ThrowableSerializer.kt @@ -27,7 +27,7 @@ class ThrowableSerializer(factory: SerializerFactory) : CustomSerializer.Proxy> = listOf(LocalDateTimeSerializer(factory), ZoneIdSerializer(factory)) override fun toProxy(obj: ZonedDateTime): ZonedDateTimeProxy = ZonedDateTimeProxy(obj.toLocalDateTime(), obj.offset, obj.zone) diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/carpenter/AMQPSchemaExtensions.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/carpenter/AMQPSchemaExtensions.kt index 611dbb9788..0bbdf01033 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/carpenter/AMQPSchemaExtensions.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/carpenter/AMQPSchemaExtensions.kt @@ -132,5 +132,10 @@ fun AMQPField.validateType(classloader: ClassLoader) = when (type) { } private fun ClassLoader.exists(clazz: String) = run { - try { this.loadClass(clazz); true } catch (e: ClassNotFoundException) { false } } + try { + this.loadClass(clazz); true + } catch (e: ClassNotFoundException) { + false + } +} diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/carpenter/Schema.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/carpenter/Schema.kt index e3a3bfab56..352ad498da 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/carpenter/Schema.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/carpenter/Schema.kt @@ -24,7 +24,7 @@ abstract class Schema( updater: (String, Field) -> Unit) { private fun Map.descriptors() = LinkedHashMap(this.mapValues { it.value.descriptor }) - var flags : EnumMap = EnumMap(SchemaFlags::class.java) + var flags: EnumMap = EnumMap(SchemaFlags::class.java) init { fields.forEach { updater(it.key, it.value) } @@ -49,15 +49,15 @@ abstract class Schema( get() = "[L$jvmName;" fun unsetCordaSerializable() { - flags.replace (SchemaFlags.CordaSerializable, false) + flags.replace(SchemaFlags.CordaSerializable, false) } } -fun EnumMap.cordaSerializable() : Boolean { +fun EnumMap.cordaSerializable(): Boolean { return this.getOrDefault(SchemaFlags.CordaSerializable, true) == true } -fun EnumMap.simpleFieldAccess() : Boolean { +fun EnumMap.simpleFieldAccess(): Boolean { return this.getOrDefault(SchemaFlags.SimpleFieldAccess, true) == true } diff --git a/node-api/src/test/java/net/corda/nodeapi/internal/serialization/amqp/ListsSerializationJavaTest.java b/node-api/src/test/java/net/corda/nodeapi/internal/serialization/amqp/ListsSerializationJavaTest.java index bcd1d1f1f7..6085546c37 100644 --- a/node-api/src/test/java/net/corda/nodeapi/internal/serialization/amqp/ListsSerializationJavaTest.java +++ b/node-api/src/test/java/net/corda/nodeapi/internal/serialization/amqp/ListsSerializationJavaTest.java @@ -12,7 +12,8 @@ import java.util.List; public class ListsSerializationJavaTest { @CordaSerializable - interface Parent {} + interface Parent { + } public static class Child implements Parent { private final int value; @@ -123,7 +124,7 @@ public class ListsSerializationJavaTest { } // Have to have own version as Kotlin inline functions cannot be easily called from Java - private static void assertEqualAfterRoundTripSerialization(T container, Class clazz) throws Exception { + private static void assertEqualAfterRoundTripSerialization(T container, Class clazz) throws Exception { SerializerFactory factory1 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader()); SerializationOutput ser = new SerializationOutput(factory1); SerializedBytes bytes = ser.serialize(container); diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoaderStaticContractTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoaderStaticContractTests.kt index 77733ec060..ce95ac21d8 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoaderStaticContractTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoaderStaticContractTests.kt @@ -37,7 +37,7 @@ class AttachmentsClassLoaderStaticContractTests : TestDependencyInjectionBase() fun generateInitial(owner: PartyAndReference, magicNumber: Int, notary: Party): TransactionBuilder { val state = State(magicNumber) return TransactionBuilder(notary) - .withItems(StateAndContract(state, ATTACHMENT_PROGRAM_ID), Command(Commands.Create(), owner.party.owningKey)) + .withItems(StateAndContract(state, ATTACHMENT_PROGRAM_ID), Command(Commands.Create(), owner.party.owningKey)) } } @@ -45,7 +45,7 @@ class AttachmentsClassLoaderStaticContractTests : TestDependencyInjectionBase() @Before fun `create service hub`() { - serviceHub = MockServices(cordappPackages=listOf("net.corda.nodeapi.internal")) + serviceHub = MockServices(cordappPackages = listOf("net.corda.nodeapi.internal")) } @After diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoaderTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoaderTests.kt index e51a974936..bf4138379d 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoaderTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/AttachmentsClassLoaderTests.kt @@ -45,6 +45,7 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { whenever(serviceHub.attachments).thenReturn(attachmentStorage) return this.withServiceHub(serviceHub) } + private fun SerializationContext.withServiceHub(serviceHub: ServiceHub): SerializationContext { return this.withTokenContext(SerializeAsTokenContextImpl(serviceHub) {}).withProperty(attachmentsClassLoaderEnabledPropertyName, true) } @@ -266,7 +267,7 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { @Test fun `test serialization of sub-sequence OpaqueBytes`() { - val bytesSequence = ByteSequence.of("0123456789".toByteArray(), 3 ,2) + val bytesSequence = ByteSequence.of("0123456789".toByteArray(), 3, 2) val bytes = bytesSequence.serialize() val copiedBytesSequence = bytes.deserialize() @@ -310,8 +311,8 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { val attachmentRef = serviceHub.attachmentId val bytes = run { val outboundContext = SerializationFactory.defaultFactory.defaultContext - .withServiceHub(serviceHub) - .withClassLoader(child) + .withServiceHub(serviceHub) + .withClassLoader(child) val wireTransaction = tx.toWireTransaction(serviceHub, outboundContext) wireTransaction.serialize(context = outboundContext) } diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolverTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolverTests.kt index 3a67501191..74a3d574ae 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolverTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/CordaClassResolverTests.kt @@ -271,6 +271,7 @@ class CordaClassResolverTests { } open class SubHashSet : HashSet() + @Test fun `Check blacklisted subclass`() { expectedEx.expect(IllegalStateException::class.java) @@ -281,6 +282,7 @@ class CordaClassResolverTests { } class SubSubHashSet : SubHashSet() + @Test fun `Check blacklisted subsubclass`() { expectedEx.expect(IllegalStateException::class.java) @@ -291,6 +293,7 @@ class CordaClassResolverTests { } class ConnectionImpl(private val connection: Connection) : Connection by connection + @Test fun `Check blacklisted interface impl`() { expectedEx.expect(IllegalStateException::class.java) @@ -302,6 +305,7 @@ class CordaClassResolverTests { interface SubConnection : Connection class SubConnectionImpl(private val subConnection: SubConnection) : SubConnection by subConnection + @Test fun `Check blacklisted super-interface impl`() { expectedEx.expect(IllegalStateException::class.java) @@ -320,6 +324,7 @@ class CordaClassResolverTests { @CordaSerializable class CordaSerializableHashSet : HashSet() + @Test fun `Check blacklist precedes CordaSerializable`() { expectedEx.expect(IllegalStateException::class.java) diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/KryoTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/KryoTests.kt index bf9c157c86..d6cb313f88 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/KryoTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/KryoTests.kt @@ -188,10 +188,10 @@ class KryoTests : TestDependencyInjectionBase() { @Test fun `serialize - deserialize PrivacySalt`() { val expected = PrivacySalt(byteArrayOf( - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32 + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32 )) val serializedBytes = expected.serialize(factory, context) val actual = serializedBytes.deserialize(factory, context) @@ -267,7 +267,7 @@ class KryoTests : TestDependencyInjectionBase() { assertEquals(exception.message, exception2.message) assertEquals(1, exception2.suppressed.size) - assertNotNull({ exception2.suppressed.find { it.message == toBeSuppressedOnSenderSide.message }}) + assertNotNull({ exception2.suppressed.find { it.message == toBeSuppressedOnSenderSide.message } }) val toBeSuppressedOnReceiverSide = IllegalStateException("bazz2") exception2.addSuppressed(toBeSuppressedOnReceiverSide) diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/ListsSerializationTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/ListsSerializationTest.kt index f8d281392b..ede793b2be 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/ListsSerializationTest.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/ListsSerializationTest.kt @@ -22,12 +22,12 @@ class ListsSerializationTest : TestDependencyInjectionBase() { private companion object { val javaEmptyListClass = Collections.emptyList().javaClass - fun verifyEnvelope(serBytes: SerializedBytes, envVerBody: (Envelope) -> Unit) = - amqpSpecific("AMQP specific envelope verification") { - val context = SerializationFactory.defaultFactory.defaultContext - val envelope = DeserializationInput(SerializerFactory(context.whitelist, context.deserializationClassLoader)).getEnvelope(serBytes) - envVerBody(envelope) - } + fun verifyEnvelope(serBytes: SerializedBytes, envVerBody: (Envelope) -> Unit) = + amqpSpecific("AMQP specific envelope verification") { + val context = SerializationFactory.defaultFactory.defaultContext + val envelope = DeserializationInput(SerializerFactory(context.whitelist, context.deserializationClassLoader)).getEnvelope(serBytes) + envVerBody(envelope) + } } @Test @@ -54,7 +54,7 @@ class ListsSerializationTest : TestDependencyInjectionBase() { } @Test - fun `check empty list serialises as Java emptyList`() = kryoSpecific("Kryo specific test"){ + fun `check empty list serialises as Java emptyList`() = kryoSpecific("Kryo specific test") { val nameID = 0 val serializedForm = emptyList().serialize() val output = ByteArrayOutputStream().apply { @@ -86,7 +86,7 @@ class ListsSerializationTest : TestDependencyInjectionBase() { data class Child(val value: Int) : Parent @CordaSerializable - data class CovariantContainer(val payload: List) + data class CovariantContainer(val payload: List) @Test fun `check covariance`() { @@ -99,11 +99,11 @@ class ListsSerializationTest : TestDependencyInjectionBase() { envelope.schema.types.single { typeNotation -> typeNotation.name == java.util.List::class.java.name + "" } } - assertEqualAfterRoundTripSerialization(container, {bytes -> verifyEnvelope(bytes, ::verifyEnvelopeBody)}) + assertEqualAfterRoundTripSerialization(container, { bytes -> verifyEnvelope(bytes, ::verifyEnvelopeBody) }) } } -internal inline fun assertEqualAfterRoundTripSerialization(obj: T, noinline streamValidation: ((SerializedBytes) -> Unit)? = null) { +internal inline fun assertEqualAfterRoundTripSerialization(obj: T, noinline streamValidation: ((SerializedBytes) -> Unit)? = null) { val serializedForm: SerializedBytes = obj.serialize() streamValidation?.invoke(serializedForm) diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/SerializationTokenTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/SerializationTokenTest.kt index 2c8a337035..909f672fde 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/SerializationTokenTest.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/SerializationTokenTest.kt @@ -12,7 +12,7 @@ import org.junit.Before import org.junit.Test import java.io.ByteArrayOutputStream -class SerializationTokenTest : TestDependencyInjectionBase() { +class SerializationTokenTest : TestDependencyInjectionBase() { private lateinit var factory: SerializationFactory private lateinit var context: SerializationContext @@ -58,7 +58,7 @@ class SerializationTokenTest : TestDependencyInjectionBase() { val testContext = this.context.withTokenContext(context) val serializedBytes = tokenizableBefore.serialize(factory, testContext) val tokenizableAfter = serializedBytes.deserialize(factory, testContext) - assertThat(tokenizableAfter).isSameAs(tokenizableBefore) + assertThat(tokenizableAfter).isSameAs(tokenizableBefore) } @Test(expected = UnsupportedOperationException::class) @@ -92,11 +92,11 @@ class SerializationTokenTest : TestDependencyInjectionBase() { val kryo: Kryo = DefaultKryoCustomizer.customize(CordaKryo(CordaClassResolver(this.context))) val stream = ByteArrayOutputStream() - Output(stream).use { - it.write(KryoHeaderV0_1.bytes) - kryo.writeClass(it, SingletonSerializeAsToken::class.java) - kryo.writeObject(it, emptyList()) - } + Output(stream).use { + it.write(KryoHeaderV0_1.bytes) + kryo.writeClass(it, SingletonSerializeAsToken::class.java) + kryo.writeObject(it, emptyList()) + } val serializedBytes = SerializedBytes(stream.toByteArray()) serializedBytes.deserialize(factory, testContext) } @@ -105,6 +105,7 @@ class SerializationTokenTest : TestDependencyInjectionBase() { object UnitSerializationToken : SerializationToken { override fun fromToken(context: SerializeAsTokenContext): Any = UnitSerializeAsToken() } + override fun toToken(context: SerializeAsTokenContext): SerializationToken = UnitSerializationToken } diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializeMapTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializeMapTests.kt index 8314286d12..68e106fd89 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializeMapTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializeMapTests.kt @@ -17,25 +17,28 @@ class DeserializeMapTests { @Test fun mapTest() { data class C(val c: Map) - val c = C (mapOf("A" to 1, "B" to 2)) + + val c = C(mapOf("A" to 1, "B" to 2)) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) DeserializationInput(sf).deserialize(serialisedBytes) } - @Test(expected=java.io.NotSerializableException::class) + @Test(expected = java.io.NotSerializableException::class) fun abstractMapFromMapOf() { data class C(val c: AbstractMap) - val c = C (mapOf("A" to 1, "B" to 2) as AbstractMap) + + val c = C(mapOf("A" to 1, "B" to 2) as AbstractMap) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) DeserializationInput(sf).deserialize(serialisedBytes) } - @Test(expected=java.io.NotSerializableException::class) + @Test(expected = java.io.NotSerializableException::class) fun abstractMapFromTreeMap() { data class C(val c: AbstractMap) - val c = C (TreeMap(mapOf("A" to 1, "B" to 2))) + + val c = C(TreeMap(mapOf("A" to 1, "B" to 2))) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) DeserializationInput(sf).deserialize(serialisedBytes) @@ -44,7 +47,8 @@ class DeserializeMapTests { @Test fun sortedMapTest() { data class C(val c: SortedMap) - val c = C(sortedMapOf ("A" to 1, "B" to 2)) + + val c = C(sortedMapOf("A" to 1, "B" to 2)) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) DeserializationInput(sf).deserialize(serialisedBytes) } @@ -52,7 +56,8 @@ class DeserializeMapTests { @Test fun navigableMapTest() { data class C(val c: NavigableMap) - val c = C(TreeMap (mapOf("A" to 1, "B" to 2)).descendingMap()) + + val c = C(TreeMap(mapOf("A" to 1, "B" to 2)).descendingMap()) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) DeserializationInput(sf).deserialize(serialisedBytes) @@ -61,9 +66,10 @@ class DeserializeMapTests { @Test fun dictionaryTest() { data class C(val c: Dictionary) - val v : Hashtable = Hashtable() - v.put ("a", 1) - v.put ("b", 2) + + val v: Hashtable = Hashtable() + v.put("a", 1) + v.put("b", 2) val c = C(v) // expected to throw @@ -74,9 +80,10 @@ class DeserializeMapTests { @Test fun hashtableTest() { data class C(val c: Hashtable) - val v : Hashtable = Hashtable() - v.put ("a", 1) - v.put ("b", 2) + + val v: Hashtable = Hashtable() + v.put("a", 1) + v.put("b", 2) val c = C(v) // expected to throw @@ -86,8 +93,9 @@ class DeserializeMapTests { @Test fun hashMapTest() { - data class C(val c : HashMap) - val c = C (HashMap (mapOf("A" to 1, "B" to 2))) + data class C(val c: HashMap) + + val c = C(HashMap(mapOf("A" to 1, "B" to 2))) // expect this to throw Assertions.assertThatThrownBy { TestSerializationOutput(VERBOSE, sf).serialize(c) } @@ -96,8 +104,9 @@ class DeserializeMapTests { @Test fun weakHashMapTest() { - data class C(val c : WeakHashMap) - val c = C (WeakHashMap (mapOf("A" to 1, "B" to 2))) + data class C(val c: WeakHashMap) + + val c = C(WeakHashMap(mapOf("A" to 1, "B" to 2))) Assertions.assertThatThrownBy { TestSerializationOutput(VERBOSE, sf).serialize(c) } .isInstanceOf(IllegalArgumentException::class.java).hasMessageContaining("Weak references with map types not supported. Suggested fix: use java.util.LinkedHashMap instead.") @@ -106,7 +115,8 @@ class DeserializeMapTests { @Test fun concreteTreeMapTest() { data class C(val c: TreeMap) - val c = C(TreeMap (mapOf("A" to 1, "B" to 3))) + + val c = C(TreeMap(mapOf("A" to 1, "B" to 3))) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) DeserializationInput(sf).deserialize(serialisedBytes) @@ -114,8 +124,9 @@ class DeserializeMapTests { @Test fun concreteLinkedHashMapTest() { - data class C(val c : LinkedHashMap) - val c = C (LinkedHashMap (mapOf("A" to 1, "B" to 2))) + data class C(val c: LinkedHashMap) + + val c = C(LinkedHashMap(mapOf("A" to 1, "B" to 2))) val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c) DeserializationInput(sf).deserialize(serialisedBytes) diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializeSimpleTypesTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializeSimpleTypesTests.kt index cc05b9b39f..4c5c9311ec 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializeSimpleTypesTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/DeserializeSimpleTypesTests.kt @@ -402,7 +402,8 @@ class DeserializeSimpleTypesTests { @Test fun arrayOfArrayOfInt() { class C(val c: Array>) - val c = C (arrayOf (arrayOf(1,2,3), arrayOf(4,5,6))) + + val c = C(arrayOf(arrayOf(1, 2, 3), arrayOf(4, 5, 6))) val serialisedC = TestSerializationOutput(VERBOSE, sf1).serialize(c) val deserializedC = DeserializationInput(sf1).deserialize(serialisedC) @@ -421,7 +422,8 @@ class DeserializeSimpleTypesTests { @Test fun arrayOfIntArray() { class C(val c: Array) - val c = C (arrayOf (IntArray(3), IntArray(3))) + + val c = C(arrayOf(IntArray(3), IntArray(3))) c.c[0][0] = 1; c.c[0][1] = 2; c.c[0][2] = 3 c.c[1][0] = 4; c.c[1][1] = 5; c.c[1][2] = 6 @@ -444,22 +446,32 @@ class DeserializeSimpleTypesTests { class C(val c: Array>) val c = C(arrayOf(arrayOf(IntArray(3), IntArray(3), IntArray(3)), - arrayOf(IntArray(3), IntArray(3), IntArray(3)), - arrayOf(IntArray(3), IntArray(3), IntArray(3)))) + arrayOf(IntArray(3), IntArray(3), IntArray(3)), + arrayOf(IntArray(3), IntArray(3), IntArray(3)))) - for (i in 0..2) { for (j in 0..2) { for (k in 0..2) { c.c[i][j][k] = i + j + k } } } + for (i in 0..2) { + for (j in 0..2) { + for (k in 0..2) { + c.c[i][j][k] = i + j + k + } + } + } val serialisedC = TestSerializationOutput(VERBOSE, sf1).serialize(c) val deserializedC = DeserializationInput(sf1).deserialize(serialisedC) - for (i in 0..2) { for (j in 0..2) { for (k in 0..2) { - assertEquals(c.c[i][j][k], deserializedC.c[i][j][k]) - }}} + for (i in 0..2) { + for (j in 0..2) { + for (k in 0..2) { + assertEquals(c.c[i][j][k], deserializedC.c[i][j][k]) + } + } + } } @Test fun nestedRepeatedTypes() { - class A(val a : A?, val b: Int) + class A(val a: A?, val b: Int) var a = A(A(A(A(A(null, 1), 2), 3), 4), 5) diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumTests.kt index d10152baf0..1f20ac013f 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumTests.kt @@ -49,7 +49,7 @@ class EnumTests { } - enum class BrasWithInit (val someList: List) { + enum class BrasWithInit(val someList: List) { TSHIRT(emptyList()), UNDERWIRE(listOf(1, 2, 3)), PUSHUP(listOf(100, 200)), @@ -90,7 +90,7 @@ class EnumTests { assertEquals(8, schema_bras.choices.size) Bras.values().forEach { val bra = it - assertNotNull (schema_bras.choices.find { it.name == bra.name }) + assertNotNull(schema_bras.choices.find { it.name == bra.name }) } } @@ -115,7 +115,7 @@ class EnumTests { assertEquals(8, schema_bras.choices.size) Bras.values().forEach { val bra = it - assertNotNull (schema_bras.choices.find { it.name == bra.name }) + assertNotNull(schema_bras.choices.find { it.name == bra.name }) } // Test the actual deserialised object @@ -124,13 +124,13 @@ class EnumTests { @Test fun multiEnum() { - data class Support (val top: Bras, val day : DayOfWeek) - data class WeeklySupport (val tops: List) + data class Support(val top: Bras, val day: DayOfWeek) + data class WeeklySupport(val tops: List) - val week = WeeklySupport (listOf( - Support (Bras.PUSHUP, DayOfWeek.MONDAY), - Support (Bras.UNDERWIRE, DayOfWeek.WEDNESDAY), - Support (Bras.PADDED, DayOfWeek.SUNDAY))) + val week = WeeklySupport(listOf( + Support(Bras.PUSHUP, DayOfWeek.MONDAY), + Support(Bras.UNDERWIRE, DayOfWeek.WEDNESDAY), + Support(Bras.PADDED, DayOfWeek.SUNDAY))) val obj = DeserializationInput(sf1).deserialize(TestSerializationOutput(VERBOSE, sf1).serialize(week)) @@ -146,7 +146,7 @@ class EnumTests { fun enumWithInit() { data class C(val c: BrasWithInit) - val c = C (BrasWithInit.PUSHUP) + val c = C(BrasWithInit.PUSHUP) val obj = DeserializationInput(sf1).deserialize(TestSerializationOutput(VERBOSE, sf1).serialize(c)) assertEquals(c.c, obj.c) @@ -157,7 +157,7 @@ class EnumTests { val path = EnumTests::class.java.getResource("EnumTests.changedEnum1") val f = File(path.toURI()) - data class C (val a: OldBras) + data class C(val a: OldBras) // Original version of the class for the serialised version of this class // @@ -177,7 +177,7 @@ class EnumTests { val path = EnumTests::class.java.getResource("EnumTests.changedEnum2") val f = File(path.toURI()) - data class C (val a: OldBras2) + data class C(val a: OldBras2) // DO NOT CHANGE THIS, it's important we serialise with a value that doesn't // change position in the upated enum class @@ -197,9 +197,9 @@ class EnumTests { @Test fun enumNotWhitelistedFails() { - data class C (val c: Bras) + data class C(val c: Bras) - class WL (val allowed: String): ClassWhitelist { + class WL(val allowed: String) : ClassWhitelist { override fun hasListed(type: Class<*>): Boolean { return type.name == allowed } @@ -214,7 +214,7 @@ class EnumTests { @Test fun enumWhitelisted() { - data class C (val c: Bras) + data class C(val c: Bras) class WL : ClassWhitelist { override fun hasListed(type: Class<*>): Boolean { @@ -231,7 +231,7 @@ class EnumTests { @Test fun enumAnnotated() { - @CordaSerializable data class C (val c: AnnotatedBras) + @CordaSerializable data class C(val c: AnnotatedBras) class WL : ClassWhitelist { override fun hasListed(type: Class<*>) = false @@ -245,21 +245,21 @@ class EnumTests { @Test fun deserializeNonWhitlistedEnum() { - data class C (val c: Bras) + data class C(val c: Bras) - class WL (val allowed: List) : ClassWhitelist { + class WL(val allowed: List) : ClassWhitelist { override fun hasListed(type: Class<*>) = type.name in allowed } // first serialise the class using a context in which Bras are whitelisted - val factory = SerializerFactory(WL(listOf (classTestName("C"), + val factory = SerializerFactory(WL(listOf(classTestName("C"), "net.corda.nodeapi.internal.serialization.amqp.EnumTests\$Bras")), ClassLoader.getSystemClassLoader()) val bytes = TestSerializationOutput(VERBOSE, factory).serialize(C(Bras.UNDERWIRE)) // then take that serialised object and attempt to deserialize it in a context that // disallows the Bras enum - val factory2 = SerializerFactory(WL(listOf (classTestName("C"))), ClassLoader.getSystemClassLoader()) + val factory2 = SerializerFactory(WL(listOf(classTestName("C"))), ClassLoader.getSystemClassLoader()) Assertions.assertThatThrownBy { DeserializationInput(factory2).deserialize(bytes) }.isInstanceOf(NotSerializableException::class.java) diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EvolvabilityTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EvolvabilityTests.kt index 0bf23ae85d..cdf690029c 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EvolvabilityTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/EvolvabilityTests.kt @@ -32,7 +32,7 @@ class EvolvabilityTests { // f.writeBytes(sc.bytes) // new version of the class, in this case the order of the parameters has been swapped - data class C (val b: Int, val a: Int) + data class C(val b: Int, val a: Int) val sc2 = f.readBytes() val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) @@ -56,7 +56,7 @@ class EvolvabilityTests { // f.writeBytes(sc.bytes) // new version of the class, in this case the order of the parameters has been swapped - data class C (val b: String, val a: Int) + data class C(val b: String, val a: Int) val sc2 = f.readBytes() val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) @@ -79,13 +79,13 @@ class EvolvabilityTests { // f.writeBytes(sc.bytes) // println ("Path = $path") - data class C (val a: Int, val b: Int?) + data class C(val a: Int, val b: Int?) val sc2 = f.readBytes() val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) - assertEquals (A, deserializedC.a) - assertEquals (null, deserializedC.b) + assertEquals(A, deserializedC.a) + assertEquals(null, deserializedC.b) } @Test(expected = NotSerializableException::class) @@ -104,7 +104,7 @@ class EvolvabilityTests { // println ("Path = $path") // new version of the class, in this case a new parameter has been added (b) - data class C (val a: Int, val b: Int) + data class C(val a: Int, val b: Int) val sc2 = f.readBytes() @@ -132,13 +132,13 @@ class EvolvabilityTests { // f.writeBytes(scc.bytes) // println ("Path = $path") - data class CC (val b: String, val d: Int) + data class CC(val b: String, val d: Int) val sc2 = f.readBytes() val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) - assertEquals (B, deserializedCC.b) - assertEquals (D, deserializedCC.d) + assertEquals(B, deserializedCC.b) + assertEquals(D, deserializedCC.d) } @Suppress("UNUSED_VARIABLE") @@ -185,16 +185,16 @@ class EvolvabilityTests { // println ("Path = $path") @Suppress("UNUSED") - data class CC (val a: Int, val b: String) { + data class CC(val a: Int, val b: String) { @DeprecatedConstructorForDeserialization(1) - constructor (a: Int) : this (a, "hello") + constructor (a: Int) : this(a, "hello") } val sc2 = f.readBytes() val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) - assertEquals (A, deserializedCC.a) - assertEquals ("hello", deserializedCC.b) + assertEquals(A, deserializedCC.a) + assertEquals("hello", deserializedCC.b) } @Test(expected = NotSerializableException::class) @@ -214,9 +214,9 @@ class EvolvabilityTests { // f.writeBytes(scc.bytes) // println ("Path = $path") - data class CC (val a: Int, val b: String) { + data class CC(val a: Int, val b: String) { // constructor annotation purposefully omitted - constructor (a: Int) : this (a, "hello") + constructor (a: Int) : this(a, "hello") } // we expect this to throw as we should not find any constructors @@ -242,20 +242,20 @@ class EvolvabilityTests { // println ("Path = $path") @Suppress("UNUSED") - data class CC (val a: Int, val b: Int, val c: String, val d: String) { + data class CC(val a: Int, val b: Int, val c: String, val d: String) { // ensure none of the original parameters align with the initial // construction order @DeprecatedConstructorForDeserialization(1) - constructor (c: String, a: Int, b: Int) : this (a, b, c, "wibble") + constructor (c: String, a: Int, b: Int) : this(a, b, c, "wibble") } val sc2 = f.readBytes() val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) - assertEquals (A, deserializedCC.a) - assertEquals (B, deserializedCC.b) - assertEquals (C, deserializedCC.c) - assertEquals ("wibble", deserializedCC.d) + assertEquals(A, deserializedCC.a) + assertEquals(B, deserializedCC.b) + assertEquals(C, deserializedCC.c) + assertEquals("wibble", deserializedCC.d) } @Test @@ -277,20 +277,20 @@ class EvolvabilityTests { // println ("Path = $path") // b is removed, d is added - data class CC (val a: Int, val c: String, val d: String) { + data class CC(val a: Int, val c: String, val d: String) { // ensure none of the original parameters align with the initial // construction order @Suppress("UNUSED") @DeprecatedConstructorForDeserialization(1) - constructor (c: String, a: Int) : this (a, c, "wibble") + constructor (c: String, a: Int) : this(a, c, "wibble") } val sc2 = f.readBytes() val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) - assertEquals (A, deserializedCC.a) - assertEquals (C, deserializedCC.c) - assertEquals ("wibble", deserializedCC.d) + assertEquals(A, deserializedCC.a) + assertEquals(C, deserializedCC.c) + assertEquals("wibble", deserializedCC.d) } @Test @@ -322,13 +322,15 @@ class EvolvabilityTests { // println ("Path = $path1") @Suppress("UNUSED") - data class C (val e: Int, val c: Int, val b: Int, val a: Int, val d: Int) { + data class C(val e: Int, val c: Int, val b: Int, val a: Int, val d: Int) { @DeprecatedConstructorForDeserialization(1) - constructor (b: Int, a: Int) : this (-1, -1, b, a, -1) + constructor (b: Int, a: Int) : this(-1, -1, b, a, -1) + @DeprecatedConstructorForDeserialization(2) - constructor (a: Int, c: Int, b: Int) : this (-1, c, b, a, -1) + constructor (a: Int, c: Int, b: Int) : this(-1, c, b, a, -1) + @DeprecatedConstructorForDeserialization(3) - constructor (a: Int, b: Int, c: Int, d: Int) : this (-1, c, b, a, d) + constructor (a: Int, b: Int, c: Int, d: Int) : this(-1, c, b, a, d) } val sb1 = File(path1.toURI()).readBytes() @@ -376,15 +378,16 @@ class EvolvabilityTests { // println ("Path = $path") // Add a parameter to inner but keep outer unchanged - data class Inner (val a: Int, val b: String?) - data class Outer (val a: Int, val b: Inner) + data class Inner(val a: Int, val b: String?) + + data class Outer(val a: Int, val b: Inner) val sc2 = f.readBytes() val outer = DeserializationInput(sf).deserialize(SerializedBytes(sc2)) - assertEquals (oa, outer.a) - assertEquals (ia, outer.b.a) - assertEquals (null, outer.b.b) + assertEquals(oa, outer.a) + assertEquals(ia, outer.b.a) + assertEquals(null, outer.b.b) } @Test @@ -416,15 +419,18 @@ class EvolvabilityTests { // println ("Path = $path1") @Suppress("UNUSED") - data class C (val b: Int, val c: Int, val d: Int, val e: Int, val f: Int, val g: Int) { + data class C(val b: Int, val c: Int, val d: Int, val e: Int, val f: Int, val g: Int) { @DeprecatedConstructorForDeserialization(1) - constructor (b: Int, c: Int) : this (b, c, -1, -1, -1, -1) + constructor (b: Int, c: Int) : this(b, c, -1, -1, -1, -1) + @DeprecatedConstructorForDeserialization(2) - constructor (b: Int, c: Int, d: Int) : this (b, c, d, -1, -1, -1) + constructor (b: Int, c: Int, d: Int) : this(b, c, d, -1, -1, -1) + @DeprecatedConstructorForDeserialization(3) - constructor (b: Int, c: Int, d: Int, e: Int) : this (b, c, d, e, -1, -1) + constructor (b: Int, c: Int, d: Int, e: Int) : this(b, c, d, e, -1, -1) + @DeprecatedConstructorForDeserialization(4) - constructor (b: Int, c: Int, d: Int, e: Int, f: Int) : this (b, c, d, e, f, -1) + constructor (b: Int, c: Int, d: Int, e: Int, f: Int) : this(b, c, d, e, f, -1) } val sb1 = File(path1.toURI()).readBytes() diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt index 05cd84c934..4b1011ad49 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt @@ -50,7 +50,7 @@ class SerializationOutputTests { data class testShort(val s: Short) - data class testBoolean(val b : Boolean) + data class testBoolean(val b: Boolean) interface FooInterface { val pub: Int @@ -145,13 +145,13 @@ class SerializationOutputTests { data class PolymorphicProperty(val foo: FooInterface?) - private inline fun serdes(obj: T, - factory: SerializerFactory = SerializerFactory ( - AllWhitelist, ClassLoader.getSystemClassLoader()), - freshDeserializationFactory: SerializerFactory = SerializerFactory( - AllWhitelist, ClassLoader.getSystemClassLoader()), - expectedEqual: Boolean = true, - expectDeserializedEqual: Boolean = true): T { + private inline fun serdes(obj: T, + factory: SerializerFactory = SerializerFactory( + AllWhitelist, ClassLoader.getSystemClassLoader()), + freshDeserializationFactory: SerializerFactory = SerializerFactory( + AllWhitelist, ClassLoader.getSystemClassLoader()), + expectedEqual: Boolean = true, + expectDeserializedEqual: Boolean = true): T { val ser = SerializationOutput(factory) val bytes = ser.serialize(obj) @@ -446,10 +446,10 @@ class SerializationOutputTests { try { try { throw IOException("Layer 1") - } catch(t: Throwable) { + } catch (t: Throwable) { throw IllegalStateException("Layer 2", t) } - } catch(t: Throwable) { + } catch (t: Throwable) { val desThrowable = serdesThrowableWithInternalInfo(t, factory, factory2, false) assertSerializedThrowableEquivalent(t, desThrowable) } @@ -476,12 +476,12 @@ class SerializationOutputTests { try { try { throw IOException("Layer 1") - } catch(t: Throwable) { + } catch (t: Throwable) { val e = IllegalStateException("Layer 2") e.addSuppressed(t) throw e } - } catch(t: Throwable) { + } catch (t: Throwable) { val desThrowable = serdesThrowableWithInternalInfo(t, factory, factory2, false) assertSerializedThrowableEquivalent(t, desThrowable) } @@ -535,6 +535,7 @@ class SerializationOutputTests { } val FOO_PROGRAM_ID = "net.corda.nodeapi.internal.serialization.amqp.SerializationOutputTests.FooContract" + class FooState : ContractState { override val participants: List = emptyList() } diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializeAndReturnSchemaTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializeAndReturnSchemaTest.kt index 86b769a14f..acd8c5b8fe 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializeAndReturnSchemaTest.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializeAndReturnSchemaTest.kt @@ -19,6 +19,7 @@ class SerializeAndReturnSchemaTest { @Test fun getSchema() { data class C(val a: Int, val b: Int) + val a = 1 val b = 2 diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/StaticInitialisationOfSerializedObjectTest.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/StaticInitialisationOfSerializedObjectTest.kt index 47decde9c0..2533bdf182 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/StaticInitialisationOfSerializedObjectTest.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/StaticInitialisationOfSerializedObjectTest.kt @@ -12,7 +12,7 @@ import java.lang.reflect.Type import java.util.concurrent.ConcurrentHashMap import kotlin.test.assertEquals -class InStatic : Exception ("Help!, help!, I'm being repressed") +class InStatic : Exception("Help!, help!, I'm being repressed") class C { companion object { @@ -28,7 +28,7 @@ class C { // comment out the companion object from here, comment out the test code and uncomment // the generation code, then re-run the test and copy the file shown in the output print // to the resource directory -class C2 (var b: Int) { +class C2(var b: Int) { /* companion object { init { @@ -39,14 +39,14 @@ class C2 (var b: Int) { } class StaticInitialisationOfSerializedObjectTest { - @Test(expected=java.lang.ExceptionInInitializerError::class) + @Test(expected = java.lang.ExceptionInInitializerError::class) fun itBlowsUp() { C() } @Test fun KotlinObjectWithCompanionObject() { - data class D (val c : C) + data class D(val c: C) val sf = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader()) @@ -71,7 +71,7 @@ class StaticInitialisationOfSerializedObjectTest { @Test fun deserializeTest() { - data class D (val c : C2) + data class D(val c: C2) val path = EvolvabilityTests::class.java.getResource("StaticInitialisationOfSerializedObjectTest.deserializeTest") val f = File(path.toURI()) @@ -86,7 +86,7 @@ class StaticInitialisationOfSerializedObjectTest { class WL : ClassWhitelist { override fun hasListed(type: Class<*>) = type.name == "net.corda.nodeapi.internal.serialization.amqp" + - ".StaticInitialisationOfSerializedObjectTest\$deserializeTest\$D" + ".StaticInitialisationOfSerializedObjectTest\$deserializeTest\$D" } val sf2 = SerializerFactory(WL(), ClassLoader.getSystemClassLoader()) @@ -100,14 +100,14 @@ class StaticInitialisationOfSerializedObjectTest { // Version of a serializer factory that will allow the class carpenter living on the // factory to have a different whitelist applied to it than the factory class TestSerializerFactory(wl1: ClassWhitelist, wl2: ClassWhitelist) : - SerializerFactory (wl1, ClassLoader.getSystemClassLoader()) { + SerializerFactory(wl1, ClassLoader.getSystemClassLoader()) { override val classCarpenter = ClassCarpenter(ClassLoader.getSystemClassLoader(), wl2) } // This time have the serilization factory and the carpenter use different whitelists @Test fun deserializeTest2() { - data class D (val c : C2) + data class D(val c: C2) val path = EvolvabilityTests::class.java.getResource("StaticInitialisationOfSerializedObjectTest.deserializeTest2") val f = File(path.toURI()) diff --git a/node/src/integration-test/kotlin/net/corda/node/BootTests.kt b/node/src/integration-test/kotlin/net/corda/node/BootTests.kt index c61ad1cca9..4b5c17a069 100644 --- a/node/src/integration-test/kotlin/net/corda/node/BootTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/BootTests.kt @@ -32,7 +32,7 @@ class BootTests { driver { val user = User("u", "p", setOf(startFlowPermission())) val future = startNode(rpcUsers = listOf(user)).getOrThrow().rpcClientToNode(). - start(user.username, user.password).proxy.startFlow(::ObjectInputStreamFlow).returnValue + start(user.username, user.password).proxy.startFlow(::ObjectInputStreamFlow).returnValue assertThatThrownBy { future.getOrThrow() }.isInstanceOf(InvalidClassException::class.java).hasMessage("filter status: REJECTED") } } diff --git a/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt b/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt index a46856b2ce..50788582b5 100644 --- a/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt @@ -36,7 +36,7 @@ class CordappScanningDriverTest { @StartableByRPC @InitiatingFlow - class ReceiveFlow(val otherParty: Party) :FlowLogic() { + class ReceiveFlow(val otherParty: Party) : FlowLogic() { @Suspendable override fun call(): String = initiateFlow(otherParty).receive().unwrap { it } } diff --git a/node/src/integration-test/kotlin/net/corda/node/NodeStartupPerformanceTests.kt b/node/src/integration-test/kotlin/net/corda/node/NodeStartupPerformanceTests.kt index a6aef9b4fd..2f29d8df6d 100644 --- a/node/src/integration-test/kotlin/net/corda/node/NodeStartupPerformanceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/NodeStartupPerformanceTests.kt @@ -17,7 +17,7 @@ class NodeStartupPerformanceTests { driver(networkMapStartStrategy = NetworkMapStartStrategy.Dedicated(startAutomatically = false)) { startDedicatedNetworkMapService().get() val times = ArrayList() - for (i in 1 .. 10) { + for (i in 1..10) { val time = Stopwatch.createStarted().apply { startNode().get() }.stop().elapsed(TimeUnit.MICROSECONDS) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt index bb177abfd9..e5a79d7d5c 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/AttachmentLoadingTests.kt @@ -70,7 +70,7 @@ class AttachmentLoadingTests : TestDependencyInjectionBase() { val contract = contractClass.newInstance() val txBuilder = generateInitialMethod.invoke(contract, PartyAndReference(DUMMY_BANK_A, OpaqueBytes(kotlin.ByteArray(1))), 1, DUMMY_NOTARY) as TransactionBuilder val context = SerializationFactory.defaultFactory.defaultContext - .withClassLoader(appClassLoader) + .withClassLoader(appClassLoader) val ledgerTx = txBuilder.toLedgerTransaction(services, context) contract.verify(ledgerTx) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt index f845395020..268d23d394 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/network/NodeInfoWatcherTest.kt @@ -29,11 +29,13 @@ import kotlin.test.assertTrue class NodeInfoWatcherTest : NodeBasedTest() { - @Rule @JvmField var folder = TemporaryFolder() + @Rule + @JvmField + var folder = TemporaryFolder() lateinit var keyManagementService: KeyManagementService lateinit var nodeInfoPath: Path - val scheduler = TestScheduler(); + val scheduler = TestScheduler() val testSubscriber = TestSubscriber() // Object under test diff --git a/node/src/integration-test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt index 465fb72229..fae4c25c51 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt @@ -170,8 +170,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { (customRetryIntervalMs?.let { mapOf("activeMQServer.bridge.retryIntervalMs" to it.toString()) } ?: emptyMap()) if (party == DUMMY_NOTARY) { startNetworkMapNode(party.name, configOverrides = configOverrides) - } - else { + } else { startNode(party.name, configOverrides = configOverrides, noNetworkMap = noNetworkMap, @@ -184,7 +183,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { private fun checkConnectivity(nodes: List>) { nodes.forEach { node1 -> nodes.forEach { node2 -> - if(!(node1 === node2)) { // Do not check connectivity to itself + if (!(node1 === node2)) { // Do not check connectivity to itself node2.internals.registerInitiatedFlow(SendBackFlow::class.java) val resultFuture = node1.services.startFlow(SendFlow(node2.info.chooseIdentity())).resultFuture assertThat(resultFuture.getOrThrow()).isEqualTo("Hello!") diff --git a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt index 0e66989f10..46ac098355 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt @@ -21,7 +21,8 @@ import kotlin.test.assertEquals * transaction size limit (which should only consider the hashes). */ class LargeTransactionsTest { - @StartableByRPC @InitiatingFlow + @StartableByRPC + @InitiatingFlow class SendLargeTransactionFlow(private val hash1: SecureHash, private val hash2: SecureHash, private val hash3: SecureHash, @@ -44,7 +45,8 @@ class LargeTransactionsTest { } } - @InitiatedBy(SendLargeTransactionFlow::class) @Suppress("UNUSED") + @InitiatedBy(SendLargeTransactionFlow::class) + @Suppress("UNUSED") class ReceiveLargeTransactionFlow(private val otherSide: FlowSession) : FlowLogic() { @Suspendable override fun call() { diff --git a/node/src/main/java/net/corda/node/shell/FlowShellCommand.java b/node/src/main/java/net/corda/node/shell/FlowShellCommand.java index 8f16381e01..4bac0ce5b5 100644 --- a/node/src/main/java/net/corda/node/shell/FlowShellCommand.java +++ b/node/src/main/java/net/corda/node/shell/FlowShellCommand.java @@ -12,11 +12,11 @@ import java.util.*; import static net.corda.node.shell.InteractiveShell.*; @Man( - "Allows you to start flows, list the ones available and to watch flows currently running on the node.\n\n" + - "Starting flow is the primary way in which you command the node to change the ledger.\n\n" + - "This command is generic, so the right way to use it depends on the flow you wish to start. You can use the 'flow start'\n" + - "command with either a full class name, or a substring of the class name that's unambiguous. The parameters to the \n" + - "flow constructors (the right one is picked automatically) are then specified using the same syntax as for the run command." + "Allows you to start flows, list the ones available and to watch flows currently running on the node.\n\n" + + "Starting flow is the primary way in which you command the node to change the ledger.\n\n" + + "This command is generic, so the right way to use it depends on the flow you wish to start. You can use the 'flow start'\n" + + "command with either a full class name, or a substring of the class name that's unambiguous. The parameters to the \n" + + "flow constructors (the right one is picked automatically) are then specified using the same syntax as for the run command." ) public class FlowShellCommand extends InteractiveShellCommand { @Command diff --git a/node/src/main/java/net/corda/node/shell/RunShellCommand.java b/node/src/main/java/net/corda/node/shell/RunShellCommand.java index c388ccfe5f..108b567a9b 100644 --- a/node/src/main/java/net/corda/node/shell/RunShellCommand.java +++ b/node/src/main/java/net/corda/node/shell/RunShellCommand.java @@ -13,10 +13,10 @@ import java.util.*; public class RunShellCommand extends InteractiveShellCommand { @Command @Man( - "Runs a method from the CordaRPCOps interface, which is the same interface exposed to RPC clients.\n\n" + + "Runs a method from the CordaRPCOps interface, which is the same interface exposed to RPC clients.\n\n" + - "You can learn more about what commands are available by typing 'run' just by itself, or by\n" + - "consulting the developer guide at https://docs.corda.net/api/kotlin/corda/net.corda.core.messaging/-corda-r-p-c-ops/index.html" + "You can learn more about what commands are available by typing 'run' just by itself, or by\n" + + "consulting the developer guide at https://docs.corda.net/api/kotlin/corda/net.corda.core.messaging/-corda-r-p-c-ops/index.html" ) @Usage("runs a method from the CordaRPCOps interface on the node.") public Object main( diff --git a/node/src/main/kotlin/net/corda/node/ArgsParser.kt b/node/src/main/kotlin/net/corda/node/ArgsParser.kt index db175ea2b7..7139055566 100644 --- a/node/src/main/kotlin/net/corda/node/ArgsParser.kt +++ b/node/src/main/kotlin/net/corda/node/ArgsParser.kt @@ -69,8 +69,8 @@ data class CmdLineOptions(val baseDirectory: Path, val isVersion: Boolean, val noLocalShell: Boolean, val sshdServer: Boolean, - val justGenerateNodeInfo : Boolean) { + val justGenerateNodeInfo: Boolean) { fun loadConfig() = ConfigHelper - .loadConfig(baseDirectory, configFile) - .parseAs() + .loadConfig(baseDirectory, configFile) + .parseAs() } diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index 640ac65389..779604259d 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -277,7 +277,7 @@ abstract class AbstractNode(config: NodeConfiguration, /** * This customizes the ServiceHub for each CordaService that is initiating flows */ - private class AppServiceHubImpl(val serviceHub: ServiceHubInternal): AppServiceHub, ServiceHub by serviceHub { + private class AppServiceHubImpl(val serviceHub: ServiceHubInternal) : AppServiceHub, ServiceHub by serviceHub { lateinit var serviceInstance: T override fun startTrackedFlow(flow: FlowLogic): FlowProgressHandle { val stateMachine = startFlowChecked(flow) diff --git a/node/src/main/kotlin/net/corda/node/internal/Node.kt b/node/src/main/kotlin/net/corda/node/internal/Node.kt index adf92b70c1..696098df29 100644 --- a/node/src/main/kotlin/net/corda/node/internal/Node.kt +++ b/node/src/main/kotlin/net/corda/node/internal/Node.kt @@ -349,7 +349,7 @@ open class Node(override val configuration: FullNodeConfiguration, _startupComplete.set(Unit) } }, - { th -> logger.error("Unexpected exception", th)} + { th -> logger.error("Unexpected exception", th) } ) shutdownHook = addShutdownHook { stop() diff --git a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt index 631361cd04..2294024e90 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt @@ -110,14 +110,14 @@ open class NodeStartup(val args: Array) { startedNode.internals.startupComplete.then { try { InteractiveShell.startShell(cmdlineOptions.baseDirectory, runShell, cmdlineOptions.sshdServer, startedNode) - } catch(e: Throwable) { + } catch (e: Throwable) { logger.error("Shell failed to start", e) } } }, - { - th -> logger.error("Unexpected exception during registration", th) - }) + { th -> + logger.error("Unexpected exception during registration", th) + }) startedNode.internals.run() } diff --git a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt index e1cec24244..493b965ba6 100644 --- a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt +++ b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt @@ -111,7 +111,7 @@ class CordappLoader private constructor(private val cordappJarPaths: List) /** Takes a package of classes and creates a JAR from them - only use in tests. */ private fun createDevCordappJar(scanPackage: String, path: URL, jarPackageName: String): URI { - if(!generatedCordapps.contains(path)) { + if (!generatedCordapps.contains(path)) { val cordappDir = File("build/tmp/generated-test-cordapps") cordappDir.mkdirs() val cordappJAR = File(cordappDir, "$scanPackage-${UUID.randomUUID()}.jar") diff --git a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappProviderImpl.kt b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappProviderImpl.kt index 9c3f58293f..967c332fd3 100644 --- a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappProviderImpl.kt +++ b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappProviderImpl.kt @@ -19,7 +19,7 @@ open class CordappProviderImpl(private val cordappLoader: CordappLoader) : Singl // TODO: Use better supported APIs in Java 9 Exception().stackTrace.forEach { stackFrame -> val cordapp = getCordappForClass(stackFrame.className) - if(cordapp != null) { + if (cordapp != null) { return getAppContext(cordapp) } } diff --git a/node/src/main/kotlin/net/corda/node/services/api/AuditService.kt b/node/src/main/kotlin/net/corda/node/services/api/AuditService.kt index b9f53f9831..127f69e3d6 100644 --- a/node/src/main/kotlin/net/corda/node/services/api/AuditService.kt +++ b/node/src/main/kotlin/net/corda/node/services/api/AuditService.kt @@ -118,6 +118,7 @@ data class FlowPermissionAuditEvent(override val timestamp: Instant, override val flowId: StateMachineRunId, val permissionRequested: String, val permissionGranted: Boolean) : AuditEvent(), FlowAuditInfo + /** * Minimal interface for recording audit information within the system. The AuditService is assumed to be available only * to trusted internal components via ServiceHubInternal. diff --git a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt index b15e768f19..95467b63bc 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt @@ -122,12 +122,13 @@ enum class CertChainPolicyType { } data class CertChainPolicyConfig(val role: String, private val policy: CertChainPolicyType, private val trustedAliases: Set) { - val certificateChainCheckPolicy: CertificateChainCheckPolicy get() { - return when (policy) { - CertChainPolicyType.Any -> CertificateChainCheckPolicy.Any - CertChainPolicyType.RootMustMatch -> CertificateChainCheckPolicy.RootMustMatch - CertChainPolicyType.LeafMustMatch -> CertificateChainCheckPolicy.LeafMustMatch - CertChainPolicyType.MustContainOneOf -> CertificateChainCheckPolicy.MustContainOneOf(trustedAliases) + val certificateChainCheckPolicy: CertificateChainCheckPolicy + get() { + return when (policy) { + CertChainPolicyType.Any -> CertificateChainCheckPolicy.Any + CertChainPolicyType.RootMustMatch -> CertificateChainCheckPolicy.RootMustMatch + CertChainPolicyType.LeafMustMatch -> CertificateChainCheckPolicy.LeafMustMatch + CertChainPolicyType.MustContainOneOf -> CertificateChainCheckPolicy.MustContainOneOf(trustedAliases) + } } - } } diff --git a/node/src/main/kotlin/net/corda/node/services/events/NodeSchedulerService.kt b/node/src/main/kotlin/net/corda/node/services/events/NodeSchedulerService.kt index 1d0b5e3d54..26a8322b80 100644 --- a/node/src/main/kotlin/net/corda/node/services/events/NodeSchedulerService.kt +++ b/node/src/main/kotlin/net/corda/node/services/events/NodeSchedulerService.kt @@ -72,7 +72,7 @@ class NodeSchedulerService(private val services: ServiceHubInternal, // to wait in our code, rather than Thread.sleep() or other time-based pauses. @Suspendable @VisibleForTesting - // We specify full classpath on SettableFuture to differentiate it from the Quasar class of the same name + // We specify full classpath on SettableFuture to differentiate it from the Quasar class of the same name fun awaitWithDeadline(clock: Clock, deadline: Instant, future: Future<*> = GuavaSettableFuture.create()): Boolean { var nanos: Long do { @@ -89,11 +89,11 @@ class NodeSchedulerService(private val services: ServiceHubInternal, try { // This will return when it times out, or when the clock mutates or when when the original future completes. originalFutureCompleted.get(nanos, TimeUnit.NANOSECONDS) - } catch(e: ExecutionException) { + } catch (e: ExecutionException) { // No need to take action as will fall out of the loop due to future.isDone - } catch(e: CancellationException) { + } catch (e: CancellationException) { // No need to take action as will fall out of the loop due to future.isDone - } catch(e: TimeoutException) { + } catch (e: TimeoutException) { // No need to take action as will fall out of the loop due to future.isDone } } @@ -111,7 +111,7 @@ class NodeSchedulerService(private val services: ServiceHubInternal, var txId = it.output.txId ?: throw IllegalStateException("DB returned null SecureHash transactionId") var index = it.output.index ?: throw IllegalStateException("DB returned null SecureHash index") Pair(StateRef(SecureHash.parse(txId), index), - ScheduledStateRef(StateRef(SecureHash.parse(txId), index), it.scheduledAt)) + ScheduledStateRef(StateRef(SecureHash.parse(txId), index), it.scheduledAt)) }, toPersistentEntity = { key: StateRef, value: ScheduledStateRef -> PersistentScheduledState().apply { @@ -152,7 +152,7 @@ class NodeSchedulerService(private val services: ServiceHubInternal, private class InnerState { var scheduledStates = createMap() - var scheduledStatesQueue: PriorityQueue = PriorityQueue( { a, b -> a.scheduledAt.compareTo(b.scheduledAt) } ) + var scheduledStatesQueue: PriorityQueue = PriorityQueue({ a, b -> a.scheduledAt.compareTo(b.scheduledAt) }) var rescheduled: GuavaSettableFuture? = null } @@ -162,7 +162,7 @@ class NodeSchedulerService(private val services: ServiceHubInternal, // We need the [StateMachineManager] to be constructed before this is called in case it schedules a flow. fun start() { mutex.locked { - scheduledStatesQueue.addAll(scheduledStates.all().map { it.second } .toMutableList()) + scheduledStatesQueue.addAll(scheduledStates.all().map { it.second }.toMutableList()) rescheduleWakeUp() } } @@ -182,7 +182,7 @@ class NodeSchedulerService(private val services: ServiceHubInternal, if (action.scheduledAt.isBefore(previousEarliest?.scheduledAt ?: Instant.MAX)) { // We are earliest rescheduleWakeUp() - } else if(previousEarliest?.ref == action.ref && previousEarliest.scheduledAt != action.scheduledAt) { + } else if (previousEarliest?.ref == action.ref && previousEarliest.scheduledAt != action.scheduledAt) { // We were earliest but might not be any more rescheduleWakeUp() } diff --git a/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt b/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt index 9ee5707a57..616e4bd8c1 100644 --- a/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt +++ b/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt @@ -30,6 +30,7 @@ class InMemoryIdentityService(identities: Iterable = emptyS constructor(wellKnownIdentities: Iterable = emptySet(), confidentialIdentities: Iterable = emptySet(), trustRoot: X509CertificateHolder) : this(wellKnownIdentities, confidentialIdentities, trustRoot.cert) + companion object { private val log = loggerFor() } @@ -45,7 +46,7 @@ class InMemoryIdentityService(identities: Iterable = emptyS init { val caCertificatesWithRoot: Set = caCertificates.toSet() + trustRoot caCertStore = CertStore.getInstance("Collection", CollectionCertStoreParameters(caCertificatesWithRoot)) - keyToParties.putAll(identities.associateBy { it.owningKey } ) + keyToParties.putAll(identities.associateBy { it.owningKey }) principalToParties.putAll(identities.associateBy { it.name }) confidentialIdentities.forEach { identity -> principalToParties.computeIfAbsent(identity.name) { identity } @@ -94,6 +95,7 @@ class InMemoryIdentityService(identities: Iterable = emptyS null } } + override fun wellKnownPartyFromAnonymous(partyRef: PartyAndReference) = wellKnownPartyFromAnonymous(partyRef.party) override fun requireWellKnownPartyFromAnonymous(party: AbstractParty): Party { return wellKnownPartyFromAnonymous(party) ?: throw IllegalStateException("Could not deanonymise party ${party.owningKey.toStringShort()}") diff --git a/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt b/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt index de1b479c1f..4645c1d8e0 100644 --- a/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt +++ b/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt @@ -48,8 +48,10 @@ class PersistentKeyManagementService(val identityService: IdentityService, fun createKeyMap(): AppendOnlyPersistentMap { return AppendOnlyPersistentMap( toPersistentEntityKey = { it.toBase58String() }, - fromPersistentEntity = { Pair(parsePublicKeyBase58(it.publicKey), - it.privateKey.deserialize(context = SerializationDefaults.STORAGE_CONTEXT)) }, + fromPersistentEntity = { + Pair(parsePublicKeyBase58(it.publicKey), + it.privateKey.deserialize(context = SerializationDefaults.STORAGE_CONTEXT)) + }, toPersistentEntity = { key: PublicKey, value: PrivateKey -> PersistentKey().apply { publicKey = key.toBase58String() @@ -81,7 +83,7 @@ class PersistentKeyManagementService(val identityService: IdentityService, override fun freshKeyAndCert(identity: PartyAndCertificate, revocationEnabled: Boolean): PartyAndCertificate = freshCertificate(identityService, freshKey(), identity, getSigner(identity.owningKey), revocationEnabled) - private fun getSigner(publicKey: PublicKey): ContentSigner = getSigner(getSigningKeyPair(publicKey)) + private fun getSigner(publicKey: PublicKey): ContentSigner = getSigner(getSigningKeyPair(publicKey)) //It looks for the PublicKey in the (potentially) CompositeKey that is ours, and then returns the associated PrivateKey to use in signing private fun getSigningKeyPair(publicKey: PublicKey): KeyPair { diff --git a/node/src/main/kotlin/net/corda/node/services/messaging/ArtemisMessagingServer.kt b/node/src/main/kotlin/net/corda/node/services/messaging/ArtemisMessagingServer.kt index b648721633..52421eb6d1 100644 --- a/node/src/main/kotlin/net/corda/node/services/messaging/ArtemisMessagingServer.kt +++ b/node/src/main/kotlin/net/corda/node/services/messaging/ArtemisMessagingServer.kt @@ -97,7 +97,8 @@ class ArtemisMessagingServer(override val config: NodeConfiguration, companion object { private val log = loggerFor() /** 10 MiB maximum allowed file size for attachments, including message headers. TODO: acquire this value from Network Map when supported. */ - @JvmStatic val MAX_FILE_SIZE = 10485760 + @JvmStatic + val MAX_FILE_SIZE = 10485760 val ipDetectRequestProperty = "ip-request-id" val ipDetectResponseProperty = "ip-address" diff --git a/node/src/main/kotlin/net/corda/node/services/messaging/NodeMessagingClient.kt b/node/src/main/kotlin/net/corda/node/services/messaging/NodeMessagingClient.kt index 410a753f10..02ee5500ec 100644 --- a/node/src/main/kotlin/net/corda/node/services/messaging/NodeMessagingClient.kt +++ b/node/src/main/kotlin/net/corda/node/services/messaging/NodeMessagingClient.kt @@ -117,10 +117,12 @@ class NodeMessagingClient(override val config: NodeConfiguration, fun createMessageToRedeliver(): PersistentMap, RetryMessage, Long> { return PersistentMap( toPersistentEntityKey = { it }, - fromPersistentEntity = { Pair(it.key, - Pair(it.message.deserialize( context = SerializationDefaults.STORAGE_CONTEXT), - it.recipients.deserialize( context = SerializationDefaults.STORAGE_CONTEXT)) - ) }, + fromPersistentEntity = { + Pair(it.key, + Pair(it.message.deserialize(context = SerializationDefaults.STORAGE_CONTEXT), + it.recipients.deserialize(context = SerializationDefaults.STORAGE_CONTEXT)) + ) + }, toPersistentEntity = { _key: Long, (_message: Message, _recipient: MessageRecipients): Pair -> RetryMessage().apply { key = _key @@ -241,7 +243,7 @@ class NodeMessagingClient(override val config: NodeConfiguration, log.info("Network map is complete, so removing filter from P2P consumer.") try { p2pConsumer!!.close() - } catch(e: ActiveMQObjectClosedException) { + } catch (e: ActiveMQObjectClosedException) { // Ignore it: this can happen if the server has gone away before we do. } p2pConsumer = makeP2PConsumer(session, false) @@ -283,8 +285,8 @@ class NodeMessagingClient(override val config: NodeConfiguration, } private fun resumeMessageRedelivery() { - messagesToRedeliver.forEach { - retryId, (message, target) -> send(message, target, retryId) + messagesToRedeliver.forEach { retryId, (message, target) -> + send(message, target, retryId) } } @@ -301,7 +303,7 @@ class NodeMessagingClient(override val config: NodeConfiguration, // It's safe to call into receive simultaneous with other threads calling send on a producer. val artemisMessage: ClientMessage = try { consumer.receive() - } catch(e: ActiveMQObjectClosedException) { + } catch (e: ActiveMQObjectClosedException) { null } ?: return false @@ -433,7 +435,7 @@ class NodeMessagingClient(override val config: NodeConfiguration, } } } - } catch(e: Exception) { + } catch (e: Exception) { log.error("Caught exception whilst executing message handler for ${msg.topicSession}", e) } return true @@ -454,7 +456,7 @@ class NodeMessagingClient(override val config: NodeConfiguration, val c = p2pConsumer ?: throw IllegalStateException("stop can't be called twice") try { c.close() - } catch(e: ActiveMQObjectClosedException) { + } catch (e: ActiveMQObjectClosedException) { // Ignore it: this can happen if the server has gone away before we do. } p2pConsumer = null diff --git a/node/src/main/kotlin/net/corda/node/services/messaging/RPCServer.kt b/node/src/main/kotlin/net/corda/node/services/messaging/RPCServer.kt index ad2eb239fa..ae4f328378 100644 --- a/node/src/main/kotlin/net/corda/node/services/messaging/RPCServer.kt +++ b/node/src/main/kotlin/net/corda/node/services/messaging/RPCServer.kt @@ -86,6 +86,7 @@ class RPCServer( private companion object { val log = loggerFor() } + private enum class State { UNSTARTED, STARTED, @@ -350,6 +351,7 @@ class RPCServer( // TODO remove this User once webserver doesn't need it private val nodeUser = User(NODE_USER, NODE_USER, setOf()) + private fun getUser(message: ClientMessage): User { val validatedUser = message.getStringProperty(Message.HDR_VALIDATED_USER) ?: throw IllegalArgumentException("Missing validated user from the Artemis message") val rpcUser = userService.getUser(validatedUser) @@ -365,6 +367,7 @@ class RPCServer( @JvmField internal val CURRENT_RPC_CONTEXT: ThreadLocal = ThreadLocal() + /** * Returns a context specific to the current RPC call. Note that trying to call this function outside of an RPC will * throw. If you'd like to use the context outside of the call (e.g. in another thread) then pass the returned reference @@ -422,6 +425,7 @@ class ObservableContext( object RpcServerObservableSerializer : Serializer>() { private object RpcObservableContextKey + private val log = loggerFor() fun createContext(observableContext: ObservableContext): SerializationContext { @@ -448,9 +452,11 @@ object RpcServerObservableSerializer : Serializer>() { } } } + override fun onError(exception: Throwable) { log.error("onError called in materialize()d RPC Observable", exception) } + override fun onCompleted() { } } diff --git a/node/src/main/kotlin/net/corda/node/services/network/NodeInfoWatcher.kt b/node/src/main/kotlin/net/corda/node/services/network/NodeInfoWatcher.kt index b73ded13e3..83121ba969 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/NodeInfoWatcher.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/NodeInfoWatcher.kt @@ -99,7 +99,7 @@ class NodeInfoWatcher(private val nodePath: Path, return result } - private fun processFile(file: Path) : NodeInfo? { + private fun processFile(file: Path): NodeInfo? { try { logger.info("Reading NodeInfo from file: $file") val signedData = file.readAll().deserialize>() diff --git a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt index 322a2c9299..09b3c8997f 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt @@ -118,6 +118,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) override fun getNodesByLegalName(name: CordaX500Name): List = serviceHub.database.transaction { queryByLegalName(name) } override fun getNodesByLegalIdentityKey(identityKey: PublicKey): List = serviceHub.database.transaction { queryByIdentityKey(identityKey) } + override fun getNodeByLegalIdentity(party: AbstractParty): NodeInfo? { val wellKnownParty = serviceHub.identityService.wellKnownPartyFromAnonymous(party) return wellKnownParty?.let { diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/AbstractPartyToX500NameAsStringConverter.kt b/node/src/main/kotlin/net/corda/node/services/persistence/AbstractPartyToX500NameAsStringConverter.kt index ac1d696af7..8dc9c857bd 100644 --- a/node/src/main/kotlin/net/corda/node/services/persistence/AbstractPartyToX500NameAsStringConverter.kt +++ b/node/src/main/kotlin/net/corda/node/services/persistence/AbstractPartyToX500NameAsStringConverter.kt @@ -32,7 +32,7 @@ class AbstractPartyToX500NameAsStringConverter(identitySvc: () -> IdentityServic if (dbData != null) { val party = identityService.wellKnownPartyFromX500Name(CordaX500Name.parse(dbData)) if (party != null) return party - log.warn ("Identity service unable to resolve X500name: $dbData") + log.warn("Identity service unable to resolve X500name: $dbData") } return null // non resolvable anonymous parties are stored as nulls } diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/DBTransactionStorage.kt b/node/src/main/kotlin/net/corda/node/services/persistence/DBTransactionStorage.kt index 0e68c98cce..ff29e4c1da 100644 --- a/node/src/main/kotlin/net/corda/node/services/persistence/DBTransactionStorage.kt +++ b/node/src/main/kotlin/net/corda/node/services/persistence/DBTransactionStorage.kt @@ -30,8 +30,10 @@ class DBTransactionStorage : WritableTransactionStorage, SingletonSerializeAsTok fun createTransactionsMap(): AppendOnlyPersistentMap { return AppendOnlyPersistentMap( toPersistentEntityKey = { it.toString() }, - fromPersistentEntity = { Pair(SecureHash.parse(it.txId), - it.transaction.deserialize( context = SerializationDefaults.STORAGE_CONTEXT)) }, + fromPersistentEntity = { + Pair(SecureHash.parse(it.txId), + it.transaction.deserialize(context = SerializationDefaults.STORAGE_CONTEXT)) + }, toPersistentEntity = { key: SecureHash, value: SignedTransaction -> DBTransaction().apply { txId = key.toString() @@ -46,9 +48,9 @@ class DBTransactionStorage : WritableTransactionStorage, SingletonSerializeAsTok private val txStorage = createTransactionsMap() override fun addTransaction(transaction: SignedTransaction): Boolean = - txStorage.addWithDuplicatesAllowed(transaction.id, transaction).apply { - updatesPublisher.bufferUntilDatabaseCommit().onNext(transaction) - } + txStorage.addWithDuplicatesAllowed(transaction.id, transaction).apply { + updatesPublisher.bufferUntilDatabaseCommit().onNext(transaction) + } override fun getTransaction(id: SecureHash): SignedTransaction? = txStorage[id] @@ -59,5 +61,6 @@ class DBTransactionStorage : WritableTransactionStorage, SingletonSerializeAsTok DataFeed(txStorage.allPersisted().map { it.second }.toList(), updatesPublisher.bufferUntilSubscribed().wrapWithDatabaseTransaction()) @VisibleForTesting - val transactions: Iterable get() = txStorage.allPersisted().map { it.second }.toList() + val transactions: Iterable + get() = txStorage.allPersisted().map { it.second }.toList() } diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/HibernateConfiguration.kt b/node/src/main/kotlin/net/corda/node/services/persistence/HibernateConfiguration.kt index 73d8f77dff..bf6efb6c8c 100644 --- a/node/src/main/kotlin/net/corda/node/services/persistence/HibernateConfiguration.kt +++ b/node/src/main/kotlin/net/corda/node/services/persistence/HibernateConfiguration.kt @@ -32,7 +32,7 @@ class HibernateConfiguration(val schemaService: SchemaService, private val datab // TODO: make this a guava cache or similar to limit ability for this to grow forever. private val sessionFactories = ConcurrentHashMap, SessionFactory>() - private val transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel") ?:"") + private val transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel") ?: "") init { logger.info("Init HibernateConfiguration for schemas: ${schemaService.schemaOptions.keys}") @@ -61,7 +61,7 @@ class HibernateConfiguration(val schemaService: SchemaService, private val datab // necessarily remain and would likely be replaced by something like Liquibase. For now it is very convenient though. // TODO: replace auto schema generation as it isn't intended for production use, according to Hibernate docs. val config = Configuration(metadataSources).setProperty("hibernate.connection.provider_class", NodeDatabaseConnectionProvider::class.java.name) - .setProperty("hibernate.hbm2ddl.auto", if (databaseProperties.getProperty("initDatabase","true") == "true") "update" else "validate") + .setProperty("hibernate.hbm2ddl.auto", if (databaseProperties.getProperty("initDatabase", "true") == "true") "update" else "validate") .setProperty("hibernate.format_sql", "true") .setProperty("hibernate.connection.isolation", transactionIsolationLevel.toString()) @@ -70,7 +70,7 @@ class HibernateConfiguration(val schemaService: SchemaService, private val datab schema.mappedTypes.forEach { config.addAnnotatedClass(it) } } - val sessionFactory = buildSessionFactory(config, metadataSources, databaseProperties.getProperty("serverNameTablePrefix","")) + val sessionFactory = buildSessionFactory(config, metadataSources, databaseProperties.getProperty("serverNameTablePrefix", "")) logger.info("Created session factory for schemas: $schemas") return sessionFactory } diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/InMemoryStateMachineRecordedTransactionMappingStorage.kt b/node/src/main/kotlin/net/corda/node/services/persistence/InMemoryStateMachineRecordedTransactionMappingStorage.kt index 740373d3d7..84dd4974dd 100644 --- a/node/src/main/kotlin/net/corda/node/services/persistence/InMemoryStateMachineRecordedTransactionMappingStorage.kt +++ b/node/src/main/kotlin/net/corda/node/services/persistence/InMemoryStateMachineRecordedTransactionMappingStorage.kt @@ -22,6 +22,7 @@ class InMemoryStateMachineRecordedTransactionMappingStorage : StateMachineRecord val stateMachineTransactionMap = HashMap>() val updates = PublishSubject.create()!! } + private val mutex = ThreadBox(InnerState()) override fun addMapping(stateMachineRunId: StateMachineRunId, transactionId: SecureHash) { diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt b/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt index 3a175effb4..c864521d7b 100644 --- a/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt +++ b/node/src/main/kotlin/net/corda/node/services/persistence/NodeAttachmentService.kt @@ -29,7 +29,7 @@ class NodeAttachmentService(metrics: MetricRegistry) : AttachmentStorage, Single @Entity @Table(name = "${NODE_DATABASE_PREFIX}attachments", - indexes = arrayOf(Index(name = "att_id_idx", columnList = "att_id"))) + indexes = arrayOf(Index(name = "att_id_idx", columnList = "att_id"))) class DBAttachment( @Id @Column(name = "att_id", length = 65535) @@ -69,7 +69,8 @@ class NodeAttachmentService(metrics: MetricRegistry) : AttachmentStorage, Single * around inside it, we haven't read the whole file, so we can't check the hash. But when copying it over the network * this will provide an additional safety check against user error. */ - @VisibleForTesting @CordaSerializable + @VisibleForTesting + @CordaSerializable class HashCheckingStream(val expected: SecureHash.SHA256, val expectedSize: Int, input: InputStream, @@ -110,16 +111,17 @@ class NodeAttachmentService(metrics: MetricRegistry) : AttachmentStorage, Single } private var _hash: HashCode? = null // Backing field for hash property - private val hash: HashCode get() { - var h = _hash - return if (h == null) { - h = stream.hash() - _hash = h - h - } else { - h + private val hash: HashCode + get() { + var h = _hash + return if (h == null) { + h = stream.hash() + _hash = h + h + } else { + h + } } - } } private class AttachmentImpl(override val id: SecureHash, dataLoader: () -> ByteArray, private val checkOnLoad: Boolean) : AbstractAttachment(dataLoader), SerializeAsToken { diff --git a/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt b/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt index 333ecd6152..0599616644 100644 --- a/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt +++ b/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt @@ -57,18 +57,18 @@ class NodeSchemaService(customSchemas: Set = emptySet()) : SchemaS PersistentIdentityService.PersistentIdentity::class.java, PersistentIdentityService.PersistentIdentityNames::class.java, ContractUpgradeServiceImpl.DBContractUpgrade::class.java - )) + )) // Required schemas are those used by internal Corda services // For example, cash is used by the vault for coin selection (but will be extracted as a standalone CorDapp in future) private val requiredSchemas: Map = mapOf(Pair(CommonSchemaV1, SchemaService.SchemaOptions()), - Pair(VaultSchemaV1, SchemaService.SchemaOptions()), - Pair(NodeInfoSchemaV1, SchemaService.SchemaOptions()), - Pair(NodeServicesV1, SchemaService.SchemaOptions())) + Pair(VaultSchemaV1, SchemaService.SchemaOptions()), + Pair(NodeInfoSchemaV1, SchemaService.SchemaOptions()), + Pair(NodeServicesV1, SchemaService.SchemaOptions())) - override var schemaOptions: Map = requiredSchemas.plus(customSchemas.map { - mappedSchema -> Pair(mappedSchema, SchemaService.SchemaOptions()) + override var schemaOptions: Map = requiredSchemas.plus(customSchemas.map { mappedSchema -> + Pair(mappedSchema, SchemaService.SchemaOptions()) }) // Currently returns all schemas supported by the state, with no filtering or enrichment. @@ -94,8 +94,8 @@ class NodeSchemaService(customSchemas: Set = emptySet()) : SchemaS } override fun registerCustomSchemas(_customSchemas: Set) { - schemaOptions = schemaOptions.plus(_customSchemas.map { - mappedSchema -> Pair(mappedSchema, SchemaService.SchemaOptions()) + schemaOptions = schemaOptions.plus(_customSchemas.map { mappedSchema -> + Pair(mappedSchema, SchemaService.SchemaOptions()) }) } } diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt index 0de001283e..dea328709a 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt @@ -42,7 +42,7 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, val logic: FlowLogic, scheduler: FiberScheduler, override val flowInitiator: FlowInitiator, - // Store the Party rather than the full cert path with PartyAndCertificate + // Store the Party rather than the full cert path with PartyAndCertificate val ourIdentity: Party) : Fiber(id.toString(), scheduler), FlowStateMachine { companion object { @@ -265,7 +265,7 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, // This is a hack to allow cash app access list of permitted issuer currency. // TODO: replace this with cordapp configuration. val config = serviceHub.configuration as? FullNodeConfiguration - val permissionGranted = config?.extraAdvertisedServiceIds?.contains(permissionName) ?: true + val permissionGranted = config?.extraAdvertisedServiceIds?.contains(permissionName) != false val checkPermissionEvent = FlowPermissionAuditEvent( serviceHub.clock.instant(), flowInitiator, @@ -482,7 +482,7 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, private fun suspend(ioRequest: FlowIORequest) { // We have to pass the thread local database transaction across via a transient field as the fiber park // swaps them out. - txTrampoline = DatabaseTransactionManager.setThreadLocalTx(null) + txTrampoline = DatabaseTransactionManager.setThreadLocalTx(null) if (ioRequest is WaitingRequest) waitingForResponse = ioRequest @@ -541,28 +541,30 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, } } -val Class>.flowVersionAndInitiatingClass: Pair>> get() { - var current: Class<*> = this - var found: Pair>>? = null - while (true) { - val annotation = current.getDeclaredAnnotation(InitiatingFlow::class.java) - if (annotation != null) { - if (found != null) throw IllegalArgumentException("${InitiatingFlow::class.java.name} can only be annotated once") - require(annotation.version > 0) { "Flow versions have to be greater or equal to 1" } - found = annotation.version to uncheckedCast(current) +val Class>.flowVersionAndInitiatingClass: Pair>> + get() { + var current: Class<*> = this + var found: Pair>>? = null + while (true) { + val annotation = current.getDeclaredAnnotation(InitiatingFlow::class.java) + if (annotation != null) { + if (found != null) throw IllegalArgumentException("${InitiatingFlow::class.java.name} can only be annotated once") + require(annotation.version > 0) { "Flow versions have to be greater or equal to 1" } + found = annotation.version to uncheckedCast(current) + } + current = current.superclass + ?: return found + ?: throw IllegalArgumentException("$name, as a flow that initiates other flows, must be annotated with " + + "${InitiatingFlow::class.java.name}. See https://docs.corda.net/api-flows.html#flowlogic-annotations.") } - current = current.superclass - ?: return found - ?: throw IllegalArgumentException("$name, as a flow that initiates other flows, must be annotated with " + - "${InitiatingFlow::class.java.name}. See https://docs.corda.net/api-flows.html#flowlogic-annotations.") } -} -val Class>.appName: String get() { - val jarFile = Paths.get(protectionDomain.codeSource.location.toURI()) - return if (jarFile.isRegularFile() && jarFile.toString().endsWith(".jar")) { - jarFile.fileName.toString().removeSuffix(".jar") - } else { - "" +val Class>.appName: String + get() { + val jarFile = Paths.get(protectionDomain.codeSource.location.toURI()) + return if (jarFile.isRegularFile() && jarFile.toString().endsWith(".jar")) { + jarFile.fileName.toString().removeSuffix(".jar") + } else { + "" + } } -} diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineManager.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineManager.kt index c8189063a6..42fd677f65 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineManager.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineManager.kt @@ -397,7 +397,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal, } val (ourFlowVersion, appName) = when (initiatedFlowFactory) { - // The flow version for the core flows is the platform version + // The flow version for the core flows is the platform version is InitiatedFlowFactory.Core -> serviceHub.myInfo.platformVersion to "corda" is InitiatedFlowFactory.CorDapp -> initiatedFlowFactory.flowVersion to initiatedFlowFactory.appName } @@ -631,8 +631,8 @@ class StateMachineManager(val serviceHub: ServiceHubInternal, val serialized = try { message.serialize() } catch (e: Exception) { - when(e) { - // Handling Kryo and AMQP serialization problems. Unfortunately the two exception types do not share much of a common exception interface. + when (e) { + // Handling Kryo and AMQP serialization problems. Unfortunately the two exception types do not share much of a common exception interface. is KryoException, is NotSerializableException -> { if (message !is ErrorSessionEnd || message.errorResponse == null) throw e diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt index 8ea6e6af09..f0c1e17823 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt @@ -112,7 +112,7 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, name = CordaX500Name.parse(it.party.name), owningKey = parsePublicKeyBase58(it.party.owningKey)))) }, - toPersistentEntity = { (txHash, index) : StateRef, (id, inputIndex, requestingParty): UniquenessProvider.ConsumingTx -> + toPersistentEntity = { (txHash, index): StateRef, (id, inputIndex, requestingParty): UniquenessProvider.ConsumingTx -> PersistedCommittedState( id = PersistentStateRef(txHash.toString(), index), consumingTxHash = id.toString(), diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/PersistentUniquenessProvider.kt b/node/src/main/kotlin/net/corda/node/services/transactions/PersistentUniquenessProvider.kt index b17b9902fc..f669ae3426 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/PersistentUniquenessProvider.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/PersistentUniquenessProvider.kt @@ -24,7 +24,7 @@ import javax.persistence.* class PersistentUniquenessProvider : UniquenessProvider, SingletonSerializeAsToken() { @MappedSuperclass - open class PersistentUniqueness ( + open class PersistentUniqueness( @EmbeddedId var id: PersistentStateRef = PersistentStateRef(), @@ -45,11 +45,11 @@ class PersistentUniquenessProvider : UniquenessProvider, SingletonSerializeAsTok @Column(name = "requesting_party_key", length = 255) var owningKey: String = "" - ): Serializable + ) : Serializable @Entity @javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}notary_commit_log") - class PersistentNotaryCommit(id: PersistentStateRef, consumingTxHash: String, consumingIndex: Int, party: PersistentParty): + class PersistentNotaryCommit(id: PersistentStateRef, consumingTxHash: String, consumingIndex: Int, party: PersistentParty) : PersistentUniqueness(id, consumingTxHash, consumingIndex, party) @@ -77,37 +77,37 @@ class PersistentUniquenessProvider : UniquenessProvider, SingletonSerializeAsTok name = CordaX500Name.parse(it.party.name), owningKey = parsePublicKeyBase58(it.party.owningKey)))) }, - toPersistentEntity = { (txHash, index) : StateRef, (id, inputIndex, requestingParty) : UniquenessProvider.ConsumingTx -> + toPersistentEntity = { (txHash, index): StateRef, (id, inputIndex, requestingParty): UniquenessProvider.ConsumingTx -> PersistentNotaryCommit( id = PersistentStateRef(txHash.toString(), index), consumingTxHash = id.toString(), consumingIndex = inputIndex, party = PersistentParty(requestingParty.name.toString(), requestingParty.owningKey.toBase58String()) ) - }, - persistentEntityClass = PersistentNotaryCommit::class.java - ) - } + }, + persistentEntityClass = PersistentNotaryCommit::class.java + ) + } override fun commit(states: List, txId: SecureHash, callerIdentity: Party) { val conflict = mutex.locked { - val conflictingStates = LinkedHashMap() - for (inputState in states) { - val consumingTx = committedStates.get(inputState) - if (consumingTx != null) conflictingStates[inputState] = consumingTx - } - if (conflictingStates.isNotEmpty()) { - log.debug("Failure, input states already committed: ${conflictingStates.keys}") - UniquenessProvider.Conflict(conflictingStates) - } else { - states.forEachIndexed { i, stateRef -> - committedStates[stateRef] = UniquenessProvider.ConsumingTx(txId, i, callerIdentity) - } - log.debug("Successfully committed all input states: $states") - null - } + val conflictingStates = LinkedHashMap() + for (inputState in states) { + val consumingTx = committedStates.get(inputState) + if (consumingTx != null) conflictingStates[inputState] = consumingTx + } + if (conflictingStates.isNotEmpty()) { + log.debug("Failure, input states already committed: ${conflictingStates.keys}") + UniquenessProvider.Conflict(conflictingStates) + } else { + states.forEachIndexed { i, stateRef -> + committedStates[stateRef] = UniquenessProvider.ConsumingTx(txId, i, callerIdentity) } + log.debug("Successfully committed all input states: $states") + null + } + } if (conflict != null) throw UniquenessException(conflict) } diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/RaftUniquenessProvider.kt b/node/src/main/kotlin/net/corda/node/services/transactions/RaftUniquenessProvider.kt index 93daf5a23a..130f954a50 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/RaftUniquenessProvider.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/RaftUniquenessProvider.kt @@ -97,7 +97,8 @@ class RaftUniquenessProvider(private val services: ServiceHubInternal, private v fun start() { log.info("Creating Copycat server, log stored in: ${storagePath.toFile()}") val stateMachineFactory = { - DistributedImmutableMap(db, RaftUniquenessProvider.Companion::createMap) } + DistributedImmutableMap(db, RaftUniquenessProvider.Companion::createMap) + } val address = raftConfig.nodeAddress.let { Address(it.host, it.port) } val storage = buildStorage(storagePath) val transport = buildTransport(transportConfiguration) @@ -110,6 +111,7 @@ class RaftUniquenessProvider(private val services: ServiceHubInternal, private v serializer: Serializer) { writeMap(obj.entries, buffer, serializer) } + override fun read(type: Class>, buffer: BufferInput>, serializer: Serializer): DistributedImmutableMap.Commands.PutAll { diff --git a/node/src/main/kotlin/net/corda/node/services/vault/HibernateQueryCriteriaParser.kt b/node/src/main/kotlin/net/corda/node/services/vault/HibernateQueryCriteriaParser.kt index 30c32220f7..7b8816b361 100644 --- a/node/src/main/kotlin/net/corda/node/services/vault/HibernateQueryCriteriaParser.kt +++ b/node/src/main/kotlin/net/corda/node/services/vault/HibernateQueryCriteriaParser.kt @@ -36,11 +36,11 @@ class HibernateQueryCriteriaParser(val contractStateType: Class, Root<*>>(Pair(VaultSchemaV1.VaultStates::class.java, vaultStates)) private val aggregateExpressions = mutableListOf>() - private val commonPredicates = mutableMapOf, Predicate>() // schema attribute Name, operator -> predicate + private val commonPredicates = mutableMapOf, Predicate>() // schema attribute Name, operator -> predicate var stateTypes: Vault.StateStatus = Vault.StateStatus.UNCONSUMED - override fun parseCriteria(criteria: QueryCriteria.VaultQueryCriteria) : Collection { + override fun parseCriteria(criteria: QueryCriteria.VaultQueryCriteria): Collection { log.trace { "Parsing VaultQueryCriteria: $criteria" } val predicateSet = mutableSetOf() @@ -48,7 +48,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class predicateSet.add(criteriaBuilder.and(vaultStates.get("lockId").isNull)) QueryCriteria.SoftLockingType.LOCKED_ONLY -> @@ -56,7 +56,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class { require(softLocking.lockIds.isNotEmpty()) { "Must specify one or more lockIds" } predicateSet.add(criteriaBuilder.or(vaultStates.get("lockId").isNull, - vaultStates.get("lockId").`in`(softLocking.lockIds.map { it.toString() }))) + vaultStates.get("lockId").`in`(softLocking.lockIds.map { it.toString() }))) } QueryCriteria.SoftLockingType.SPECIFIED -> { require(softLocking.lockIds.isNotEmpty()) { "Must specify one or more lockIds" } @@ -154,7 +154,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class parseExpression(entityRoot: Root, expression: CriteriaExpression, predicateSet: MutableSet) { - if (expression is CriteriaExpression.AggregateFunctionExpression) { + if (expression is CriteriaExpression.AggregateFunctionExpression) { parseAggregateFunction(entityRoot, expression) } else { predicateSet.add(parseExpression(entityRoot, expression) as Predicate) @@ -221,7 +221,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class { + override fun parseCriteria(criteria: QueryCriteria.FungibleAssetQueryCriteria): Collection { log.trace { "Parsing FungibleAssetQueryCriteria: $criteria" } val predicateSet = mutableSetOf() @@ -265,7 +265,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class { + override fun parseCriteria(criteria: QueryCriteria.LinearStateQueryCriteria): Collection { log.trace { "Parsing LinearStateQueryCriteria: $criteria" } val predicateSet = mutableSetOf() @@ -314,8 +314,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class if (message.contains("Not an entity")) throw VaultQueryException(""" @@ -386,8 +385,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class(VaultSchemaV1.VaultStates::stateStatus.name), criteria.status)) } - } - else { + } else { commonPredicates.put(predicateID, criteriaBuilder.equal(vaultStates.get(VaultSchemaV1.VaultStates::stateStatus.name), criteria.status)) } } @@ -417,7 +415,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class val (entityStateClass, entityStateAttributeParent, entityStateAttributeChild) = - when(sortAttribute) { + when (sortAttribute) { is SortAttribute.Standard -> parse(sortAttribute.attribute) is SortAttribute.Custom -> Triple(sortAttribute.entityStateClass, sortAttribute.entityStateColumnName, null) } @@ -451,8 +449,8 @@ class HibernateQueryCriteriaParser(val contractStateType: Class, String, String?> { - val entityClassAndColumnName : Triple, String, String?> = - when(sortAttribute) { + val entityClassAndColumnName: Triple, String, String?> = + when (sortAttribute) { is Sort.CommonStateAttribute -> { Triple(VaultSchemaV1.VaultStates::class.java, sortAttribute.attributeParent, sortAttribute.attributeChild) } diff --git a/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt b/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt index 6564859865..3b5236d97a 100644 --- a/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt +++ b/node/src/main/kotlin/net/corda/node/services/vault/NodeVaultService.kt @@ -247,7 +247,7 @@ class NodeVaultService(private val clock: Clock, private val keyManagementServic val vaultStates = criteriaUpdate.from(VaultSchemaV1.VaultStates::class.java) val stateStatusPredication = criteriaBuilder.equal(vaultStates.get(VaultSchemaV1.VaultStates::stateStatus.name), Vault.StateStatus.UNCONSUMED) val lockIdPredicate = criteriaBuilder.or(vaultStates.get(VaultSchemaV1.VaultStates::lockId.name).isNull, - criteriaBuilder.equal(vaultStates.get(VaultSchemaV1.VaultStates::lockId.name), lockId.toString())) + criteriaBuilder.equal(vaultStates.get(VaultSchemaV1.VaultStates::lockId.name), lockId.toString())) val persistentStateRefs = stateRefs.map { PersistentStateRef(it.txhash.bytes.toHexString(), it.index) } val compositeKey = vaultStates.get(VaultSchemaV1.VaultStates::stateRef.name) val stateRefsPredicate = criteriaBuilder.and(compositeKey.`in`(persistentStateRefs)) @@ -468,8 +468,7 @@ class NodeVaultService(private val clock: Clock, private val keyManagementServic vaultState.lockId, vaultState.lockUpdateTime)) statesAndRefs.add(StateAndRef(state, stateRef)) - } - else { + } else { // TODO: improve typing of returned other results log.debug { "OtherResults: ${Arrays.toString(result.toArray())}" } otherResults.addAll(result.toArray().asList()) diff --git a/node/src/main/kotlin/net/corda/node/services/vault/VaultSchema.kt b/node/src/main/kotlin/net/corda/node/services/vault/VaultSchema.kt index 8dd74ab76f..0c8ba52a4e 100644 --- a/node/src/main/kotlin/net/corda/node/services/vault/VaultSchema.kt +++ b/node/src/main/kotlin/net/corda/node/services/vault/VaultSchema.kt @@ -25,7 +25,7 @@ object VaultSchema */ @CordaSerializable object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, version = 1, - mappedTypes = listOf(VaultStates::class.java, VaultLinearStates::class.java, VaultFungibleStates::class.java, VaultTxnNote::class.java)) { + mappedTypes = listOf(VaultStates::class.java, VaultLinearStates::class.java, VaultFungibleStates::class.java, VaultTxnNote::class.java)) { @Entity @Table(name = "vault_states", indexes = arrayOf(Index(name = "state_status_idx", columnList = "state_status"))) @@ -90,8 +90,8 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio ) : PersistentState() { constructor(uid: UniqueIdentifier, _participants: List) : this(externalId = uid.externalId, - uuid = uid.id, - participants = _participants.toMutableSet()) + uuid = uid.id, + participants = _participants.toMutableSet()) } @Entity @@ -131,27 +131,27 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio ) : PersistentState() { constructor(_owner: AbstractParty, _quantity: Long, _issuerParty: AbstractParty, _issuerRef: OpaqueBytes, _participants: List) : this(owner = _owner, - quantity = _quantity, - issuer = _issuerParty, - issuerRef = _issuerRef.bytes, - participants = _participants.toMutableSet()) + quantity = _quantity, + issuer = _issuerParty, + issuerRef = _issuerRef.bytes, + participants = _participants.toMutableSet()) } @Entity @Table(name = "vault_transaction_notes", - indexes = arrayOf(Index(name = "seq_no_index", columnList = "seq_no"), - Index(name = "transaction_id_index", columnList = "transaction_id"))) + indexes = arrayOf(Index(name = "seq_no_index", columnList = "seq_no"), + Index(name = "transaction_id_index", columnList = "transaction_id"))) class VaultTxnNote( - @Id - @GeneratedValue - @Column(name = "seq_no") - var seqNo: Int, + @Id + @GeneratedValue + @Column(name = "seq_no") + var seqNo: Int, - @Column(name = "transaction_id", length = 64) - var txId: String, + @Column(name = "transaction_id", length = 64) + var txId: String, - @Column(name = "note") - var note: String + @Column(name = "note") + var note: String ) : Serializable { constructor(txId: String, note: String) : this(0, txId, note) } diff --git a/node/src/main/kotlin/net/corda/node/shell/FlowWatchPrintingSubscriber.kt b/node/src/main/kotlin/net/corda/node/shell/FlowWatchPrintingSubscriber.kt index 32920ffd23..235c2bcbe9 100644 --- a/node/src/main/kotlin/net/corda/node/shell/FlowWatchPrintingSubscriber.kt +++ b/node/src/main/kotlin/net/corda/node/shell/FlowWatchPrintingSubscriber.kt @@ -59,7 +59,7 @@ class FlowWatchPrintingSubscriber(private val toStream: RenderPrintWriter) : Sub } private fun createStateMachinesTable(): TableElement { - val table = TableElement(1,2,1,2).overflow(Overflow.HIDDEN).rightCellPadding(1) + val table = TableElement(1, 2, 1, 2).overflow(Overflow.HIDDEN).rightCellPadding(1) val header = RowElement(true).add("Id", "Flow name", "Initiator", "Status").style(Decoration.bold.fg(Color.black).bg(Color.white)) table.add(header) return table @@ -102,12 +102,12 @@ class FlowWatchPrintingSubscriber(private val toStream: RenderPrintWriter) : Sub } private fun formatFlowId(flowId: StateMachineRunId): String { - return flowId.toString().removeSurrounding("[","]") + return flowId.toString().removeSurrounding("[", "]") } private fun formatFlowInitiator(flowInitiator: FlowInitiator): String { return when (flowInitiator) { - is FlowInitiator.Scheduled -> flowInitiator.scheduledState.ref.toString() + is FlowInitiator.Scheduled -> flowInitiator.scheduledState.ref.toString() is FlowInitiator.Shell -> "Shell" // TODO Change when we will have more information on shell user. is FlowInitiator.Peer -> flowInitiator.party.name.organisation is FlowInitiator.RPC -> "RPC: " + flowInitiator.username @@ -117,7 +117,7 @@ class FlowWatchPrintingSubscriber(private val toStream: RenderPrintWriter) : Sub private fun formatFlowResult(flowResult: Try<*>): String { fun successFormat(value: Any?): String { - return when(value) { + return when (value) { is SignedTransaction -> "Tx ID: " + value.id.toString() is kotlin.Unit -> "No return value" null -> "No return value" diff --git a/node/src/main/kotlin/net/corda/node/shell/InteractiveShell.kt b/node/src/main/kotlin/net/corda/node/shell/InteractiveShell.kt index 07ee7e3f96..a671fdb1dd 100644 --- a/node/src/main/kotlin/net/corda/node/shell/InteractiveShell.kt +++ b/node/src/main/kotlin/net/corda/node/shell/InteractiveShell.kt @@ -247,11 +247,11 @@ object InteractiveShell { // Wait for the flow to end and the progress tracker to notice. By the time the latch is released // the tracker is done with the screen. latch.await() - } catch(e: InterruptedException) { + } catch (e: InterruptedException) { ANSIProgressRenderer.progressTracker = null // TODO: When the flow framework allows us to kill flows mid-flight, do so here. } - } catch(e: NoApplicableConstructor) { + } catch (e: NoApplicableConstructor) { output.println("No matching constructor found:", Color.red) e.errors.forEach { output.println("- $it", Color.red) } } finally { @@ -305,14 +305,14 @@ object InteractiveShell { continue } return invoke(flow) - } catch(e: StringToMethodCallParser.UnparseableCallException.MissingParameter) { + } catch (e: StringToMethodCallParser.UnparseableCallException.MissingParameter) { errors.add("${getPrototype()}: missing parameter ${e.paramName}") - } catch(e: StringToMethodCallParser.UnparseableCallException.TooManyParameters) { + } catch (e: StringToMethodCallParser.UnparseableCallException.TooManyParameters) { errors.add("${getPrototype()}: too many parameters") - } catch(e: StringToMethodCallParser.UnparseableCallException.ReflectionDataMissing) { + } catch (e: StringToMethodCallParser.UnparseableCallException.ReflectionDataMissing) { val argTypes = ctor.parameterTypes.map { it.simpleName } errors.add("$argTypes: ") - } catch(e: StringToMethodCallParser.UnparseableCallException) { + } catch (e: StringToMethodCallParser.UnparseableCallException) { val argTypes = ctor.parameterTypes.map { it.simpleName } errors.add("$argTypes: ${e.message}") } @@ -506,7 +506,7 @@ object InteractiveShell { } finally { try { value.close() - } catch(e: IOException) { + } catch (e: IOException) { // Ignore. } } diff --git a/node/src/main/kotlin/net/corda/node/utilities/AppendOnlyPersistentMap.kt b/node/src/main/kotlin/net/corda/node/utilities/AppendOnlyPersistentMap.kt index ab9f83e884..62508f0e2b 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/AppendOnlyPersistentMap.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/AppendOnlyPersistentMap.kt @@ -9,9 +9,9 @@ import java.util.* * behaviour is unpredictable! There is a best-effort check for double inserts, but this should *not* be relied on, so * ONLY USE THIS IF YOUR TABLE IS APPEND-ONLY */ -class AppendOnlyPersistentMap ( +class AppendOnlyPersistentMap( val toPersistentEntityKey: (K) -> EK, - val fromPersistentEntity: (E) -> Pair, + val fromPersistentEntity: (E) -> Pair, val toPersistentEntity: (key: K, value: V) -> E, val persistentEntityClass: Class, cacheBound: Long = 1024 @@ -48,10 +48,11 @@ class AppendOnlyPersistentMap ( return result.map { x -> fromPersistentEntity(x) }.asSequence() } - private tailrec fun set(key: K, value: V, logWarning: Boolean, store: (K,V) -> V?): Boolean { + private tailrec fun set(key: K, value: V, logWarning: Boolean, store: (K, V) -> V?): Boolean { var insertionAttempt = false var isUnique = true - val existingInCache = cache.get(key) { // Thread safe, if multiple threads may wait until the first one has loaded. + val existingInCache = cache.get(key) { + // Thread safe, if multiple threads may wait until the first one has loaded. insertionAttempt = true // Key wasn't in the cache and might be in the underlying storage. // Depending on 'store' method, this may insert without checking key duplication or it may avoid inserting a duplicated key. @@ -85,8 +86,8 @@ class AppendOnlyPersistentMap ( * If the map previously contained a mapping for the key, the behaviour is unpredictable and may throw an error from the underlying storage. */ operator fun set(key: K, value: V) = - set(key, value, logWarning = false) { - k, v -> DatabaseTransactionManager.current().session.save(toPersistentEntity(k, v)) + set(key, value, logWarning = false) { k, v -> + DatabaseTransactionManager.current().session.save(toPersistentEntity(k, v)) null } @@ -96,8 +97,7 @@ class AppendOnlyPersistentMap ( * @return true if added key was unique, otherwise false */ fun addWithDuplicatesAllowed(key: K, value: V, logWarning: Boolean = true): Boolean = - set(key, value, logWarning) { - k, v -> + set(key, value, logWarning) { k, v -> val existingEntry = DatabaseTransactionManager.current().session.find(persistentEntityClass, toPersistentEntityKey(k)) if (existingEntry == null) { DatabaseTransactionManager.current().session.save(toPersistentEntity(k, v)) @@ -107,7 +107,7 @@ class AppendOnlyPersistentMap ( } } - fun putAll(entries: Map) { + fun putAll(entries: Map) { entries.forEach { set(it.key, it.value) } diff --git a/node/src/main/kotlin/net/corda/node/utilities/CordaPersistence.kt b/node/src/main/kotlin/net/corda/node/utilities/CordaPersistence.kt index c1d6d8d0b7..0bf9885945 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/CordaPersistence.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/CordaPersistence.kt @@ -24,14 +24,14 @@ const val NODE_DATABASE_PREFIX = "node_" //HikariDataSource implements Closeable which allows CordaPersistence to be Closeable class CordaPersistence(var dataSource: HikariDataSource, private val schemaService: SchemaService, - private val createIdentityService: ()-> IdentityService, databaseProperties: Properties): Closeable { + private val createIdentityService: () -> IdentityService, databaseProperties: Properties) : Closeable { var transactionIsolationLevel = parserTransactionIsolationLevel(databaseProperties.getProperty("transactionIsolationLevel")) - val hibernateConfig: HibernateConfiguration by lazy { + val hibernateConfig: HibernateConfiguration by lazy { transaction { HibernateConfiguration(schemaService, databaseProperties, createIdentityService) } - } + } val entityManagerFactory: SessionFactory by lazy { transaction { @@ -70,8 +70,7 @@ class CordaPersistence(var dataSource: HikariDataSource, private val schemaServi return if (outer != null) { outer.statement() - } - else { + } else { inTopLevelTransaction(transactionIsolation, repetitionAttempts, statement) } } @@ -84,19 +83,16 @@ class CordaPersistence(var dataSource: HikariDataSource, private val schemaServi val answer = transaction.statement() transaction.commit() return answer - } - catch (e: SQLException) { + } catch (e: SQLException) { transaction.rollback() repetitions++ if (repetitions >= repetitionAttempts) { throw e } - } - catch (e: Throwable) { + } catch (e: Throwable) { transaction.rollback() throw e - } - finally { + } finally { transaction.close() } } @@ -170,7 +166,7 @@ private class DatabaseTransactionWrappingSubscriber(val db: CordaPersistence? } // A subscriber that wraps another but does not pass on observations to it. -private class NoOpSubscriber(t: Subscriber): Subscriber(t) { +private class NoOpSubscriber(t: Subscriber) : Subscriber(t) { override fun onCompleted() { } diff --git a/node/src/main/kotlin/net/corda/node/utilities/DatabaseTransactionManager.kt b/node/src/main/kotlin/net/corda/node/utilities/DatabaseTransactionManager.kt index f847080433..9016112f7b 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/DatabaseTransactionManager.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/DatabaseTransactionManager.kt @@ -30,7 +30,7 @@ class DatabaseTransaction(isolation: Int, val threadLocal: ThreadLocal private constructor( val cache: LoadingCache -): LoadingCache by cache { +) : LoadingCache by cache { constructor(bound: Long, concurrencyLevel: Int, loadFunction: (K) -> V) : this(buildCache(bound, concurrencyLevel, loadFunction)) @@ -25,9 +25,7 @@ class NonInvalidatingCache private constructor( override fun reload(key: K, oldValue: V): ListenableFuture { throw IllegalStateException("Non invalidating cache refreshed") } + override fun load(key: K) = loadFunction(key) - override fun loadAll(keys: Iterable): MutableMap { - return super.loadAll(keys) - } } } \ No newline at end of file diff --git a/node/src/main/kotlin/net/corda/node/utilities/NonInvalidatingUnboundCache.kt b/node/src/main/kotlin/net/corda/node/utilities/NonInvalidatingUnboundCache.kt index 44caaa9adb..ea16bfd064 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/NonInvalidatingUnboundCache.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/NonInvalidatingUnboundCache.kt @@ -6,10 +6,10 @@ import com.google.common.util.concurrent.ListenableFuture class NonInvalidatingUnboundCache private constructor( val cache: LoadingCache -): LoadingCache by cache { +) : LoadingCache by cache { constructor(concurrencyLevel: Int, loadFunction: (K) -> V, removalListener: RemovalListener = RemovalListener {}, - keysToPreload: () -> Iterable = { emptyList() } ) : + keysToPreload: () -> Iterable = { emptyList() }) : this(buildCache(concurrencyLevel, loadFunction, removalListener, keysToPreload)) private companion object { @@ -27,9 +27,7 @@ class NonInvalidatingUnboundCache private constructor( override fun reload(key: K, oldValue: V): ListenableFuture { throw IllegalStateException("Non invalidating cache refreshed") } + override fun load(key: K) = loadFunction(key) - override fun loadAll(keys: Iterable): MutableMap { - return super.loadAll(keys) - } } } \ No newline at end of file diff --git a/node/src/main/kotlin/net/corda/node/utilities/PersistentMap.kt b/node/src/main/kotlin/net/corda/node/utilities/PersistentMap.kt index 55acb14efc..c24ce3c229 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/PersistentMap.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/PersistentMap.kt @@ -11,9 +11,9 @@ import java.util.* /** * Implements an unbound caching layer on top of a table accessed via Hibernate mapping. */ -class PersistentMap ( +class PersistentMap( val toPersistentEntityKey: (K) -> EK, - val fromPersistentEntity: (E) -> Pair, + val fromPersistentEntity: (E) -> Pair, val toPersistentEntity: (key: K, value: V) -> E, val persistentEntityClass: Class ) : MutableMap, AbstractMap() { @@ -34,7 +34,7 @@ class PersistentMap ( getAll(session.createQuery(criteriaQuery).resultList.map { e -> fromPersistentEntity(e as E).first }.asIterable()) } - class ExplicitRemoval(private val toPersistentEntityKey: (K) -> EK, private val persistentEntityClass: Class): RemovalListener { + class ExplicitRemoval(private val toPersistentEntityKey: (K) -> EK, private val persistentEntityClass: Class) : RemovalListener { override fun onRemoval(notification: RemovalNotification?) { when (notification?.cause) { RemovalCause.EXPLICIT -> { @@ -47,7 +47,8 @@ class PersistentMap ( RemovalCause.EXPIRED, RemovalCause.SIZE, RemovalCause.COLLECTED -> { log.error("Entry was removed from cache!!!") } - RemovalCause.REPLACED -> {} + RemovalCause.REPLACED -> { + } } } } @@ -62,10 +63,11 @@ class PersistentMap ( override val size get() = cache.size().toInt() - private tailrec fun set(key: K, value: V, logWarning: Boolean = true, store: (K,V) -> V?, replace: (K, V) -> Unit) : Boolean { + private tailrec fun set(key: K, value: V, logWarning: Boolean = true, store: (K, V) -> V?, replace: (K, V) -> Unit): Boolean { var insertionAttempt = false var isUnique = true - val existingInCache = cache.get(key) { // Thread safe, if multiple threads may wait until the first one has loaded. + val existingInCache = cache.get(key) { + // Thread safe, if multiple threads may wait until the first one has loaded. insertionAttempt = true // Value wasn't in the cache and wasn't in DB (because the cache is unbound). // Store the value, depending on store implementation this may replace existing entry in DB. @@ -98,7 +100,7 @@ class PersistentMap ( operator fun set(key: K, value: V) = set(key, value, logWarning = false, - store = { k: K, v: V -> + store = { k: K, v: V -> DatabaseTransactionManager.current().session.save(toPersistentEntity(k, v)) null }, @@ -145,10 +147,10 @@ class PersistentMap ( private fun merge(key: K, value: V): V? { val existingEntry = DatabaseTransactionManager.current().session.find(persistentEntityClass, toPersistentEntityKey(key)) return if (existingEntry != null) { - DatabaseTransactionManager.current().session.merge(toPersistentEntity(key,value)) + DatabaseTransactionManager.current().session.merge(toPersistentEntity(key, value)) fromPersistentEntity(existingEntry).second } else { - DatabaseTransactionManager.current().session.save(toPersistentEntity(key,value)) + DatabaseTransactionManager.current().session.save(toPersistentEntity(key, value)) null } } @@ -193,56 +195,59 @@ class PersistentMap ( } } - override val keys: MutableSet get() { - return object : AbstractSet() { - override val size: Int get() = this@PersistentMap.size - override fun iterator(): MutableIterator { - return object : MutableIterator { - private val entryIterator = EntryIterator() + override val keys: MutableSet + get() { + return object : AbstractSet() { + override val size: Int get() = this@PersistentMap.size + override fun iterator(): MutableIterator { + return object : MutableIterator { + private val entryIterator = EntryIterator() - override fun hasNext(): Boolean = entryIterator.hasNext() - override fun next(): K = entryIterator.next().key - override fun remove() { - entryIterator.remove() + override fun hasNext(): Boolean = entryIterator.hasNext() + override fun next(): K = entryIterator.next().key + override fun remove() { + entryIterator.remove() + } } } } } - } - override val values: MutableCollection get() { - return object : AbstractCollection() { - override val size: Int get() = this@PersistentMap.size - override fun iterator(): MutableIterator { - return object : MutableIterator { - private val entryIterator = EntryIterator() + override val values: MutableCollection + get() { + return object : AbstractCollection() { + override val size: Int get() = this@PersistentMap.size + override fun iterator(): MutableIterator { + return object : MutableIterator { + private val entryIterator = EntryIterator() - override fun hasNext(): Boolean = entryIterator.hasNext() - override fun next(): V = entryIterator.next().value - override fun remove() { - entryIterator.remove() + override fun hasNext(): Boolean = entryIterator.hasNext() + override fun next(): V = entryIterator.next().value + override fun remove() { + entryIterator.remove() + } } } } } - } - override val entries: MutableSet> get() { - return object : AbstractSet>() { - override val size: Int get() = this@PersistentMap.size - override fun iterator(): MutableIterator> { - return object : MutableIterator> { - private val entryIterator = EntryIterator() + override val entries: MutableSet> + get() { + return object : AbstractSet>() { + override val size: Int get() = this@PersistentMap.size + override fun iterator(): MutableIterator> { + return object : MutableIterator> { + private val entryIterator = EntryIterator() - override fun hasNext(): Boolean = entryIterator.hasNext() - override fun next(): MutableMap.MutableEntry = entryIterator.next() - override fun remove() { - entryIterator.remove() + override fun hasNext(): Boolean = entryIterator.hasNext() + override fun next(): MutableMap.MutableEntry = entryIterator.next() + override fun remove() { + entryIterator.remove() + } } } } } - } override fun put(key: K, value: V): V? { val old = cache.get(key) diff --git a/node/src/main/kotlin/net/corda/node/utilities/TestClock.kt b/node/src/main/kotlin/net/corda/node/utilities/TestClock.kt index e582f45147..60af87f895 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/TestClock.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/TestClock.kt @@ -21,7 +21,8 @@ class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableC override fun toToken(context: SerializeAsTokenContext) = token.registerWithContext(context, this) - @Synchronized fun updateDate(date: LocalDate): Boolean { + @Synchronized + fun updateDate(date: LocalDate): Boolean { val currentDate = LocalDate.now(this) if (currentDate.isBefore(date)) { // It's ok to increment diff --git a/node/src/main/kotlin/net/corda/node/utilities/X509Utilities.kt b/node/src/main/kotlin/net/corda/node/utilities/X509Utilities.kt index a9685fd910..4dfa07ec09 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/X509Utilities.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/X509Utilities.kt @@ -115,7 +115,7 @@ object X509Utilities { subjectPublicKey: PublicKey, validityWindow: Pair = DEFAULT_VALIDITY_WINDOW, nameConstraints: NameConstraints? = null): X509CertificateHolder - = createCertificate(certificateType, issuerCertificate, issuerKeyPair, subject.x500Name, subjectPublicKey, validityWindow, nameConstraints) + = createCertificate(certificateType, issuerCertificate, issuerKeyPair, subject.x500Name, subjectPublicKey, validityWindow, nameConstraints) /** * Create a X509 v3 certificate for use as a CA or for TLS. This does not require a [CordaX500Name] because the @@ -267,9 +267,9 @@ object X509Utilities { * @param nameConstraints any name constraints to impose on certificates signed by the generated certificate. */ internal fun createCertificate(certificateType: CertificateType, issuer: X500Name, issuerKeyPair: KeyPair, - subject: X500Name, subjectPublicKey: PublicKey, - validityWindow: Pair, - nameConstraints: NameConstraints? = null): X509CertificateHolder { + subject: X500Name, subjectPublicKey: PublicKey, + validityWindow: Pair, + nameConstraints: NameConstraints? = null): X509CertificateHolder { val signatureScheme = Crypto.findSignatureScheme(issuerKeyPair.private) val provider = Crypto.findProvider(signatureScheme.providerName) diff --git a/node/src/main/resources/net/corda/node/shell/base/login.groovy b/node/src/main/resources/net/corda/node/shell/base/login.groovy index 500704ae69..f6df32b386 100644 --- a/node/src/main/resources/net/corda/node/shell/base/login.groovy +++ b/node/src/main/resources/net/corda/node/shell/base/login.groovy @@ -11,5 +11,5 @@ Useful commands include 'help' to see what is available, and 'bye' to shut down """ prompt = { -> - return "${new Date()}>>> "; + return "${new Date()}>>> " } diff --git a/node/src/test/java/net/corda/node/services/vault/VaultQueryJavaTests.java b/node/src/test/java/net/corda/node/services/vault/VaultQueryJavaTests.java index 6a38dde99a..97dab2aaa7 100644 --- a/node/src/test/java/net/corda/node/services/vault/VaultQueryJavaTests.java +++ b/node/src/test/java/net/corda/node/services/vault/VaultQueryJavaTests.java @@ -91,10 +91,10 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase { @Test public void unconsumedStatesForStateRefsSortedByTxnId() { Vault issuedStates = - database.transaction(tx -> { - VaultFiller.fillWithSomeTestLinearStates(services, 8); - return VaultFiller.fillWithSomeTestLinearStates(services, 2); - }); + database.transaction(tx -> { + VaultFiller.fillWithSomeTestLinearStates(services, 8); + return VaultFiller.fillWithSomeTestLinearStates(services, 2); + }); database.transaction(tx -> { Stream stateRefsStream = StreamSupport.stream(issuedStates.getStates().spliterator(), false).map(StateAndRef::getRef); List stateRefs = stateRefsStream.collect(Collectors.toList()); @@ -120,7 +120,7 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase { database.transaction(tx -> { VaultFiller.fillWithSomeTestCash(services, new Amount(100, Currency.getInstance("USD")), - issuerServices, + issuerServices, TestConstants.getDUMMY_NOTARY(), 3, 3, @@ -151,14 +151,14 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase { List dealIds = Arrays.asList("123", "456", "789"); @SuppressWarnings("unchecked") Triple, UniqueIdentifier, Vault> ids = - database.transaction((DatabaseTransaction tx) -> { - Vault states = VaultFiller.fillWithSomeTestLinearStates(services, 10, null); - StateAndRef linearState = states.getStates().iterator().next(); - UniqueIdentifier uid = linearState.component1().getData().getLinearId(); + database.transaction((DatabaseTransaction tx) -> { + Vault states = VaultFiller.fillWithSomeTestLinearStates(services, 10, null); + StateAndRef linearState = states.getStates().iterator().next(); + UniqueIdentifier uid = linearState.component1().getData().getLinearId(); - Vault dealStates = VaultFiller.fillWithSomeTestDeals(services, dealIds); - return new Triple(linearState,uid,dealStates); - }); + Vault dealStates = VaultFiller.fillWithSomeTestDeals(services, dealIds); + return new Triple(linearState, uid, dealStates); + }); database.transaction(tx -> { // consume states VaultFiller.consumeDeals(services, (List>) ids.getThird().getStates(), getDUMMY_NOTARY()); @@ -276,13 +276,13 @@ public class VaultQueryJavaTests extends TestDependencyInjectionBase { public void trackDealStatesPagedSorted() { List dealIds = Arrays.asList("123", "456", "789"); UniqueIdentifier uid = - database.transaction(tx -> { - Vault states = VaultFiller.fillWithSomeTestLinearStates(services, 10, null); - UniqueIdentifier _uid = states.getStates().iterator().next().component1().getData().getLinearId(); + database.transaction(tx -> { + Vault states = VaultFiller.fillWithSomeTestLinearStates(services, 10, null); + UniqueIdentifier _uid = states.getStates().iterator().next().component1().getData().getLinearId(); - VaultFiller.fillWithSomeTestDeals(services, dealIds); - return _uid; - }); + VaultFiller.fillWithSomeTestDeals(services, dealIds); + return _uid; + }); database.transaction(tx -> { // DOCSTART VaultJavaQueryExample5 @SuppressWarnings("unchecked") diff --git a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt index a33dadfcea..e03fd6972c 100644 --- a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt +++ b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt @@ -272,6 +272,6 @@ class CordaRPCOpsImplTest { @StartableByRPC class VoidRPCFlow : FlowLogic() { @Suspendable - override fun call() : Void? = null + override fun call(): Void? = null } } diff --git a/node/src/test/kotlin/net/corda/node/InteractiveShellTest.kt b/node/src/test/kotlin/net/corda/node/InteractiveShellTest.kt index d13fda0a4c..f694eec66c 100644 --- a/node/src/test/kotlin/net/corda/node/InteractiveShellTest.kt +++ b/node/src/test/kotlin/net/corda/node/InteractiveShellTest.kt @@ -84,4 +84,4 @@ class InteractiveShellTest { fun party() = check("party: \"${MEGA_CORP.name}\"", MEGA_CORP.name.toString()) class DummyFSM(val logic: FlowA) : FlowStateMachine by mock() - } +} diff --git a/node/src/test/kotlin/net/corda/node/internal/cordapp/CordappLoaderTest.kt b/node/src/test/kotlin/net/corda/node/internal/cordapp/CordappLoaderTest.kt index c1a1b6e5b0..6e8fab1620 100644 --- a/node/src/test/kotlin/net/corda/node/internal/cordapp/CordappLoaderTest.kt +++ b/node/src/test/kotlin/net/corda/node/internal/cordapp/CordappLoaderTest.kt @@ -9,25 +9,29 @@ import java.nio.file.Paths @InitiatingFlow class DummyFlow : FlowLogic() { @Suspendable - override fun call() { } + override fun call() { + } } @InitiatedBy(DummyFlow::class) class LoaderTestFlow(unusedSession: FlowSession) : FlowLogic() { @Suspendable - override fun call() { } + override fun call() { + } } @SchedulableFlow class DummySchedulableFlow : FlowLogic() { @Suspendable - override fun call() { } + override fun call() { + } } @StartableByRPC class DummyRPCFlow : FlowLogic() { @Suspendable - override fun call() { } + override fun call() { + } } class CordappLoaderTest { diff --git a/node/src/test/kotlin/net/corda/node/internal/cordapp/CordappProviderImplTests.kt b/node/src/test/kotlin/net/corda/node/internal/cordapp/CordappProviderImplTests.kt index 10dcd4a3ad..877037c387 100644 --- a/node/src/test/kotlin/net/corda/node/internal/cordapp/CordappProviderImplTests.kt +++ b/node/src/test/kotlin/net/corda/node/internal/cordapp/CordappProviderImplTests.kt @@ -37,7 +37,7 @@ class CordappProviderImplTests { val provider = CordappProviderImpl(loader) provider.start(attachmentStore) - + Assert.assertNull(provider.getCordappAttachmentId(provider.cordapps.first())) } diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index 294d758cf4..ffaafa6246 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -80,6 +80,7 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) { return listOf(true, false) } } + private lateinit var mockNet: MockNetwork @Before @@ -164,8 +165,8 @@ class TwoPartyTradeFlowTests(val anonymous: Boolean) { val cashStates = bobNode.database.transaction { bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, notary, 3, 3, - issuedBy = issuer) - } + issuedBy = issuer) + } val alicesFakePaper = aliceNode.database.transaction { fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(), diff --git a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt index bb7c0d3e92..013eea5d74 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt @@ -153,7 +153,7 @@ class ScheduledFlowTests { val statesFromB: List> = nodeB.database.transaction { queryStatesWithPaging(nodeB.services.vaultService) } - assertEquals("Expect all states to be present",2 * N, statesFromA.count()) + assertEquals("Expect all states to be present", 2 * N, statesFromA.count()) statesFromA.forEach { ref -> if (ref !in statesFromB) { throw IllegalStateException("State $ref is only present on node A.") diff --git a/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt b/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt index 3d1942c01c..6a1adee86a 100644 --- a/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/messaging/ArtemisMessagingTests.kt @@ -40,7 +40,9 @@ import kotlin.test.assertNull //TODO This needs to be merged into P2PMessagingTest as that creates a more realistic environment class ArtemisMessagingTests : TestDependencyInjectionBase() { - @Rule @JvmField val temporaryFolder = TemporaryFolder() + @Rule + @JvmField + val temporaryFolder = TemporaryFolder() val serverPort = freePort() val rpcPort = freePort() diff --git a/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt index a8646caad0..5e0f97e770 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt @@ -44,7 +44,7 @@ abstract class AbstractNetworkMapServiceTest lateinit var alice: StartedNode companion object { - val subscriberLegalName = CordaX500Name(organisation ="Subscriber", locality ="New York", country ="US") + val subscriberLegalName = CordaX500Name(organisation = "Subscriber", locality = "New York", country = "US") } @Before @@ -205,7 +205,7 @@ abstract class AbstractNetworkMapServiceTest private var lastSerial = Long.MIN_VALUE private fun StartedNode<*>.registration(addOrRemove: AddOrRemove, - serial: Long? = null): CordaFuture { + serial: Long? = null): CordaFuture { val distinctSerial = if (serial == null) { ++lastSerial } else { diff --git a/node/src/test/kotlin/net/corda/node/services/persistence/DBTransactionStorageTests.kt b/node/src/test/kotlin/net/corda/node/services/persistence/DBTransactionStorageTests.kt index f043a4c675..3a3148c0db 100644 --- a/node/src/test/kotlin/net/corda/node/services/persistence/DBTransactionStorageTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/persistence/DBTransactionStorageTests.kt @@ -42,11 +42,12 @@ class DBTransactionStorageTests : TestDependencyInjectionBase() { database.transaction { services = object : MockServices(BOB_KEY) { - override val vaultService: VaultServiceInternal get() { - val vaultService = NodeVaultService(clock, keyManagementService, stateLoader, database.hibernateConfig) - hibernatePersister = HibernateObserver(vaultService.rawUpdates, database.hibernateConfig) - return vaultService - } + override val vaultService: VaultServiceInternal + get() { + val vaultService = NodeVaultService(clock, keyManagementService, stateLoader, database.hibernateConfig) + hibernatePersister = HibernateObserver(vaultService.rawUpdates, database.hibernateConfig) + return vaultService + } override fun recordTransactions(txs: Iterable) { for (stx in txs) { diff --git a/node/src/test/kotlin/net/corda/node/services/persistence/HibernateConfigurationTest.kt b/node/src/test/kotlin/net/corda/node/services/persistence/HibernateConfigurationTest.kt index 7cb537575b..e554ea59be 100644 --- a/node/src/test/kotlin/net/corda/node/services/persistence/HibernateConfigurationTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/persistence/HibernateConfigurationTest.kt @@ -89,6 +89,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() { // Refactored to use notifyAll() as we have no other unit test for that method with multiple transactions. vaultService.notifyAll(txs.map { it.tx }) } + override fun jdbcSession() = database.createSession() } hibernatePersister = services.hibernatePersister @@ -146,10 +147,10 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() { @Test fun `select by composite primary key`() { val issuedStates = - database.transaction { - services.fillWithSomeTestLinearStates(8) - services.fillWithSomeTestLinearStates(2) - } + database.transaction { + services.fillWithSomeTestLinearStates(8) + services.fillWithSomeTestLinearStates(2) + } val persistentStateRefs = issuedStates.states.map { PersistentStateRef(it.ref) }.toList() // structure query @@ -383,7 +384,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() { // aggregate function criteriaQuery.multiselect(cashStates.get("currency"), - criteriaBuilder.sum(cashStates.get("pennies"))) + criteriaBuilder.sum(cashStates.get("pennies"))) // group by criteriaQuery.groupBy(cashStates.get("currency")) @@ -627,7 +628,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() { services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L), ownedBy = ALICE) val cashStates = services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L), - issuedBy = BOB.ref(0), ownedBy = (BOB)).states + issuedBy = BOB.ref(0), ownedBy = (BOB)).states // persist additional cash states explicitly with V3 schema cashStates.forEach { val cashState = it.state.data @@ -662,7 +663,8 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() { queryResults.forEach { val contractState = it.contractState.deserialize>(context = SerializationDefaults.STORAGE_CONTEXT) val cashState = contractState.data as Cash.State - println("${it.stateRef} with owner: ${cashState.owner.owningKey.toBase58String()}") } + println("${it.stateRef} with owner: ${cashState.owner.owningKey.toBase58String()}") + } assertThat(queryResults).hasSize(12) } @@ -697,32 +699,32 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() { @Test fun `query fungible states by participants`() { val firstCashState = - database.transaction { - // persist original cash states explicitly with V3 schema - cashStates.forEach { - val cashState = it.state.data - val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner) - hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3) - } + database.transaction { + // persist original cash states explicitly with V3 schema + cashStates.forEach { + val cashState = it.state.data + val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner) + hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3) + } - val moreCash = services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L), - issuedBy = BOB.ref(0), ownedBy = BOB).states - // persist additional cash states explicitly with V3 schema - moreCash.forEach { - val cashState = it.state.data - val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner) - hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3) - } + val moreCash = services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L), + issuedBy = BOB.ref(0), ownedBy = BOB).states + // persist additional cash states explicitly with V3 schema + moreCash.forEach { + val cashState = it.state.data + val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner) + hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3) + } - val cashStates = services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L), ownedBy = (ALICE)).states - // persist additional cash states explicitly with V3 schema - cashStates.forEach { - val cashState = it.state.data - val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner) - hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3) + val cashStates = services.fillWithSomeTestCash(100.DOLLARS, issuerServices, DUMMY_NOTARY, 2, 2, Random(0L), ownedBy = (ALICE)).states + // persist additional cash states explicitly with V3 schema + cashStates.forEach { + val cashState = it.state.data + val dummyFungibleState = DummyFungibleContract.State(cashState.amount, cashState.owner) + hibernatePersister.persistStateWithSchema(dummyFungibleState, it.ref, SampleCashSchemaV3) + } + cashStates.first() } - cashStates.first() - } // structure query val criteriaQuery = criteriaBuilder.createQuery(VaultSchemaV1.VaultStates::class.java) @@ -874,7 +876,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() { val jdbcSession = services.jdbcSession() val prepStatement = jdbcSession.prepareStatement(nativeQuery) val rs = prepStatement.executeQuery() - // DOCEND JdbcSession + // DOCEND JdbcSession var count = 0 while (rs.next()) { val stateRef = StateRef(SecureHash.parse(rs.getString(1)), rs.getInt(2)) diff --git a/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt b/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt index 0481ca51cd..46e954ecde 100644 --- a/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/persistence/NodeAttachmentStorageTest.kt @@ -99,18 +99,18 @@ class NodeAttachmentStorageTest { fun `corrupt entry throws exception`() { val testJar = makeTestJar() val id = - database.transaction { - val storage = NodeAttachmentService(MetricRegistry()) - val id = testJar.read { storage.importAttachment(it) } + database.transaction { + val storage = NodeAttachmentService(MetricRegistry()) + val id = testJar.read { storage.importAttachment(it) } - // Corrupt the file in the store. - val bytes = testJar.readAll() - val corruptBytes = "arggghhhh".toByteArray() - System.arraycopy(corruptBytes, 0, bytes, 0, corruptBytes.size) - val corruptAttachment = NodeAttachmentService.DBAttachment(attId = id.toString(), content = bytes) - DatabaseTransactionManager.current().session.merge(corruptAttachment) - id - } + // Corrupt the file in the store. + val bytes = testJar.readAll() + val corruptBytes = "arggghhhh".toByteArray() + System.arraycopy(corruptBytes, 0, bytes, 0, corruptBytes.size) + val corruptAttachment = NodeAttachmentService.DBAttachment(attId = id.toString(), content = bytes) + DatabaseTransactionManager.current().session.merge(corruptAttachment) + id + } database.transaction { val storage = NodeAttachmentService(MetricRegistry()) val e = assertFailsWith { diff --git a/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt index d7b90b8880..73bb252af5 100644 --- a/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt @@ -41,7 +41,7 @@ class NodeSchemaServiceTest { */ @Test fun `auto scanning of custom schemas for testing with Driver`() { - driver (startNodesInProcess = true) { + driver(startNodesInProcess = true) { val node = startNode() val nodeHandle = node.getOrThrow() val result = nodeHandle.rpc.startFlow(::MappedSchemasFlow) @@ -53,7 +53,7 @@ class NodeSchemaServiceTest { @StartableByRPC class MappedSchemasFlow : FlowLogic>() { @Suspendable - override fun call() : List { + override fun call(): List { // returning MappedSchema's as String'ified family names to avoid whitelist serialization errors return (this.serviceHub as ServiceHubInternal).schemaService.schemaOptions.keys.map { it.name } } diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt index 42b504a65e..57ca2cebba 100644 --- a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt @@ -702,8 +702,7 @@ class FlowFrameworkTests { private inline fun > StartedNode<*>.registerFlowFactory( initiatingFlowClass: KClass>, initiatedFlowVersion: Int = 1, - noinline flowFactory: (FlowSession) -> P): CordaFuture

- { + noinline flowFactory: (FlowSession) -> P): CordaFuture

{ val observable = internals.internalRegisterFlowFactory( initiatingFlowClass.java, InitiatedFlowFactory.CorDapp(initiatedFlowVersion, "", flowFactory), @@ -715,6 +714,7 @@ class FlowFrameworkTests { private fun sessionInit(clientFlowClass: KClass>, flowVersion: Int = 1, payload: Any? = null): SessionInit { return SessionInit(0, clientFlowClass.java.name, flowVersion, "", payload) } + private fun sessionConfirm(flowVersion: Int = 1) = SessionConfirm(0, 0, flowVersion, "") private fun sessionData(payload: Any) = SessionData(0, payload) private val normalEnd = NormalSessionEnd(0) @@ -766,14 +766,15 @@ class FlowFrameworkTests { private infix fun StartedNode.sent(message: SessionMessage): Pair = Pair(internals.id, message) private infix fun Pair.to(node: StartedNode<*>): SessionTransfer = SessionTransfer(first, second, node.network.myAddress) - private val FlowLogic<*>.progressSteps: CordaFuture>> get() { - return progressTracker!!.changes - .ofType(Change.Position::class.java) - .map { it.newStep } - .materialize() - .toList() - .toFuture() - } + private val FlowLogic<*>.progressSteps: CordaFuture>> + get() { + return progressTracker!!.changes + .ofType(Change.Position::class.java) + .map { it.newStep } + .materialize() + .toList() + .toFuture() + } private class LazyServiceHubAccessFlow : FlowLogic() { val lazyTime: Instant by lazy { serviceHub.clock.instant() } @@ -782,7 +783,8 @@ class FlowFrameworkTests { } private class NoOpFlow(val nonTerminating: Boolean = false) : FlowLogic() { - @Transient var flowStarted = false + @Transient + var flowStarted = false @Suspendable override fun call() { @@ -833,7 +835,8 @@ class FlowFrameworkTests { override val progressTracker: ProgressTracker = ProgressTracker(START_STEP, RECEIVED_STEP) private var nonTerminating: Boolean = false - @Transient var receivedPayloads: List = emptyList() + @Transient + var receivedPayloads: List = emptyList() @Suspendable override fun call() { @@ -879,6 +882,7 @@ class FlowFrameworkTests { @InitiatingFlow private class SendAndReceiveFlow(val otherParty: Party, val payload: Any, val otherPartySession: FlowSession? = null) : FlowLogic() { constructor(otherPartySession: FlowSession, payload: Any) : this(otherPartySession.counterparty, payload, otherPartySession) + @Suspendable override fun call(): Any = (otherPartySession ?: initiateFlow(otherParty)).sendAndReceive(payload).unwrap { it } } @@ -891,8 +895,11 @@ class FlowFrameworkTests { @InitiatingFlow private class PingPongFlow(val otherParty: Party, val payload: Long, val otherPartySession: FlowSession? = null) : FlowLogic() { constructor(otherPartySession: FlowSession, payload: Long) : this(otherPartySession.counterparty, payload, otherPartySession) - @Transient var receivedPayload: Long? = null - @Transient var receivedPayload2: Long? = null + + @Transient + var receivedPayload: Long? = null + @Transient + var receivedPayload2: Long? = null @Suspendable override fun call() { @@ -959,6 +966,7 @@ class FlowFrameworkTests { @InitiatingFlow(version = 2) private class UpgradedFlow(val otherParty: Party, val otherPartySession: FlowSession? = null) : FlowLogic>() { constructor(otherPartySession: FlowSession) : this(otherPartySession.counterparty, otherPartySession) + @Suspendable override fun call(): Pair { val otherPartySession = this.otherPartySession ?: initiateFlow(otherParty) diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt index 1c1124cb1f..491931ab2a 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/PersistentUniquenessProviderTests.kt @@ -32,7 +32,8 @@ class PersistentUniquenessProviderTests : TestDependencyInjectionBase() { LogHelper.reset(PersistentUniquenessProvider::class) } - @Test fun `should commit a transaction with unused inputs without exception`() { + @Test + fun `should commit a transaction with unused inputs without exception`() { database.transaction { val provider = PersistentUniquenessProvider() val inputState = generateStateRef() @@ -41,7 +42,8 @@ class PersistentUniquenessProviderTests : TestDependencyInjectionBase() { } } - @Test fun `should report a conflict for a transaction with previously used inputs`() { + @Test + fun `should report a conflict for a transaction with previously used inputs`() { database.transaction { val provider = PersistentUniquenessProvider() val inputState = generateStateRef() diff --git a/node/src/test/kotlin/net/corda/node/services/vault/NodeVaultServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/vault/NodeVaultServiceTest.kt index 8b364eb12b..5250e7f500 100644 --- a/node/src/test/kotlin/net/corda/node/services/vault/NodeVaultServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/vault/NodeVaultServiceTest.kt @@ -55,7 +55,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() { setCordappPackages("net.corda.finance.contracts.asset") LogHelper.setLevel(NodeVaultService::class) val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(BOC_KEY, DUMMY_CASH_ISSUER_KEY), - customSchemas = setOf(CashSchemaV1)) + customSchemas = setOf(CashSchemaV1)) database = databaseAndServices.first services = databaseAndServices.second issuerServices = MockServices(DUMMY_CASH_ISSUER_KEY, BOC_KEY) @@ -195,7 +195,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() { assertThat(vaultService.queryBy(criteriaByLockId1).states).hasSize(3) } println("SOFT LOCK STATES #1 succeeded") - } catch(e: Throwable) { + } catch (e: Throwable) { println("SOFT LOCK STATES #1 failed") } finally { countDown.countDown() @@ -211,7 +211,7 @@ class NodeVaultServiceTest : TestDependencyInjectionBase() { assertThat(vaultService.queryBy(criteriaByLockId2).states).hasSize(3) } println("SOFT LOCK STATES #2 succeeded") - } catch(e: Throwable) { + } catch (e: Throwable) { println("SOFT LOCK STATES #2 failed") } finally { countDown.countDown() diff --git a/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt b/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt index 74c799fc57..9e484833d6 100644 --- a/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/vault/VaultQueryTests.kt @@ -65,8 +65,8 @@ class VaultQueryTests : TestDependencyInjectionBase() { identitySvc.verifyAndRegisterIdentity(CASH_NOTARY_IDENTITY) identitySvc.verifyAndRegisterIdentity(BOC_IDENTITY) val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(MEGA_CORP_KEY, DUMMY_NOTARY_KEY), - createIdentityService = { identitySvc }, - customSchemas = setOf(CashSchemaV1, CommercialPaperSchemaV1, DummyLinearStateSchemaV1)) + createIdentityService = { identitySvc }, + customSchemas = setOf(CashSchemaV1, CommercialPaperSchemaV1, DummyLinearStateSchemaV1)) database = databaseAndServices.first services = databaseAndServices.second notaryServices = MockServices(DUMMY_NOTARY_KEY, DUMMY_CASH_ISSUER_KEY, BOC_KEY, MEGA_CORP_KEY) @@ -1064,7 +1064,7 @@ class VaultQueryTests : TestDependencyInjectionBase() { } database.transaction { @Suppress("EXPECTED_CONDITION") - val pagingSpec = PageSpecification(DEFAULT_PAGE_NUM, @Suppress("INTEGER_OVERFLOW")MAX_PAGE_SIZE + 1) // overflow = -2147483648 + val pagingSpec = PageSpecification(DEFAULT_PAGE_NUM, @Suppress("INTEGER_OVERFLOW") MAX_PAGE_SIZE + 1) // overflow = -2147483648 val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL) vaultService.queryBy(criteria, paging = pagingSpec) } diff --git a/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt b/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt index a1450132a5..60e853d023 100644 --- a/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/vault/VaultWithCashTest.kt @@ -46,7 +46,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() { LogHelper.setLevel(VaultWithCashTest::class) val databaseAndServices = makeTestDatabaseAndMockServices(keys = listOf(DUMMY_CASH_ISSUER_KEY, DUMMY_NOTARY_KEY), - customSchemas = setOf(CashSchemaV1)) + customSchemas = setOf(CashSchemaV1)) database = databaseAndServices.first services = databaseAndServices.second issuerServices = MockServices(DUMMY_CASH_ISSUER_KEY, MEGA_CORP_KEY) @@ -85,24 +85,24 @@ class VaultWithCashTest : TestDependencyInjectionBase() { val freshKey = services.keyManagementService.freshKey() val usefulTX = - database.transaction { - // A tx that sends us money. - val usefulBuilder = TransactionBuilder(null) - Cash().generateIssue(usefulBuilder, 100.DOLLARS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshKey), DUMMY_NOTARY) - megaCorpServices.signInitialTransaction(usefulBuilder) - } + database.transaction { + // A tx that sends us money. + val usefulBuilder = TransactionBuilder(null) + Cash().generateIssue(usefulBuilder, 100.DOLLARS `issued by` MEGA_CORP.ref(1), AnonymousParty(freshKey), DUMMY_NOTARY) + megaCorpServices.signInitialTransaction(usefulBuilder) + } database.transaction { assertEquals(0.DOLLARS, services.getCashBalance(USD)) services.recordTransactions(usefulTX) } val spendTX = - database.transaction { - // A tx that spends our money. - val spendTXBuilder = TransactionBuilder(DUMMY_NOTARY) - Cash.generateSpend(services, spendTXBuilder, 80.DOLLARS, BOB) - val spendPTX = services.signInitialTransaction(spendTXBuilder, freshKey) - notaryServices.addSignature(spendPTX) - } + database.transaction { + // A tx that spends our money. + val spendTXBuilder = TransactionBuilder(DUMMY_NOTARY) + Cash.generateSpend(services, spendTXBuilder, 80.DOLLARS, BOB) + val spendPTX = services.signInitialTransaction(spendTXBuilder, freshKey) + notaryServices.addSignature(spendPTX) + } database.transaction { assertEquals(100.DOLLARS, services.getCashBalance(USD)) } @@ -174,7 +174,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() { LOCKED: ${lockedStates2.count()} : $lockedStates2 """) txn1 - } catch(e: Exception) { + } catch (e: Exception) { println(e) } } @@ -210,7 +210,7 @@ class VaultWithCashTest : TestDependencyInjectionBase() { LOCKED: ${lockedStates2.count()} : $lockedStates2 """) txn2 - } catch(e: Exception) { + } catch (e: Exception) { println(e) } } @@ -254,18 +254,19 @@ class VaultWithCashTest : TestDependencyInjectionBase() { val linearId = UniqueIdentifier() val dummyIssue = - database.transaction { // Issue a linear state - val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY) - .addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID) - .addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey)) - val dummyIssuePtx = notaryServices.signInitialTransaction(dummyIssueBuilder) - val dummyIssue = services.addSignature(dummyIssuePtx) + database.transaction { + // Issue a linear state + val dummyIssueBuilder = TransactionBuilder(notary = DUMMY_NOTARY) + .addOutputState(DummyLinearContract.State(linearId = linearId, participants = listOf(freshIdentity)), DUMMY_LINEAR_CONTRACT_PROGRAM_ID) + .addCommand(dummyCommand(notaryServices.myInfo.chooseIdentity().owningKey)) + val dummyIssuePtx = notaryServices.signInitialTransaction(dummyIssueBuilder) + val dummyIssue = services.addSignature(dummyIssuePtx) - dummyIssue.toLedgerTransaction(services).verify() + dummyIssue.toLedgerTransaction(services).verify() - services.recordTransactions(dummyIssue) - dummyIssue - } + services.recordTransactions(dummyIssue) + dummyIssue + } database.transaction { assertThat(vaultService.queryBy().states).hasSize(1) @@ -333,9 +334,9 @@ class VaultWithCashTest : TestDependencyInjectionBase() { services.fillWithSomeTestDeals(listOf("123", "456", "789")) } val deals = - database.transaction { - vaultService.queryBy().states - } + database.transaction { + vaultService.queryBy().states + } database.transaction { services.fillWithSomeTestLinearStates(3) } diff --git a/node/src/test/kotlin/net/corda/node/utilities/AffinityExecutorTests.kt b/node/src/test/kotlin/net/corda/node/utilities/AffinityExecutorTests.kt index 4187645e33..b1994a3d0c 100644 --- a/node/src/test/kotlin/net/corda/node/utilities/AffinityExecutorTests.kt +++ b/node/src/test/kotlin/net/corda/node/utilities/AffinityExecutorTests.kt @@ -11,12 +11,14 @@ class AffinityExecutorTests { var _executor: AffinityExecutor.ServiceAffinityExecutor? = null val executor: AffinityExecutor.ServiceAffinityExecutor get() = _executor!! - @After fun shutdown() { + @After + fun shutdown() { _executor?.shutdown() _executor = null } - @Test fun `flush handles nested executes`() { + @Test + fun `flush handles nested executes`() { _executor = AffinityExecutor.ServiceAffinityExecutor("test4", 1) var nestedRan = false val latch = CountDownLatch(1) @@ -29,7 +31,8 @@ class AffinityExecutorTests { assertTrue(nestedRan) } - @Test fun `single threaded affinity executor runs on correct thread`() { + @Test + fun `single threaded affinity executor runs on correct thread`() { val thisThread = Thread.currentThread() _executor = AffinityExecutor.ServiceAffinityExecutor("test thread", 1) assertTrue(!executor.isOnThread) @@ -50,7 +53,8 @@ class AffinityExecutorTests { assertEquals(thread2.get(), thread.get()) } - @Test fun `pooled executor`() { + @Test + fun `pooled executor`() { _executor = AffinityExecutor.ServiceAffinityExecutor("test2", 3) assertFalse(executor.isOnThread) diff --git a/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt b/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt index d0cdb64932..b1c0ace017 100644 --- a/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt +++ b/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt @@ -13,7 +13,8 @@ import java.util.concurrent.CompletableFuture.supplyAsync class AttachmentDemoTest { // run with a 10,000,000 bytes in-memory zip file. In practice, a slightly bigger file will be used (~10,002,000 bytes). - @Test fun `attachment demo using a 10MB zip file`() { + @Test + fun `attachment demo using a 10MB zip file`() { val numOfExpectedBytes = 10_000_000 driver(isDebug = true, portAllocation = PortAllocation.Incremental(20000)) { val demoUser = listOf(User("demo", "demo", setOf(startFlowPermission()))) diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt index 097a33c5e8..c81d80592c 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt @@ -141,11 +141,12 @@ class FloatingRatePaymentEvent(date: LocalDate, val CSVHeader = RatePaymentEvent.CSVHeader + ",FixingDate" } - override val flow: Amount get() { - // TODO: Should an uncalculated amount return a zero ? null ? etc. - val v = rate.ratioUnit?.value ?: return Amount(0, notional.token) - return Amount(dayCountFactor.times(BigDecimal(notional.quantity)).times(v).toLong(), notional.token) - } + override val flow: Amount + get() { + // TODO: Should an uncalculated amount return a zero ? null ? etc. + val v = rate.ratioUnit?.value ?: return Amount(0, notional.token) + return Amount(dayCountFactor.times(BigDecimal(notional.quantity)).times(v).toLong(), notional.token) + } override fun toString(): String = "FloatingPaymentEvent $accrualStartDate -> $accrualEndDate : $dayCountFactor : $days : $date : $notional : $rate (fix on $fixingDate): $flow" diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRSUtils.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRSUtils.kt index fb7e367a3c..c362e602a5 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRSUtils.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRSUtils.kt @@ -71,7 +71,6 @@ class FixedRate(ratioUnit: RatioUnit) : Rate(ratioUnit) { fun isPositive(): Boolean = ratioUnit!!.value > BigDecimal("0.0") override fun equals(other: Any?) = other?.javaClass == javaClass && super.equals(other) - override fun hashCode() = super.hashCode() } /** diff --git a/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt b/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt index a6b720cf72..ef07a9a5a3 100644 --- a/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt +++ b/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt @@ -242,7 +242,7 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() { } private fun makePartialTX() = TransactionBuilder(DUMMY_NOTARY).withItems( - TransactionState(1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE, Cash.PROGRAM_ID, DUMMY_NOTARY)) + TransactionState(1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE, Cash.PROGRAM_ID, DUMMY_NOTARY)) private fun makeFullTx() = makePartialTX().withItems(dummyCommand()) } diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt index f9751e8d6c..f8f9c1f625 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt @@ -86,7 +86,7 @@ class VisualiserViewModel { // top right: 33.0469,64.3209 try { return node.place.coordinate.project(view.mapImage.fitWidth, view.mapImage.fitHeight, 64.3209, 29.8406, -23.2031, 33.0469) - } catch(e: Exception) { + } catch (e: Exception) { throw Exception("Cannot project ${node.started!!.info.chooseIdentity()}", e) } } diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt index af7aae480e..0df1f7cdc2 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt @@ -141,6 +141,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java) val notaryId = node1.rpcOps.notaryIdentities().first() + @InitiatingFlow class StartDealFlow(val otherParty: Party, val payload: AutoOffer) : FlowLogic() { diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt index 46a38d7f5e..74529cd530 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt @@ -162,8 +162,10 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, // These are used from the network visualiser tool. private val _allFlowSteps = PublishSubject.create>() private val _doneSteps = PublishSubject.create>() - @Suppress("unused") val allFlowSteps: Observable> = _allFlowSteps - @Suppress("unused") val doneSteps: Observable> = _doneSteps + @Suppress("unused") + val allFlowSteps: Observable> = _allFlowSteps + @Suppress("unused") + val doneSteps: Observable> = _doneSteps private var pumpCursor = 0 diff --git a/samples/network-visualiser/src/test/kotlin/net/corda/netmap/simulation/IRSSimulationTest.kt b/samples/network-visualiser/src/test/kotlin/net/corda/netmap/simulation/IRSSimulationTest.kt index 7a329a9ad4..4bd32364a4 100644 --- a/samples/network-visualiser/src/test/kotlin/net/corda/netmap/simulation/IRSSimulationTest.kt +++ b/samples/network-visualiser/src/test/kotlin/net/corda/netmap/simulation/IRSSimulationTest.kt @@ -21,7 +21,8 @@ class IRSSimulationTest { unsetCordappPackages() } - @Test fun `runs to completion`() { + @Test + fun `runs to completion`() { LogHelper.setLevel("+messages") // FIXME: Don't manipulate static state in tests. val sim = IRSSimulation(false, false, null) val future = sim.start() diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt index c107c44578..cabacf9476 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt @@ -31,7 +31,7 @@ private class NotaryDemoClientApi(val rpc: CordaRPCOps) { private val counterparty by lazy { val parties = rpc.networkMapSnapshot() parties.fold(ArrayList()) { acc, elem -> - acc.addAll(elem.legalIdentitiesAndCerts.filter { it.name == BOB.name}) + acc.addAll(elem.legalIdentitiesAndCerts.filter { it.name == BOB.name }) acc }.single().party } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/DirectoryMarketDataBuilder.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/DirectoryMarketDataBuilder.java index fcb4949773..b9c5f02823 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/DirectoryMarketDataBuilder.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/DirectoryMarketDataBuilder.java @@ -1,6 +1,6 @@ /** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. */ package com.opengamma.strata.examples.marketdata; @@ -19,46 +19,46 @@ import java.util.stream.Collectors; */ public class DirectoryMarketDataBuilder extends ExampleMarketDataBuilder { - /** - * The path to the root of the directory structure. - */ - private final Path rootPath; + /** + * The path to the root of the directory structure. + */ + private final Path rootPath; - /** - * Constructs an instance. - * - * @param rootPath the path to the root of the directory structure - */ - public DirectoryMarketDataBuilder(Path rootPath) { - this.rootPath = rootPath; - } - - //------------------------------------------------------------------------- - @Override - protected Collection getAllResources(String subdirectoryName) { - File dir = rootPath.resolve(subdirectoryName).toFile(); - if (!dir.exists()) { - throw new IllegalArgumentException(Messages.format("Directory does not exist: {}", dir)); + /** + * Constructs an instance. + * + * @param rootPath the path to the root of the directory structure + */ + public DirectoryMarketDataBuilder(Path rootPath) { + this.rootPath = rootPath; } - return Arrays.stream(dir.listFiles()) - .filter(f -> !f.isHidden()) - .map(ResourceLocator::ofFile) - .collect(Collectors.toList()); - } - @Override - protected ResourceLocator getResource(String subdirectoryName, String resourceName) { - File file = rootPath.resolve(subdirectoryName).resolve(resourceName).toFile(); - if (!file.exists()) { - return null; + //------------------------------------------------------------------------- + @Override + protected Collection getAllResources(String subdirectoryName) { + File dir = rootPath.resolve(subdirectoryName).toFile(); + if (!dir.exists()) { + throw new IllegalArgumentException(Messages.format("Directory does not exist: {}", dir)); + } + return Arrays.stream(dir.listFiles()) + .filter(f -> !f.isHidden()) + .map(ResourceLocator::ofFile) + .collect(Collectors.toList()); } - return ResourceLocator.ofFile(file); - } - @Override - protected boolean subdirectoryExists(String subdirectoryName) { - File file = rootPath.resolve(subdirectoryName).toFile(); - return file.exists(); - } + @Override + protected ResourceLocator getResource(String subdirectoryName, String resourceName) { + File file = rootPath.resolve(subdirectoryName).resolve(resourceName).toFile(); + if (!file.exists()) { + return null; + } + return ResourceLocator.ofFile(file); + } + + @Override + protected boolean subdirectoryExists(String subdirectoryName) { + File file = rootPath.resolve(subdirectoryName).toFile(); + return file.exists(); + } } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleData.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleData.java index 5780b6c0d9..7073b361b2 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleData.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleData.java @@ -1,6 +1,6 @@ /** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. */ package com.opengamma.strata.examples.marketdata; @@ -18,40 +18,41 @@ import java.util.Locale; */ public final class ExampleData { - /** - * Restricted constructor. - */ - private ExampleData() { - } - - //------------------------------------------------------------------------- - /** - * Loads a golden copy of expected results from a text file. - * - * @param name the name of the results - * @return the loaded results - */ - public static String loadExpectedResults(String name) { - String classpathResourceName = String.format(Locale.ENGLISH, "classpath:goldencopy/%s.txt", name); - ResourceLocator resourceLocator = ResourceLocator.of(classpathResourceName); - try { - return resourceLocator.getCharSource().read().trim(); - } catch (IOException ex) { - throw new UncheckedIOException(name, ex); + /** + * Restricted constructor. + */ + private ExampleData() { } - } - /** - * Loads a trade report template from the standard INI format. - * - * @param templateName the name of the template - * @return the loaded report template - */ - public static TradeReportTemplate loadTradeReportTemplate(String templateName) { - String resourceName = String.format(Locale.ENGLISH, "classpath:example-reports/%s.ini", templateName); - ResourceLocator resourceLocator = ResourceLocator.of(resourceName); - IniFile ini = IniFile.of(resourceLocator.getCharSource()); - return TradeReportTemplate.load(ini); - } + //------------------------------------------------------------------------- + + /** + * Loads a golden copy of expected results from a text file. + * + * @param name the name of the results + * @return the loaded results + */ + public static String loadExpectedResults(String name) { + String classpathResourceName = String.format(Locale.ENGLISH, "classpath:goldencopy/%s.txt", name); + ResourceLocator resourceLocator = ResourceLocator.of(classpathResourceName); + try { + return resourceLocator.getCharSource().read().trim(); + } catch (IOException ex) { + throw new UncheckedIOException(name, ex); + } + } + + /** + * Loads a trade report template from the standard INI format. + * + * @param templateName the name of the template + * @return the loaded report template + */ + public static TradeReportTemplate loadTradeReportTemplate(String templateName) { + String resourceName = String.format(Locale.ENGLISH, "classpath:example-reports/%s.ini", templateName); + ResourceLocator resourceLocator = ResourceLocator.of(resourceName); + IniFile ini = IniFile.of(resourceLocator.getCharSource()); + return TradeReportTemplate.load(ini); + } } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleMarketData.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleMarketData.java index a0fb78bed6..9ed74a4b23 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleMarketData.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleMarketData.java @@ -1,6 +1,6 @@ /** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. */ package com.opengamma.strata.examples.marketdata; @@ -10,25 +10,26 @@ package com.opengamma.strata.examples.marketdata; */ public final class ExampleMarketData { - /** - * Root resource directory of the built-in example market data - */ - private static final String EXAMPLE_MARKET_DATA_ROOT = "example-marketdata"; + /** + * Root resource directory of the built-in example market data + */ + private static final String EXAMPLE_MARKET_DATA_ROOT = "example-marketdata"; - /** - * Restricted constructor. - */ - private ExampleMarketData() { - } + /** + * Restricted constructor. + */ + private ExampleMarketData() { + } - //------------------------------------------------------------------------- - /** - * Gets a market data builder for the built-in example market data. - * - * @return the market data builder - */ - public static ExampleMarketDataBuilder builder() { - return ExampleMarketDataBuilder.ofResource(EXAMPLE_MARKET_DATA_ROOT); - } + //------------------------------------------------------------------------- + + /** + * Gets a market data builder for the built-in example market data. + * + * @return the market data builder + */ + public static ExampleMarketDataBuilder builder() { + return ExampleMarketDataBuilder.ofResource(EXAMPLE_MARKET_DATA_ROOT); + } } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleMarketDataBuilder.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleMarketDataBuilder.java index a59374c7f6..1f81eb3015 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleMarketDataBuilder.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/ExampleMarketDataBuilder.java @@ -1,6 +1,6 @@ /** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. */ package com.opengamma.strata.examples.marketdata; @@ -67,355 +67,358 @@ import static com.opengamma.strata.collect.Guavate.toImmutableList; */ public abstract class ExampleMarketDataBuilder { - private static final Logger log = LoggerFactory.getLogger(ExampleMarketDataBuilder.class); + private static final Logger log = LoggerFactory.getLogger(ExampleMarketDataBuilder.class); - /** The name of the subdirectory containing historical fixings. */ - private static final String HISTORICAL_FIXINGS_DIR = "historical-fixings"; + /** The name of the subdirectory containing historical fixings. */ + private static final String HISTORICAL_FIXINGS_DIR = "historical-fixings"; - /** The name of the subdirectory containing calibrated rates curves. */ - private static final String CURVES_DIR = "curves"; - /** The name of the curve groups file. */ - private static final String CURVES_GROUPS_FILE = "groups.csv"; - /** The name of the curve settings file. */ - private static final String CURVES_SETTINGS_FILE = "settings.csv"; + /** The name of the subdirectory containing calibrated rates curves. */ + private static final String CURVES_DIR = "curves"; + /** The name of the curve groups file. */ + private static final String CURVES_GROUPS_FILE = "groups.csv"; + /** The name of the curve settings file. */ + private static final String CURVES_SETTINGS_FILE = "settings.csv"; - /** The name of the directory containing CDS ISDA yield curve, credit curve and static data. */ - private static final String CREDIT_DIR = "credit"; - private static final String CDS_YIELD_CURVES_FILE = "cds.yieldCurves.csv"; - private static final String SINGLE_NAME_CREDIT_CURVES_FILE = "singleName.creditCurves.csv"; - private static final String SINGLE_NAME_STATIC_DATA_FILE = "singleName.staticData.csv"; - private static final String INDEX_CREDIT_CURVES_FILE = "index.creditCurves.csv"; - private static final String INDEX_STATIC_DATA_FILE = "index.staticData.csv"; + /** The name of the directory containing CDS ISDA yield curve, credit curve and static data. */ + private static final String CREDIT_DIR = "credit"; + private static final String CDS_YIELD_CURVES_FILE = "cds.yieldCurves.csv"; + private static final String SINGLE_NAME_CREDIT_CURVES_FILE = "singleName.creditCurves.csv"; + private static final String SINGLE_NAME_STATIC_DATA_FILE = "singleName.staticData.csv"; + private static final String INDEX_CREDIT_CURVES_FILE = "index.creditCurves.csv"; + private static final String INDEX_STATIC_DATA_FILE = "index.staticData.csv"; - /** The name of the subdirectory containing simple market quotes. */ - private static final String QUOTES_DIR = "quotes"; - /** The name of the quotes file. */ - private static final String QUOTES_FILE = "quotes.csv"; + /** The name of the subdirectory containing simple market quotes. */ + private static final String QUOTES_DIR = "quotes"; + /** The name of the quotes file. */ + private static final String QUOTES_FILE = "quotes.csv"; - //------------------------------------------------------------------------- - /** - * Creates an instance from a given classpath resource root location using the class loader - * which created this class. - *

- * This is designed to handle resource roots which may physically correspond to a directory on - * disk, or be located within a jar file. - * - * @param resourceRoot the resource root path - * @return the market data builder - */ - public static ExampleMarketDataBuilder ofResource(String resourceRoot) { - return ofResource(resourceRoot, ExampleMarketDataBuilder.class.getClassLoader()); - } + //------------------------------------------------------------------------- - /** - * Creates an instance from a given classpath resource root location, using the given class loader - * to find the resource. - *

- * This is designed to handle resource roots which may physically correspond to a directory on - * disk, or be located within a jar file. - * - * @param resourceRoot the resource root path - * @param classLoader the class loader with which to find the resource - * @return the market data builder - */ - public static ExampleMarketDataBuilder ofResource(String resourceRoot, ClassLoader classLoader) { - // classpath resources are forward-slash separated - String qualifiedRoot = resourceRoot; - qualifiedRoot = qualifiedRoot.startsWith("/") ? qualifiedRoot.substring(1) : qualifiedRoot; - qualifiedRoot = qualifiedRoot.startsWith("\\") ? qualifiedRoot.substring(1) : qualifiedRoot; - qualifiedRoot = qualifiedRoot.endsWith("/") ? qualifiedRoot : qualifiedRoot + "/"; - URL url = classLoader.getResource(qualifiedRoot); - if (url == null) { - throw new IllegalArgumentException(Messages.format("Classpath resource not found: {}", qualifiedRoot)); - } - if (url.getProtocol() != null && "jar".equals(url.getProtocol().toLowerCase(Locale.ENGLISH))) { - // Inside a JAR - int classSeparatorIdx = url.getFile().indexOf("!"); - if (classSeparatorIdx == -1) { - throw new IllegalArgumentException(Messages.format("Unexpected JAR file URL: {}", url)); - } - String jarPath = url.getFile().substring("file:".length(), classSeparatorIdx); - File jarFile; - try { - jarFile = new File(jarPath); - } catch (Exception e) { - throw new IllegalArgumentException(Messages.format("Unable to create file for JAR: {}", jarPath), e); - } - return new JarMarketDataBuilder(jarFile, resourceRoot); - } else { - // Resource is on disk - File file; - try { - file = new File(url.toURI()); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(Messages.format("Unexpected file location: {}", url), e); - } - return new DirectoryMarketDataBuilder(file.toPath()); - } - } - - /** - * Creates an instance from a given directory root. - * - * @param rootPath the root directory - * @return the market data builder - */ - public static ExampleMarketDataBuilder ofPath(Path rootPath) { - return new DirectoryMarketDataBuilder(rootPath); - } - - //------------------------------------------------------------------------- - /** - * Builds a market data snapshot from this environment. - * - * @param marketDataDate the date of the market data - * @return the snapshot - */ - public ImmutableMarketData buildSnapshot(LocalDate marketDataDate) { - ImmutableMarketDataBuilder builder = ImmutableMarketData.builder(marketDataDate); - loadFixingSeries(builder); - loadRatesCurves(builder, marketDataDate); - loadQuotes(builder, marketDataDate); - loadFxRates(builder); - loadCreditMarketData(builder, marketDataDate); - return builder.build(); - } - - /** - * Gets the rates market lookup to use with this environment. - * - * @param marketDataDate the date of the market data - * @return the rates lookup - */ - public RatesMarketDataLookup ratesLookup(LocalDate marketDataDate) { - SortedMap curves = loadAllRatesCurves(); - return RatesMarketDataLookup.of(curves.get(marketDataDate)); - } - - /** - * Gets all rates curves. - * - * @return the map of all rates curves - */ - public SortedMap loadAllRatesCurves() { - if (!subdirectoryExists(CURVES_DIR)) { - throw new IllegalArgumentException("No rates curves directory found"); - } - ResourceLocator curveGroupsResource = getResource(CURVES_DIR, CURVES_GROUPS_FILE); - if (curveGroupsResource == null) { - throw new IllegalArgumentException(Messages.format( - "Unable to load rates curves: curve groups file not found at {}/{}", CURVES_DIR, CURVES_GROUPS_FILE)); - } - ResourceLocator curveSettingsResource = getResource(CURVES_DIR, CURVES_SETTINGS_FILE); - if (curveSettingsResource == null) { - throw new IllegalArgumentException(Messages.format( - "Unable to load rates curves: curve settings file not found at {}/{}", CURVES_DIR, CURVES_SETTINGS_FILE)); - } - ListMultimap curveGroups = - RatesCurvesCsvLoader.loadAllDates(curveGroupsResource, curveSettingsResource, getRatesCurvesResources()); - - // There is only one curve group in the market data file so this will always succeed - Map curveGroupMap = Maps.transformValues(curveGroups.asMap(), groups -> groups.iterator().next()); - return new TreeMap<>(curveGroupMap); - } - - //------------------------------------------------------------------------- - private void loadFixingSeries(ImmutableMarketDataBuilder builder) { - if (!subdirectoryExists(HISTORICAL_FIXINGS_DIR)) { - log.debug("No historical fixings directory found"); - return; - } - try { - Collection fixingSeriesResources = getAllResources(HISTORICAL_FIXINGS_DIR); - Map fixingSeries = FixingSeriesCsvLoader.load(fixingSeriesResources); - builder.addTimeSeriesMap(fixingSeries); - } catch (Exception e) { - log.error("Error loading fixing series", e); - } - } - - private void loadRatesCurves(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) { - if (!subdirectoryExists(CURVES_DIR)) { - log.debug("No rates curves directory found"); - return; + /** + * Creates an instance from a given classpath resource root location using the class loader + * which created this class. + *

+ * This is designed to handle resource roots which may physically correspond to a directory on + * disk, or be located within a jar file. + * + * @param resourceRoot the resource root path + * @return the market data builder + */ + public static ExampleMarketDataBuilder ofResource(String resourceRoot) { + return ofResource(resourceRoot, ExampleMarketDataBuilder.class.getClassLoader()); } - ResourceLocator curveGroupsResource = getResource(CURVES_DIR, CURVES_GROUPS_FILE); - if (curveGroupsResource == null) { - log.error("Unable to load rates curves: curve groups file not found at {}/{}", CURVES_DIR, CURVES_GROUPS_FILE); - return; + /** + * Creates an instance from a given classpath resource root location, using the given class loader + * to find the resource. + *

+ * This is designed to handle resource roots which may physically correspond to a directory on + * disk, or be located within a jar file. + * + * @param resourceRoot the resource root path + * @param classLoader the class loader with which to find the resource + * @return the market data builder + */ + public static ExampleMarketDataBuilder ofResource(String resourceRoot, ClassLoader classLoader) { + // classpath resources are forward-slash separated + String qualifiedRoot = resourceRoot; + qualifiedRoot = qualifiedRoot.startsWith("/") ? qualifiedRoot.substring(1) : qualifiedRoot; + qualifiedRoot = qualifiedRoot.startsWith("\\") ? qualifiedRoot.substring(1) : qualifiedRoot; + qualifiedRoot = qualifiedRoot.endsWith("/") ? qualifiedRoot : qualifiedRoot + "/"; + URL url = classLoader.getResource(qualifiedRoot); + if (url == null) { + throw new IllegalArgumentException(Messages.format("Classpath resource not found: {}", qualifiedRoot)); + } + if (url.getProtocol() != null && "jar".equals(url.getProtocol().toLowerCase(Locale.ENGLISH))) { + // Inside a JAR + int classSeparatorIdx = url.getFile().indexOf("!"); + if (classSeparatorIdx == -1) { + throw new IllegalArgumentException(Messages.format("Unexpected JAR file URL: {}", url)); + } + String jarPath = url.getFile().substring("file:".length(), classSeparatorIdx); + File jarFile; + try { + jarFile = new File(jarPath); + } catch (Exception e) { + throw new IllegalArgumentException(Messages.format("Unable to create file for JAR: {}", jarPath), e); + } + return new JarMarketDataBuilder(jarFile, resourceRoot); + } else { + // Resource is on disk + File file; + try { + file = new File(url.toURI()); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(Messages.format("Unexpected file location: {}", url), e); + } + return new DirectoryMarketDataBuilder(file.toPath()); + } } - ResourceLocator curveSettingsResource = getResource(CURVES_DIR, CURVES_SETTINGS_FILE); - if (curveSettingsResource == null) { - log.error("Unable to load rates curves: curve settings file not found at {}/{}", CURVES_DIR, CURVES_SETTINGS_FILE); - return; - } - try { - Collection curvesResources = getRatesCurvesResources(); - List ratesCurves = - RatesCurvesCsvLoader.load(marketDataDate, curveGroupsResource, curveSettingsResource, curvesResources); - - for (CurveGroup group : ratesCurves) { - // add entry for higher level discount curve name - group.getDiscountCurves().forEach( - (ccy, curve) -> builder.addValue(CurveId.of(group.getName(), curve.getName()), curve)); - // add entry for higher level forward curve name - group.getForwardCurves().forEach( - (idx, curve) -> builder.addValue(CurveId.of(group.getName(), curve.getName()), curve)); - } - - } catch (Exception e) { - log.error("Error loading rates curves", e); - } - } - - // load quotes - private void loadQuotes(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) { - if (!subdirectoryExists(QUOTES_DIR)) { - log.debug("No quotes directory found"); - return; + /** + * Creates an instance from a given directory root. + * + * @param rootPath the root directory + * @return the market data builder + */ + public static ExampleMarketDataBuilder ofPath(Path rootPath) { + return new DirectoryMarketDataBuilder(rootPath); } - ResourceLocator quotesResource = getResource(QUOTES_DIR, QUOTES_FILE); - if (quotesResource == null) { - log.error("Unable to load quotes: quotes file not found at {}/{}", QUOTES_DIR, QUOTES_FILE); - return; + //------------------------------------------------------------------------- + + /** + * Builds a market data snapshot from this environment. + * + * @param marketDataDate the date of the market data + * @return the snapshot + */ + public ImmutableMarketData buildSnapshot(LocalDate marketDataDate) { + ImmutableMarketDataBuilder builder = ImmutableMarketData.builder(marketDataDate); + loadFixingSeries(builder); + loadRatesCurves(builder, marketDataDate); + loadQuotes(builder, marketDataDate); + loadFxRates(builder); + loadCreditMarketData(builder, marketDataDate); + return builder.build(); } - try { - Map quotes = QuotesCsvLoader.load(marketDataDate, quotesResource); - builder.addValueMap(quotes); - - } catch (Exception ex) { - log.error("Error loading quotes", ex); - } - } - - private void loadFxRates(ImmutableMarketDataBuilder builder) { - // TODO - load from CSV file - format to be defined - builder.addValue(FxRateId.of(Currency.GBP, Currency.USD), FxRate.of(Currency.GBP, Currency.USD, 1.61)); - } - - //------------------------------------------------------------------------- - private Collection getRatesCurvesResources() { - return getAllResources(CURVES_DIR).stream() - .filter(res -> !res.getLocator().endsWith(CURVES_GROUPS_FILE)) - .filter(res -> !res.getLocator().endsWith(CURVES_SETTINGS_FILE)) - .collect(toImmutableList()); - } - - private void loadCreditMarketData(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) { - if (!subdirectoryExists(CREDIT_DIR)) { - log.debug("No credit curves directory found"); - return; + /** + * Gets the rates market lookup to use with this environment. + * + * @param marketDataDate the date of the market data + * @return the rates lookup + */ + public RatesMarketDataLookup ratesLookup(LocalDate marketDataDate) { + SortedMap curves = loadAllRatesCurves(); + return RatesMarketDataLookup.of(curves.get(marketDataDate)); } - String creditMarketDataDateDirectory = String.format( - Locale.ENGLISH, - "%s/%s", - CREDIT_DIR, - marketDataDate.format(DateTimeFormatter.ISO_LOCAL_DATE)); + /** + * Gets all rates curves. + * + * @return the map of all rates curves + */ + public SortedMap loadAllRatesCurves() { + if (!subdirectoryExists(CURVES_DIR)) { + throw new IllegalArgumentException("No rates curves directory found"); + } + ResourceLocator curveGroupsResource = getResource(CURVES_DIR, CURVES_GROUPS_FILE); + if (curveGroupsResource == null) { + throw new IllegalArgumentException(Messages.format( + "Unable to load rates curves: curve groups file not found at {}/{}", CURVES_DIR, CURVES_GROUPS_FILE)); + } + ResourceLocator curveSettingsResource = getResource(CURVES_DIR, CURVES_SETTINGS_FILE); + if (curveSettingsResource == null) { + throw new IllegalArgumentException(Messages.format( + "Unable to load rates curves: curve settings file not found at {}/{}", CURVES_DIR, CURVES_SETTINGS_FILE)); + } + ListMultimap curveGroups = + RatesCurvesCsvLoader.loadAllDates(curveGroupsResource, curveSettingsResource, getRatesCurvesResources()); - if (!subdirectoryExists(creditMarketDataDateDirectory)) { - log.debug("Unable to load market data: directory not found at {}", creditMarketDataDateDirectory); - return; + // There is only one curve group in the market data file so this will always succeed + Map curveGroupMap = Maps.transformValues(curveGroups.asMap(), groups -> groups.iterator().next()); + return new TreeMap<>(curveGroupMap); } - loadCdsYieldCurves(builder, creditMarketDataDateDirectory); - loadCdsSingleNameSpreadCurves(builder, creditMarketDataDateDirectory); - loadCdsIndexSpreadCurves(builder, creditMarketDataDateDirectory); - } - - private void loadCdsYieldCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) { - ResourceLocator cdsYieldCurvesResource = getResource(creditMarketDataDateDirectory, CDS_YIELD_CURVES_FILE); - if (cdsYieldCurvesResource == null) { - log.debug("Unable to load cds yield curves: file not found at {}/{}", creditMarketDataDateDirectory, - CDS_YIELD_CURVES_FILE); - return; + //------------------------------------------------------------------------- + private void loadFixingSeries(ImmutableMarketDataBuilder builder) { + if (!subdirectoryExists(HISTORICAL_FIXINGS_DIR)) { + log.debug("No historical fixings directory found"); + return; + } + try { + Collection fixingSeriesResources = getAllResources(HISTORICAL_FIXINGS_DIR); + Map fixingSeries = FixingSeriesCsvLoader.load(fixingSeriesResources); + builder.addTimeSeriesMap(fixingSeries); + } catch (Exception e) { + log.error("Error loading fixing series", e); + } } - CharSource inputSource = cdsYieldCurvesResource.getCharSource(); - Map yieldCuves = MarkitYieldCurveDataParser.parse(inputSource); + private void loadRatesCurves(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) { + if (!subdirectoryExists(CURVES_DIR)) { + log.debug("No rates curves directory found"); + return; + } - for (IsdaYieldCurveInputsId id : yieldCuves.keySet()) { - IsdaYieldCurveInputs curveInputs = yieldCuves.get(id); - builder.addValue(id, curveInputs); - } - } + ResourceLocator curveGroupsResource = getResource(CURVES_DIR, CURVES_GROUPS_FILE); + if (curveGroupsResource == null) { + log.error("Unable to load rates curves: curve groups file not found at {}/{}", CURVES_DIR, CURVES_GROUPS_FILE); + return; + } - private void loadCdsSingleNameSpreadCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) { - ResourceLocator singleNameCurvesResource = getResource(creditMarketDataDateDirectory, SINGLE_NAME_CREDIT_CURVES_FILE); - if (singleNameCurvesResource == null) { - log.debug("Unable to load single name spread curves: file not found at {}/{}", creditMarketDataDateDirectory, - SINGLE_NAME_CREDIT_CURVES_FILE); - return; + ResourceLocator curveSettingsResource = getResource(CURVES_DIR, CURVES_SETTINGS_FILE); + if (curveSettingsResource == null) { + log.error("Unable to load rates curves: curve settings file not found at {}/{}", CURVES_DIR, CURVES_SETTINGS_FILE); + return; + } + try { + Collection curvesResources = getRatesCurvesResources(); + List ratesCurves = + RatesCurvesCsvLoader.load(marketDataDate, curveGroupsResource, curveSettingsResource, curvesResources); + + for (CurveGroup group : ratesCurves) { + // add entry for higher level discount curve name + group.getDiscountCurves().forEach( + (ccy, curve) -> builder.addValue(CurveId.of(group.getName(), curve.getName()), curve)); + // add entry for higher level forward curve name + group.getForwardCurves().forEach( + (idx, curve) -> builder.addValue(CurveId.of(group.getName(), curve.getName()), curve)); + } + + } catch (Exception e) { + log.error("Error loading rates curves", e); + } } - ResourceLocator singleNameStaticDataResource = getResource(creditMarketDataDateDirectory, SINGLE_NAME_STATIC_DATA_FILE); - if (singleNameStaticDataResource == null) { - log.debug("Unable to load single name static data: file not found at {}/{}", creditMarketDataDateDirectory, - SINGLE_NAME_STATIC_DATA_FILE); - return; + // load quotes + private void loadQuotes(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) { + if (!subdirectoryExists(QUOTES_DIR)) { + log.debug("No quotes directory found"); + return; + } + + ResourceLocator quotesResource = getResource(QUOTES_DIR, QUOTES_FILE); + if (quotesResource == null) { + log.error("Unable to load quotes: quotes file not found at {}/{}", QUOTES_DIR, QUOTES_FILE); + return; + } + + try { + Map quotes = QuotesCsvLoader.load(marketDataDate, quotesResource); + builder.addValueMap(quotes); + + } catch (Exception ex) { + log.error("Error loading quotes", ex); + } } - try { - CharSource inputCreditCurvesSource = singleNameCurvesResource.getCharSource(); - CharSource inputStaticDataSource = singleNameStaticDataResource.getCharSource(); - MarkitSingleNameCreditCurveDataParser.parse(builder, inputCreditCurvesSource, inputStaticDataSource); - } catch (Exception ex) { - throw new RuntimeException(String.format( - Locale.ENGLISH, - "Unable to read single name spread curves: exception at %s/%s", - creditMarketDataDateDirectory, SINGLE_NAME_CREDIT_CURVES_FILE), ex); - } - } - - private void loadCdsIndexSpreadCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) { - ResourceLocator inputCurvesResource = getResource(creditMarketDataDateDirectory, INDEX_CREDIT_CURVES_FILE); - if (inputCurvesResource == null) { - log.debug("Unable to load single name spread curves: file not found at {}/{}", creditMarketDataDateDirectory, - INDEX_CREDIT_CURVES_FILE); - return; + private void loadFxRates(ImmutableMarketDataBuilder builder) { + // TODO - load from CSV file - format to be defined + builder.addValue(FxRateId.of(Currency.GBP, Currency.USD), FxRate.of(Currency.GBP, Currency.USD, 1.61)); } - ResourceLocator inputStaticDataResource = getResource(creditMarketDataDateDirectory, INDEX_STATIC_DATA_FILE); - if (inputStaticDataResource == null) { - log.debug("Unable to load index static data: file not found at {}/{}", creditMarketDataDateDirectory, - INDEX_STATIC_DATA_FILE); - return; + //------------------------------------------------------------------------- + private Collection getRatesCurvesResources() { + return getAllResources(CURVES_DIR).stream() + .filter(res -> !res.getLocator().endsWith(CURVES_GROUPS_FILE)) + .filter(res -> !res.getLocator().endsWith(CURVES_SETTINGS_FILE)) + .collect(toImmutableList()); } - CharSource indexCreditCurvesSource = inputCurvesResource.getCharSource(); - CharSource indexStaticDataSource = inputStaticDataResource.getCharSource(); - MarkitIndexCreditCurveDataParser.parse(builder, indexCreditCurvesSource, indexStaticDataSource); + private void loadCreditMarketData(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) { + if (!subdirectoryExists(CREDIT_DIR)) { + log.debug("No credit curves directory found"); + return; + } - } + String creditMarketDataDateDirectory = String.format( + Locale.ENGLISH, + "%s/%s", + CREDIT_DIR, + marketDataDate.format(DateTimeFormatter.ISO_LOCAL_DATE)); - //------------------------------------------------------------------------- - /** - * Gets all available resources from a given subdirectory. - * - * @param subdirectoryName the name of the subdirectory - * @return a collection of locators for the resources in the subdirectory - */ - protected abstract Collection getAllResources(String subdirectoryName); + if (!subdirectoryExists(creditMarketDataDateDirectory)) { + log.debug("Unable to load market data: directory not found at {}", creditMarketDataDateDirectory); + return; + } - /** - * Gets a specific resource from a given subdirectory. - * - * @param subdirectoryName the name of the subdirectory - * @param resourceName the name of the resource - * @return a locator for the requested resource - */ - protected abstract ResourceLocator getResource(String subdirectoryName, String resourceName); + loadCdsYieldCurves(builder, creditMarketDataDateDirectory); + loadCdsSingleNameSpreadCurves(builder, creditMarketDataDateDirectory); + loadCdsIndexSpreadCurves(builder, creditMarketDataDateDirectory); + } - /** - * Checks whether a specific subdirectory exists. - * - * @param subdirectoryName the name of the subdirectory - * @return whether the subdirectory exists - */ - protected abstract boolean subdirectoryExists(String subdirectoryName); + private void loadCdsYieldCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) { + ResourceLocator cdsYieldCurvesResource = getResource(creditMarketDataDateDirectory, CDS_YIELD_CURVES_FILE); + if (cdsYieldCurvesResource == null) { + log.debug("Unable to load cds yield curves: file not found at {}/{}", creditMarketDataDateDirectory, + CDS_YIELD_CURVES_FILE); + return; + } + + CharSource inputSource = cdsYieldCurvesResource.getCharSource(); + Map yieldCuves = MarkitYieldCurveDataParser.parse(inputSource); + + for (IsdaYieldCurveInputsId id : yieldCuves.keySet()) { + IsdaYieldCurveInputs curveInputs = yieldCuves.get(id); + builder.addValue(id, curveInputs); + } + } + + private void loadCdsSingleNameSpreadCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) { + ResourceLocator singleNameCurvesResource = getResource(creditMarketDataDateDirectory, SINGLE_NAME_CREDIT_CURVES_FILE); + if (singleNameCurvesResource == null) { + log.debug("Unable to load single name spread curves: file not found at {}/{}", creditMarketDataDateDirectory, + SINGLE_NAME_CREDIT_CURVES_FILE); + return; + } + + ResourceLocator singleNameStaticDataResource = getResource(creditMarketDataDateDirectory, SINGLE_NAME_STATIC_DATA_FILE); + if (singleNameStaticDataResource == null) { + log.debug("Unable to load single name static data: file not found at {}/{}", creditMarketDataDateDirectory, + SINGLE_NAME_STATIC_DATA_FILE); + return; + } + + try { + CharSource inputCreditCurvesSource = singleNameCurvesResource.getCharSource(); + CharSource inputStaticDataSource = singleNameStaticDataResource.getCharSource(); + MarkitSingleNameCreditCurveDataParser.parse(builder, inputCreditCurvesSource, inputStaticDataSource); + } catch (Exception ex) { + throw new RuntimeException(String.format( + Locale.ENGLISH, + "Unable to read single name spread curves: exception at %s/%s", + creditMarketDataDateDirectory, SINGLE_NAME_CREDIT_CURVES_FILE), ex); + } + } + + private void loadCdsIndexSpreadCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) { + ResourceLocator inputCurvesResource = getResource(creditMarketDataDateDirectory, INDEX_CREDIT_CURVES_FILE); + if (inputCurvesResource == null) { + log.debug("Unable to load single name spread curves: file not found at {}/{}", creditMarketDataDateDirectory, + INDEX_CREDIT_CURVES_FILE); + return; + } + + ResourceLocator inputStaticDataResource = getResource(creditMarketDataDateDirectory, INDEX_STATIC_DATA_FILE); + if (inputStaticDataResource == null) { + log.debug("Unable to load index static data: file not found at {}/{}", creditMarketDataDateDirectory, + INDEX_STATIC_DATA_FILE); + return; + } + + CharSource indexCreditCurvesSource = inputCurvesResource.getCharSource(); + CharSource indexStaticDataSource = inputStaticDataResource.getCharSource(); + MarkitIndexCreditCurveDataParser.parse(builder, indexCreditCurvesSource, indexStaticDataSource); + + } + + //------------------------------------------------------------------------- + + /** + * Gets all available resources from a given subdirectory. + * + * @param subdirectoryName the name of the subdirectory + * @return a collection of locators for the resources in the subdirectory + */ + protected abstract Collection getAllResources(String subdirectoryName); + + /** + * Gets a specific resource from a given subdirectory. + * + * @param subdirectoryName the name of the subdirectory + * @param resourceName the name of the resource + * @return a locator for the requested resource + */ + protected abstract ResourceLocator getResource(String subdirectoryName, String resourceName); + + /** + * Checks whether a specific subdirectory exists. + * + * @param subdirectoryName the name of the subdirectory + * @return whether the subdirectory exists + */ + protected abstract boolean subdirectoryExists(String subdirectoryName); } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/JarMarketDataBuilder.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/JarMarketDataBuilder.java index cc599609da..34ed9064e4 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/JarMarketDataBuilder.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/JarMarketDataBuilder.java @@ -1,6 +1,6 @@ /** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. */ package com.opengamma.strata.examples.marketdata; @@ -22,96 +22,96 @@ import java.util.stream.Collectors; */ public class JarMarketDataBuilder extends ExampleMarketDataBuilder { - /** - * The JAR file containing the expected structure of resources. - */ - private final File jarFile; - /** - * The root path to the resources within the JAR file. - */ - private final String rootPath; - /** - * A cache of JAR entries under the root path. - */ - private final ImmutableSet entries; + /** + * The JAR file containing the expected structure of resources. + */ + private final File jarFile; + /** + * The root path to the resources within the JAR file. + */ + private final String rootPath; + /** + * A cache of JAR entries under the root path. + */ + private final ImmutableSet entries; - /** - * Constructs an instance. - * - * @param jarFile the JAR file containing the expected structure of resources - * @param rootPath the root path to the resources within the JAR file - */ - public JarMarketDataBuilder(File jarFile, String rootPath) { - // classpath resources are forward-slash separated - String jarRoot = rootPath.startsWith("/") ? rootPath.substring(1) : rootPath; - if (!jarRoot.endsWith("/")) { - jarRoot += "/"; - } - this.jarFile = jarFile; - this.rootPath = jarRoot; - this.entries = getEntries(jarFile, rootPath); - } - - //------------------------------------------------------------------------- - @Override - protected Collection getAllResources(String subdirectoryName) { - String resolvedSubdirectory = subdirectoryName + "/"; - return entries.stream() - .filter(e -> e.startsWith(resolvedSubdirectory) && !e.equals(resolvedSubdirectory)) - .map(e -> getEntryLocator(rootPath + e)) - .collect(Collectors.toSet()); - } - - @Override - protected ResourceLocator getResource(String subdirectoryName, String resourceName) { - String fullLocation = String.format(Locale.ENGLISH, "%s%s/%s", rootPath, subdirectoryName, resourceName); - try (JarFile jar = new JarFile(jarFile)) { - JarEntry entry = jar.getJarEntry(fullLocation); - if (entry == null) { - return null; - } - return getEntryLocator(entry.getName()); - } catch (Exception e) { - throw new IllegalArgumentException( - Messages.format("Error loading resource from JAR file: {}", jarFile), e); - } - } - - @Override - protected boolean subdirectoryExists(String subdirectoryName) { - // classpath resources are forward-slash separated - String resolvedName = subdirectoryName.startsWith("/") ? subdirectoryName.substring(1) : subdirectoryName; - if (!resolvedName.endsWith("/")) { - resolvedName += "/"; - } - return entries.contains(resolvedName); - } - - //------------------------------------------------------------------------- - // Gets the resource locator corresponding to a given entry - private ResourceLocator getEntryLocator(String entryName) { - return ResourceLocator.of(ResourceLocator.CLASSPATH_URL_PREFIX + entryName); - } - - private static ImmutableSet getEntries(File jarFile, String rootPath) { - ImmutableSet.Builder builder = ImmutableSet.builder(); - try (JarFile jar = new JarFile(jarFile)) { - Enumeration jarEntries = jar.entries(); - while (jarEntries.hasMoreElements()) { - JarEntry entry = jarEntries.nextElement(); - String entryName = entry.getName(); - if (entryName.startsWith(rootPath) && !entryName.equals(rootPath)) { - String relativeEntryPath = entryName.substring(rootPath.length() + 1); - if (!relativeEntryPath.trim().isEmpty()) { - builder.add(relativeEntryPath); - } + /** + * Constructs an instance. + * + * @param jarFile the JAR file containing the expected structure of resources + * @param rootPath the root path to the resources within the JAR file + */ + public JarMarketDataBuilder(File jarFile, String rootPath) { + // classpath resources are forward-slash separated + String jarRoot = rootPath.startsWith("/") ? rootPath.substring(1) : rootPath; + if (!jarRoot.endsWith("/")) { + jarRoot += "/"; } - } - } catch (Exception e) { - throw new IllegalArgumentException( - Messages.format("Error scanning entries in JAR file: {}", jarFile), e); + this.jarFile = jarFile; + this.rootPath = jarRoot; + this.entries = getEntries(jarFile, rootPath); + } + + //------------------------------------------------------------------------- + @Override + protected Collection getAllResources(String subdirectoryName) { + String resolvedSubdirectory = subdirectoryName + "/"; + return entries.stream() + .filter(e -> e.startsWith(resolvedSubdirectory) && !e.equals(resolvedSubdirectory)) + .map(e -> getEntryLocator(rootPath + e)) + .collect(Collectors.toSet()); + } + + @Override + protected ResourceLocator getResource(String subdirectoryName, String resourceName) { + String fullLocation = String.format(Locale.ENGLISH, "%s%s/%s", rootPath, subdirectoryName, resourceName); + try (JarFile jar = new JarFile(jarFile)) { + JarEntry entry = jar.getJarEntry(fullLocation); + if (entry == null) { + return null; + } + return getEntryLocator(entry.getName()); + } catch (Exception e) { + throw new IllegalArgumentException( + Messages.format("Error loading resource from JAR file: {}", jarFile), e); + } + } + + @Override + protected boolean subdirectoryExists(String subdirectoryName) { + // classpath resources are forward-slash separated + String resolvedName = subdirectoryName.startsWith("/") ? subdirectoryName.substring(1) : subdirectoryName; + if (!resolvedName.endsWith("/")) { + resolvedName += "/"; + } + return entries.contains(resolvedName); + } + + //------------------------------------------------------------------------- + // Gets the resource locator corresponding to a given entry + private ResourceLocator getEntryLocator(String entryName) { + return ResourceLocator.of(ResourceLocator.CLASSPATH_URL_PREFIX + entryName); + } + + private static ImmutableSet getEntries(File jarFile, String rootPath) { + ImmutableSet.Builder builder = ImmutableSet.builder(); + try (JarFile jar = new JarFile(jarFile)) { + Enumeration jarEntries = jar.entries(); + while (jarEntries.hasMoreElements()) { + JarEntry entry = jarEntries.nextElement(); + String entryName = entry.getName(); + if (entryName.startsWith(rootPath) && !entryName.equals(rootPath)) { + String relativeEntryPath = entryName.substring(rootPath.length() + 1); + if (!relativeEntryPath.trim().isEmpty()) { + builder.add(relativeEntryPath); + } + } + } + } catch (Exception e) { + throw new IllegalArgumentException( + Messages.format("Error scanning entries in JAR file: {}", jarFile), e); + } + return builder.build(); } - return builder.build(); - } } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitIndexCreditCurveDataParser.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitIndexCreditCurveDataParser.java index 7b3bdd8c86..9f220e2e58 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitIndexCreditCurveDataParser.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitIndexCreditCurveDataParser.java @@ -1,6 +1,6 @@ /** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. */ package com.opengamma.strata.examples.marketdata.credit.markit; @@ -44,217 +44,219 @@ import java.util.Map; */ public class MarkitIndexCreditCurveDataParser { - // Markit date format with the month in full caps. e.g. 11-JUL-14 - private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder() - .parseCaseInsensitive().appendPattern("dd-MMM-uu").toFormatter(Locale.ENGLISH); + // Markit date format with the month in full caps. e.g. 11-JUL-14 + private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder() + .parseCaseInsensitive().appendPattern("dd-MMM-uu").toFormatter(Locale.ENGLISH); - enum Columns { + enum Columns { - Series("Series"), - Version("Version"), - Term("Term"), - RedCode("RED Code"), - Maturity("Maturity"), - CompositeSpread("Composite Spread"), - ModelSpread("Model Spread"); + Series("Series"), + Version("Version"), + Term("Term"), + RedCode("RED Code"), + Maturity("Maturity"), + CompositeSpread("Composite Spread"), + ModelSpread("Model Spread"); - private final String columnName; + private final String columnName; - Columns(String columnName) { - this.columnName = columnName; - } - - public String getColumnName() { - return columnName; - } - } - - /** - * Parses the specified sources. - * - * @param builder the market data builder that the resulting curve and recovery rate items should be loaded into - * @param curveSource the source of curve data to parse - * @param staticDataSource the source of static data to parse - */ - public static void parse( - ImmutableMarketDataBuilder builder, - CharSource curveSource, - CharSource staticDataSource) { - - Map> curveData = Maps.newHashMap(); - Map staticDataMap = parseStaticData(staticDataSource); - - CsvFile csv = CsvFile.of(curveSource, true); - for (CsvRow row : csv.rows()) { - String seriesText = row.getField(Columns.Series.getColumnName()); - String versionText = row.getField(Columns.Version.getColumnName()); - String termText = row.getField(Columns.Term.getColumnName()); - String redCodeText = row.getField(Columns.RedCode.getColumnName()); - String maturityText = row.getField(Columns.Maturity.getColumnName()); - String compositeSpreadText = row.getField(Columns.CompositeSpread.getColumnName()); - String modelSpreadText = row.getField(Columns.ModelSpread.getColumnName()); - - StandardId indexId = MarkitRedCode.id(redCodeText); - int indexSeries = Integer.parseInt(seriesText); - int indexAnnexVersion = Integer.parseInt(versionText); - - IsdaIndexCreditCurveInputsId id = IsdaIndexCreditCurveInputsId.of( - IndexReferenceInformation.of( - indexId, - indexSeries, - indexAnnexVersion)); - - Tenor term = Tenor.parse(termText); - LocalDate maturity = LocalDate.parse(maturityText, DATE_FORMAT); - - double spread; - if (compositeSpreadText.isEmpty()) { - if (modelSpreadText.isEmpty()) { - // there is no rate for this row, continue - continue; + Columns(String columnName) { + this.columnName = columnName; } - // fall back to the model rate is the composite is missing - spread = parseRate(modelSpreadText); - } else { - // prefer the composite rate if it is present - spread = parseRate(compositeSpreadText); - } - List points = curveData.get(id); - if (points == null) { - points = Lists.newArrayList(); - curveData.put(id, points); - } - points.add(new Point(term, maturity, spread)); + public String getColumnName() { + return columnName; + } } - for (IsdaIndexCreditCurveInputsId curveId : curveData.keySet()) { - MarkitRedCode redCode = MarkitRedCode.from(curveId.getReferenceInformation().getIndexId()); - StaticData staticData = staticDataMap.get(redCode); - ArgChecker.notNull(staticData, "Did not find a static data record for " + redCode); - CdsConvention convention = staticData.getConvention(); - double recoveryRate = staticData.getRecoveryRate(); - double indexFactor = staticData.getIndexFactor(); - // TODO add fromDate handling + /** + * Parses the specified sources. + * + * @param builder the market data builder that the resulting curve and recovery rate items should be loaded into + * @param curveSource the source of curve data to parse + * @param staticDataSource the source of static data to parse + */ + public static void parse( + ImmutableMarketDataBuilder builder, + CharSource curveSource, + CharSource staticDataSource) { - String creditCurveName = curveId.toString(); + Map> curveData = Maps.newHashMap(); + Map staticDataMap = parseStaticData(staticDataSource); - List points = curveData.get(curveId); + CsvFile csv = CsvFile.of(curveSource, true); + for (CsvRow row : csv.rows()) { + String seriesText = row.getField(Columns.Series.getColumnName()); + String versionText = row.getField(Columns.Version.getColumnName()); + String termText = row.getField(Columns.Term.getColumnName()); + String redCodeText = row.getField(Columns.RedCode.getColumnName()); + String maturityText = row.getField(Columns.Maturity.getColumnName()); + String compositeSpreadText = row.getField(Columns.CompositeSpread.getColumnName()); + String modelSpreadText = row.getField(Columns.ModelSpread.getColumnName()); - Period[] periods = points.stream().map(s -> s.getTenor().getPeriod()).toArray(Period[]::new); - LocalDate[] endDates = points.stream().map(s -> s.getDate()).toArray(LocalDate[]::new); - double[] rates = points.stream().mapToDouble(s -> s.getRate()).toArray(); + StandardId indexId = MarkitRedCode.id(redCodeText); + int indexSeries = Integer.parseInt(seriesText); + int indexAnnexVersion = Integer.parseInt(versionText); - IsdaCreditCurveInputs curveInputs = IsdaCreditCurveInputs.of( - CurveName.of(creditCurveName), - periods, - endDates, - rates, - convention, - indexFactor); + IsdaIndexCreditCurveInputsId id = IsdaIndexCreditCurveInputsId.of( + IndexReferenceInformation.of( + indexId, + indexSeries, + indexAnnexVersion)); - builder.addValue(curveId, curveInputs); + Tenor term = Tenor.parse(termText); + LocalDate maturity = LocalDate.parse(maturityText, DATE_FORMAT); - IsdaIndexRecoveryRateId recoveryRateId = IsdaIndexRecoveryRateId.of(curveId.getReferenceInformation()); - CdsRecoveryRate cdsRecoveryRate = CdsRecoveryRate.of(recoveryRate); + double spread; + if (compositeSpreadText.isEmpty()) { + if (modelSpreadText.isEmpty()) { + // there is no rate for this row, continue + continue; + } + // fall back to the model rate is the composite is missing + spread = parseRate(modelSpreadText); + } else { + // prefer the composite rate if it is present + spread = parseRate(compositeSpreadText); + } - builder.addValue(recoveryRateId, cdsRecoveryRate); - } - } + List points = curveData.get(id); + if (points == null) { + points = Lists.newArrayList(); + curveData.put(id, points); + } + points.add(new Point(term, maturity, spread)); + } - // parses the static data file - private static Map parseStaticData(CharSource source) { - CsvFile csv = CsvFile.of(source, true); + for (IsdaIndexCreditCurveInputsId curveId : curveData.keySet()) { + MarkitRedCode redCode = MarkitRedCode.from(curveId.getReferenceInformation().getIndexId()); + StaticData staticData = staticDataMap.get(redCode); + ArgChecker.notNull(staticData, "Did not find a static data record for " + redCode); + CdsConvention convention = staticData.getConvention(); + double recoveryRate = staticData.getRecoveryRate(); + double indexFactor = staticData.getIndexFactor(); + // TODO add fromDate handling - Map result = Maps.newHashMap(); - for (CsvRow row : csv.rows()) { - String redCodeText = row.getField("RedCode"); - String fromDateText = row.getField("From Date"); - String conventionText = row.getField("Convention"); - String recoveryRateText = row.getField("Recovery Rate"); - String indexFactorText = row.getField("Index Factor"); + String creditCurveName = curveId.toString(); - MarkitRedCode redCode = MarkitRedCode.of(redCodeText); - LocalDate fromDate = LocalDate.parse(fromDateText, DATE_FORMAT); - CdsConvention convention = CdsConvention.of(conventionText); - double recoveryRate = parseRate(recoveryRateText); - double indexFactor = Double.parseDouble(indexFactorText); + List points = curveData.get(curveId); - result.put(redCode, new StaticData(fromDate, convention, recoveryRate, indexFactor)); - } - return result; - } + Period[] periods = points.stream().map(s -> s.getTenor().getPeriod()).toArray(Period[]::new); + LocalDate[] endDates = points.stream().map(s -> s.getDate()).toArray(LocalDate[]::new); + double[] rates = points.stream().mapToDouble(s -> s.getRate()).toArray(); - //------------------------------------------------------------------------- - /** - * Stores the parsed static data. - */ - private static class StaticData { + IsdaCreditCurveInputs curveInputs = IsdaCreditCurveInputs.of( + CurveName.of(creditCurveName), + periods, + endDates, + rates, + convention, + indexFactor); - private LocalDate fromDate; - private CdsConvention convention; - private double recoveryRate; - private double indexFactor; + builder.addValue(curveId, curveInputs); - private StaticData(LocalDate fromDate, CdsConvention convention, double recoveryRate, double indexFactor) { - this.fromDate = fromDate; - this.convention = convention; - this.recoveryRate = recoveryRate; - this.indexFactor = indexFactor; + IsdaIndexRecoveryRateId recoveryRateId = IsdaIndexRecoveryRateId.of(curveId.getReferenceInformation()); + CdsRecoveryRate cdsRecoveryRate = CdsRecoveryRate.of(recoveryRate); + + builder.addValue(recoveryRateId, cdsRecoveryRate); + } } - @SuppressWarnings("unused") - public LocalDate getFromDate() { - return fromDate; + // parses the static data file + private static Map parseStaticData(CharSource source) { + CsvFile csv = CsvFile.of(source, true); + + Map result = Maps.newHashMap(); + for (CsvRow row : csv.rows()) { + String redCodeText = row.getField("RedCode"); + String fromDateText = row.getField("From Date"); + String conventionText = row.getField("Convention"); + String recoveryRateText = row.getField("Recovery Rate"); + String indexFactorText = row.getField("Index Factor"); + + MarkitRedCode redCode = MarkitRedCode.of(redCodeText); + LocalDate fromDate = LocalDate.parse(fromDateText, DATE_FORMAT); + CdsConvention convention = CdsConvention.of(conventionText); + double recoveryRate = parseRate(recoveryRateText); + double indexFactor = Double.parseDouble(indexFactorText); + + result.put(redCode, new StaticData(fromDate, convention, recoveryRate, indexFactor)); + } + return result; } - public CdsConvention getConvention() { - return convention; + //------------------------------------------------------------------------- + + /** + * Stores the parsed static data. + */ + private static class StaticData { + + private LocalDate fromDate; + private CdsConvention convention; + private double recoveryRate; + private double indexFactor; + + private StaticData(LocalDate fromDate, CdsConvention convention, double recoveryRate, double indexFactor) { + this.fromDate = fromDate; + this.convention = convention; + this.recoveryRate = recoveryRate; + this.indexFactor = indexFactor; + } + + @SuppressWarnings("unused") + public LocalDate getFromDate() { + return fromDate; + } + + public CdsConvention getConvention() { + return convention; + } + + public double getRecoveryRate() { + return recoveryRate; + } + + public double getIndexFactor() { + return indexFactor; + } } - public double getRecoveryRate() { - return recoveryRate; + //------------------------------------------------------------------------- + + /** + * Stores the parsed data points. + */ + private static class Point { + private final Tenor tenor; + + private final LocalDate date; + + private final double rate; + + private Point(Tenor tenor, LocalDate date, double rate) { + this.tenor = tenor; + this.date = date; + this.rate = rate; + } + + public Tenor getTenor() { + return tenor; + } + + public LocalDate getDate() { + return date; + } + + public double getRate() { + return rate; + } } - public double getIndexFactor() { - return indexFactor; + // Converts from a string percentage rate with a percent sign to a double rate + // e.g. 0.12% => 0.0012d + private static double parseRate(String input) { + return Double.parseDouble(input.replace("%", "")) / 100d; } - } - - //------------------------------------------------------------------------- - /** - * Stores the parsed data points. - */ - private static class Point { - private final Tenor tenor; - - private final LocalDate date; - - private final double rate; - - private Point(Tenor tenor, LocalDate date, double rate) { - this.tenor = tenor; - this.date = date; - this.rate = rate; - } - - public Tenor getTenor() { - return tenor; - } - - public LocalDate getDate() { - return date; - } - - public double getRate() { - return rate; - } - } - - // Converts from a string percentage rate with a percent sign to a double rate - // e.g. 0.12% => 0.0012d - private static double parseRate(String input) { - return Double.parseDouble(input.replace("%", "")) / 100d; - } } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitRedCode.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitRedCode.java index bae17190a3..0581a6c772 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitRedCode.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitRedCode.java @@ -1,6 +1,6 @@ /** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. */ package com.opengamma.strata.examples.marketdata.credit.markit; @@ -19,72 +19,74 @@ import org.joda.convert.FromString; * http://www.markit.com/product/reference-data-cds */ public final class MarkitRedCode - extends TypedString { + extends TypedString { - /** - * Serialization version. - */ - private static final long serialVersionUID = 1L; + /** + * Serialization version. + */ + private static final long serialVersionUID = 1L; - /** - * Scheme used in an OpenGamma {@link StandardId} where the value is a Markit RED code. - */ - public static final String MARKIT_REDCODE_SCHEME = "MarkitRedCode"; + /** + * Scheme used in an OpenGamma {@link StandardId} where the value is a Markit RED code. + */ + public static final String MARKIT_REDCODE_SCHEME = "MarkitRedCode"; - //------------------------------------------------------------------------- - /** - * Obtains an instance from the specified name. - *

- * RED codes must be 6 or 9 characters long. - * - * @param name the name of the field - * @return a RED code - */ - @FromString - public static MarkitRedCode of(String name) { - ArgChecker.isTrue(name.length() == 6 || name.length() == 9, "RED Code must be exactly 6 or 9 characters"); - return new MarkitRedCode(name); - } + //------------------------------------------------------------------------- - /** - * Converts from a standard identifier ensuring the scheme is correct. - * - * @param id standard id identifying a RED code - * @return the equivalent RED code - */ - public static MarkitRedCode from(StandardId id) { - Preconditions.checkArgument(id.getScheme().equals(MARKIT_REDCODE_SCHEME)); - return MarkitRedCode.of(id.getValue()); - } + /** + * Obtains an instance from the specified name. + *

+ * RED codes must be 6 or 9 characters long. + * + * @param name the name of the field + * @return a RED code + */ + @FromString + public static MarkitRedCode of(String name) { + ArgChecker.isTrue(name.length() == 6 || name.length() == 9, "RED Code must be exactly 6 or 9 characters"); + return new MarkitRedCode(name); + } - /** - * Creates a standard identifier using the correct Markit RED code scheme. - * - * @param name the Markit RED code, 6 or 9 characters long - * @return the equivalent standard identifier - */ - public static StandardId id(String name) { - ArgChecker.isTrue(name.length() == 6 || name.length() == 9, "RED Code must be exactly 6 or 9 characters"); - return StandardId.of(MARKIT_REDCODE_SCHEME, name); - } + /** + * Converts from a standard identifier ensuring the scheme is correct. + * + * @param id standard id identifying a RED code + * @return the equivalent RED code + */ + public static MarkitRedCode from(StandardId id) { + Preconditions.checkArgument(id.getScheme().equals(MARKIT_REDCODE_SCHEME)); + return MarkitRedCode.of(id.getValue()); + } - /** - * Creates an instance. - * - * @param name the RED code - */ - private MarkitRedCode(String name) { - super(name); - } + /** + * Creates a standard identifier using the correct Markit RED code scheme. + * + * @param name the Markit RED code, 6 or 9 characters long + * @return the equivalent standard identifier + */ + public static StandardId id(String name) { + ArgChecker.isTrue(name.length() == 6 || name.length() == 9, "RED Code must be exactly 6 or 9 characters"); + return StandardId.of(MARKIT_REDCODE_SCHEME, name); + } - //------------------------------------------------------------------------- - /** - * Converts this RED code to a standard identifier. - * - * @return the standard identifier - */ - public StandardId toStandardId() { - return StandardId.of(MARKIT_REDCODE_SCHEME, getName()); - } + /** + * Creates an instance. + * + * @param name the RED code + */ + private MarkitRedCode(String name) { + super(name); + } + + //------------------------------------------------------------------------- + + /** + * Converts this RED code to a standard identifier. + * + * @return the standard identifier + */ + public StandardId toStandardId() { + return StandardId.of(MARKIT_REDCODE_SCHEME, getName()); + } } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitRestructuringClause.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitRestructuringClause.java index 35e87365a6..be4cdd1b16 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitRestructuringClause.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitRestructuringClause.java @@ -1,6 +1,6 @@ /** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. */ package com.opengamma.strata.examples.marketdata.credit.markit; @@ -14,96 +14,97 @@ import com.opengamma.strata.product.credit.RestructuringClause; */ public enum MarkitRestructuringClause { - /** - * Modified-Modified Restructuring 2003. - */ - MM, - /** - * Modified-Modified Restructuring 2014. - */ - MM14, - /** - * Modified Restructuring 2003. - */ - MR, - /** - * Modified Restructuring 2014. - */ - MR14, - /** - * Cum/Old/Full Restructuring 2003. - */ - CR, - /** - * Cum/Old/Full Restructuring 2014. - */ - CR14, - /** - * Ex/No restructuring 2003. - */ - XR, - /** - * Ex/No restructuring 2014. - */ - XR14; + /** + * Modified-Modified Restructuring 2003. + */ + MM, + /** + * Modified-Modified Restructuring 2014. + */ + MM14, + /** + * Modified Restructuring 2003. + */ + MR, + /** + * Modified Restructuring 2014. + */ + MR14, + /** + * Cum/Old/Full Restructuring 2003. + */ + CR, + /** + * Cum/Old/Full Restructuring 2014. + */ + CR14, + /** + * Ex/No restructuring 2003. + */ + XR, + /** + * Ex/No restructuring 2014. + */ + XR14; - //------------------------------------------------------------------------- - /** - * Converts Markit code to standard restructuring clause. - * - * @return the converted clause - */ - public RestructuringClause translate() { - switch (this) { - case MM: - return RestructuringClause.MOD_MOD_RESTRUCTURING_2003; - case MM14: - return RestructuringClause.MOD_MOD_RESTRUCTURING_2014; - case MR: - return RestructuringClause.MODIFIED_RESTRUCTURING_2003; - case MR14: - return RestructuringClause.MODIFIED_RESTRUCTURING_2014; - case CR: - return RestructuringClause.CUM_RESTRUCTURING_2003; - case CR14: - return RestructuringClause.CUM_RESTRUCTURING_2014; - case XR: - return RestructuringClause.NO_RESTRUCTURING_2003; - case XR14: - return RestructuringClause.NO_RESTRUCTURING_2014; - default: - throw new IllegalStateException("Unmapped restructuring clause. Do not have mapping for " + this); + //------------------------------------------------------------------------- + + /** + * Converts Markit code to standard restructuring clause. + * + * @return the converted clause + */ + public RestructuringClause translate() { + switch (this) { + case MM: + return RestructuringClause.MOD_MOD_RESTRUCTURING_2003; + case MM14: + return RestructuringClause.MOD_MOD_RESTRUCTURING_2014; + case MR: + return RestructuringClause.MODIFIED_RESTRUCTURING_2003; + case MR14: + return RestructuringClause.MODIFIED_RESTRUCTURING_2014; + case CR: + return RestructuringClause.CUM_RESTRUCTURING_2003; + case CR14: + return RestructuringClause.CUM_RESTRUCTURING_2014; + case XR: + return RestructuringClause.NO_RESTRUCTURING_2003; + case XR14: + return RestructuringClause.NO_RESTRUCTURING_2014; + default: + throw new IllegalStateException("Unmapped restructuring clause. Do not have mapping for " + this); + } } - } - /** - * Converts restructuring clause to Markit equivalent. - * - * @param restructuringClause the clause to convert - * @return the converted clause - */ - public static MarkitRestructuringClause from(RestructuringClause restructuringClause) { - switch (restructuringClause) { - case MOD_MOD_RESTRUCTURING_2003: - return MM; - case MOD_MOD_RESTRUCTURING_2014: - return MM14; - case MODIFIED_RESTRUCTURING_2003: - return MR; - case MODIFIED_RESTRUCTURING_2014: - return MR14; - case CUM_RESTRUCTURING_2003: - return CR; - case CUM_RESTRUCTURING_2014: - return CR14; - case NO_RESTRUCTURING_2003: - return XR; - case NO_RESTRUCTURING_2014: - return XR14; - default: - throw new UnsupportedOperationException("Unknown restructuring clause. Do not have mapping for " + restructuringClause); + /** + * Converts restructuring clause to Markit equivalent. + * + * @param restructuringClause the clause to convert + * @return the converted clause + */ + public static MarkitRestructuringClause from(RestructuringClause restructuringClause) { + switch (restructuringClause) { + case MOD_MOD_RESTRUCTURING_2003: + return MM; + case MOD_MOD_RESTRUCTURING_2014: + return MM14; + case MODIFIED_RESTRUCTURING_2003: + return MR; + case MODIFIED_RESTRUCTURING_2014: + return MR14; + case CUM_RESTRUCTURING_2003: + return CR; + case CUM_RESTRUCTURING_2014: + return CR14; + case NO_RESTRUCTURING_2003: + return XR; + case NO_RESTRUCTURING_2014: + return XR14; + default: + throw new UnsupportedOperationException("Unknown restructuring clause. Do not have mapping for " + restructuringClause); + } } - } } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitSeniorityLevel.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitSeniorityLevel.java index 53829372d4..8aca3087d0 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitSeniorityLevel.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitSeniorityLevel.java @@ -1,6 +1,6 @@ /** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. */ package com.opengamma.strata.examples.marketdata.credit.markit; @@ -14,75 +14,76 @@ import com.opengamma.strata.product.credit.SeniorityLevel; */ public enum MarkitSeniorityLevel { - /** - * Senior domestic. - */ - SECDOM, + /** + * Senior domestic. + */ + SECDOM, - /** - * Senior foreign. - */ - SNRFOR, + /** + * Senior foreign. + */ + SNRFOR, - /** - * Subordinate, Lower Tier 2. - */ - SUBLT2, + /** + * Subordinate, Lower Tier 2. + */ + SUBLT2, - /** - * Subordinate Tier 1. - */ - PREFT1, + /** + * Subordinate Tier 1. + */ + PREFT1, - /** - * Subordinate, Upper Tier 2. - */ - JRSUBUT2; + /** + * Subordinate, Upper Tier 2. + */ + JRSUBUT2; - //------------------------------------------------------------------------- - /** - * Converts Markit code to standard seniority level. - * - * @return the converted level - */ - public SeniorityLevel translate() { - switch (this) { - case SECDOM: - return SeniorityLevel.SENIOR_SECURED_DOMESTIC; - case SNRFOR: - return SeniorityLevel.SENIOR_UNSECURED_FOREIGN; - case SUBLT2: - return SeniorityLevel.SUBORDINATE_LOWER_TIER_2; - case PREFT1: - return SeniorityLevel.SUBORDINATE_TIER_1; - case JRSUBUT2: - return SeniorityLevel.SUBORDINATE_UPPER_TIER_2; - default: - throw new IllegalStateException("Unmapped seniority level. Do not have mapping for " + this); + //------------------------------------------------------------------------- + + /** + * Converts Markit code to standard seniority level. + * + * @return the converted level + */ + public SeniorityLevel translate() { + switch (this) { + case SECDOM: + return SeniorityLevel.SENIOR_SECURED_DOMESTIC; + case SNRFOR: + return SeniorityLevel.SENIOR_UNSECURED_FOREIGN; + case SUBLT2: + return SeniorityLevel.SUBORDINATE_LOWER_TIER_2; + case PREFT1: + return SeniorityLevel.SUBORDINATE_TIER_1; + case JRSUBUT2: + return SeniorityLevel.SUBORDINATE_UPPER_TIER_2; + default: + throw new IllegalStateException("Unmapped seniority level. Do not have mapping for " + this); + } } - } - /** - * Converts seniority level to Markit equivalent. - * - * @param seniorityLevel the level to convert - * @return the converted level - */ - public static MarkitSeniorityLevel from(SeniorityLevel seniorityLevel) { - switch (seniorityLevel) { - case SENIOR_SECURED_DOMESTIC: - return SECDOM; - case SENIOR_UNSECURED_FOREIGN: - return SNRFOR; - case SUBORDINATE_LOWER_TIER_2: - return SUBLT2; - case SUBORDINATE_TIER_1: - return PREFT1; - case SUBORDINATE_UPPER_TIER_2: - return JRSUBUT2; - default: - throw new IllegalArgumentException("Unknown seniority level. Do not have mapping for " + seniorityLevel); + /** + * Converts seniority level to Markit equivalent. + * + * @param seniorityLevel the level to convert + * @return the converted level + */ + public static MarkitSeniorityLevel from(SeniorityLevel seniorityLevel) { + switch (seniorityLevel) { + case SENIOR_SECURED_DOMESTIC: + return SECDOM; + case SENIOR_UNSECURED_FOREIGN: + return SNRFOR; + case SUBORDINATE_LOWER_TIER_2: + return SUBLT2; + case SUBORDINATE_TIER_1: + return PREFT1; + case SUBORDINATE_UPPER_TIER_2: + return JRSUBUT2; + default: + throw new IllegalArgumentException("Unknown seniority level. Do not have mapping for " + seniorityLevel); + } } - } } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitSingleNameCreditCurveDataParser.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitSingleNameCreditCurveDataParser.java index 3ad85682a9..1da9114513 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitSingleNameCreditCurveDataParser.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitSingleNameCreditCurveDataParser.java @@ -1,6 +1,6 @@ /** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. */ package com.opengamma.strata.examples.marketdata.credit.markit; @@ -56,141 +56,141 @@ import java.util.Scanner; */ public class MarkitSingleNameCreditCurveDataParser { - // Markit date format with the month in full caps. e.g. 11-JUL-14 - private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder() - .parseCaseInsensitive().appendPattern("dd-MMM-uu").toFormatter(Locale.ENGLISH); + // Markit date format with the month in full caps. e.g. 11-JUL-14 + private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder() + .parseCaseInsensitive().appendPattern("dd-MMM-uu").toFormatter(Locale.ENGLISH); - // Index used to access the specified columns of string data in the file - private static final int DATE = 0; - private static final int RED_CODE = 3; - private static final int TIER = 4; - private static final int CURRENCY = 5; - private static final int DOCS_CLAUSE = 6; - private static final int FIRST_SPREAD_COLUMN = 8; - private static final int RECOVERY = 19; + // Index used to access the specified columns of string data in the file + private static final int DATE = 0; + private static final int RED_CODE = 3; + private static final int TIER = 4; + private static final int CURRENCY = 5; + private static final int DOCS_CLAUSE = 6; + private static final int FIRST_SPREAD_COLUMN = 8; + private static final int RECOVERY = 19; - private static final List TENORS = ImmutableList.of( - Tenor.TENOR_6M, - Tenor.TENOR_1Y, - Tenor.TENOR_2Y, - Tenor.TENOR_3Y, - Tenor.TENOR_4Y, - Tenor.TENOR_5Y, - Tenor.TENOR_7Y, - Tenor.TENOR_10Y, - Tenor.TENOR_15Y, - Tenor.TENOR_20Y, - Tenor.TENOR_30Y); + private static final List TENORS = ImmutableList.of( + Tenor.TENOR_6M, + Tenor.TENOR_1Y, + Tenor.TENOR_2Y, + Tenor.TENOR_3Y, + Tenor.TENOR_4Y, + Tenor.TENOR_5Y, + Tenor.TENOR_7Y, + Tenor.TENOR_10Y, + Tenor.TENOR_15Y, + Tenor.TENOR_20Y, + Tenor.TENOR_30Y); - /** - * Parses the specified sources. - * - * @param builder the market data builder that the resulting curve and recovery rate items should be loaded into - * @param curveSource the source of curve data to parse - * @param staticDataSource the source of static data to parse - */ - public static void parse( - ImmutableMarketDataBuilder builder, - CharSource curveSource, - CharSource staticDataSource) { + /** + * Parses the specified sources. + * + * @param builder the market data builder that the resulting curve and recovery rate items should be loaded into + * @param curveSource the source of curve data to parse + * @param staticDataSource the source of static data to parse + */ + public static void parse( + ImmutableMarketDataBuilder builder, + CharSource curveSource, + CharSource staticDataSource) { - Map conventions = parseStaticData(staticDataSource); - try (Scanner scanner = new Scanner(curveSource.openStream())) { - while (scanner.hasNextLine()) { + Map conventions = parseStaticData(staticDataSource); + try (Scanner scanner = new Scanner(curveSource.openStream())) { + while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - // skip over header rows - if (line.startsWith("V5 CDS Composites by Convention") || - line.trim().isEmpty() || - line.startsWith("\"Date\",")) { - continue; + String line = scanner.nextLine(); + // skip over header rows + if (line.startsWith("V5 CDS Composites by Convention") || + line.trim().isEmpty() || + line.startsWith("\"Date\",")) { + continue; + } + String[] columns = line.split(","); + for (int i = 0; i < columns.length; i++) { + // get rid of quotes and trim the string + columns[i] = columns[i].replaceFirst("^\"", "").replaceFirst("\"$", "").trim(); + } + + LocalDate valuationDate = LocalDate.parse(columns[DATE], DATE_FORMAT); + + MarkitRedCode redCode = MarkitRedCode.of(columns[RED_CODE]); + SeniorityLevel seniorityLevel = MarkitSeniorityLevel.valueOf(columns[TIER]).translate(); + Currency currency = Currency.parse(columns[CURRENCY]); + RestructuringClause restructuringClause = MarkitRestructuringClause.valueOf(columns[DOCS_CLAUSE]).translate(); + + double recoveryRate = parseRate(columns[RECOVERY]); + + SingleNameReferenceInformation referenceInformation = SingleNameReferenceInformation.of( + redCode.toStandardId(), + seniorityLevel, + currency, + restructuringClause); + + IsdaSingleNameCreditCurveInputsId curveId = IsdaSingleNameCreditCurveInputsId.of(referenceInformation); + + List periodsList = Lists.newArrayList(); + List ratesList = Lists.newArrayList(); + for (int i = 0; i < TENORS.size(); i++) { + String rateString = columns[FIRST_SPREAD_COLUMN + i]; + if (rateString.isEmpty()) { + // no data at this point + continue; + } + periodsList.add(TENORS.get(i).getPeriod()); + ratesList.add(parseRate(rateString)); + } + + String creditCurveName = curveId.toString(); + + CdsConvention cdsConvention = conventions.get(redCode); + + Period[] periods = periodsList.stream().toArray(Period[]::new); + LocalDate[] endDates = Lists + .newArrayList(periods) + .stream() + .map(p -> cdsConvention.calculateUnadjustedMaturityDateFromValuationDate(valuationDate, p)) + .toArray(LocalDate[]::new); + + double[] rates = ratesList.stream().mapToDouble(s -> s).toArray(); + double unitScalingFactor = 1d; // for single name, we don't do any scaling (no index factor) + + IsdaCreditCurveInputs curveInputs = IsdaCreditCurveInputs.of( + CurveName.of(creditCurveName), + periods, + endDates, + rates, + cdsConvention, + unitScalingFactor); + + builder.addValue(curveId, curveInputs); + + IsdaSingleNameRecoveryRateId recoveryRateId = IsdaSingleNameRecoveryRateId.of(referenceInformation); + CdsRecoveryRate cdsRecoveryRate = CdsRecoveryRate.of(recoveryRate); + + builder.addValue(recoveryRateId, cdsRecoveryRate); + + } + } catch (IOException ex) { + throw new UncheckedIOException(ex); } - String[] columns = line.split(","); - for (int i = 0; i < columns.length; i++) { - // get rid of quotes and trim the string - columns[i] = columns[i].replaceFirst("^\"", "").replaceFirst("\"$", "").trim(); - } - - LocalDate valuationDate = LocalDate.parse(columns[DATE], DATE_FORMAT); - - MarkitRedCode redCode = MarkitRedCode.of(columns[RED_CODE]); - SeniorityLevel seniorityLevel = MarkitSeniorityLevel.valueOf(columns[TIER]).translate(); - Currency currency = Currency.parse(columns[CURRENCY]); - RestructuringClause restructuringClause = MarkitRestructuringClause.valueOf(columns[DOCS_CLAUSE]).translate(); - - double recoveryRate = parseRate(columns[RECOVERY]); - - SingleNameReferenceInformation referenceInformation = SingleNameReferenceInformation.of( - redCode.toStandardId(), - seniorityLevel, - currency, - restructuringClause); - - IsdaSingleNameCreditCurveInputsId curveId = IsdaSingleNameCreditCurveInputsId.of(referenceInformation); - - List periodsList = Lists.newArrayList(); - List ratesList = Lists.newArrayList(); - for (int i = 0; i < TENORS.size(); i++) { - String rateString = columns[FIRST_SPREAD_COLUMN + i]; - if (rateString.isEmpty()) { - // no data at this point - continue; - } - periodsList.add(TENORS.get(i).getPeriod()); - ratesList.add(parseRate(rateString)); - } - - String creditCurveName = curveId.toString(); - - CdsConvention cdsConvention = conventions.get(redCode); - - Period[] periods = periodsList.stream().toArray(Period[]::new); - LocalDate[] endDates = Lists - .newArrayList(periods) - .stream() - .map(p -> cdsConvention.calculateUnadjustedMaturityDateFromValuationDate(valuationDate, p)) - .toArray(LocalDate[]::new); - - double[] rates = ratesList.stream().mapToDouble(s -> s).toArray(); - double unitScalingFactor = 1d; // for single name, we don't do any scaling (no index factor) - - IsdaCreditCurveInputs curveInputs = IsdaCreditCurveInputs.of( - CurveName.of(creditCurveName), - periods, - endDates, - rates, - cdsConvention, - unitScalingFactor); - - builder.addValue(curveId, curveInputs); - - IsdaSingleNameRecoveryRateId recoveryRateId = IsdaSingleNameRecoveryRateId.of(referenceInformation); - CdsRecoveryRate cdsRecoveryRate = CdsRecoveryRate.of(recoveryRate); - - builder.addValue(recoveryRateId, cdsRecoveryRate); - - } - } catch (IOException ex) { - throw new UncheckedIOException(ex); } - } - // parses the static data file of RED code to convention - private static Map parseStaticData(CharSource source) { - CsvFile csv = CsvFile.of(source, true); - Map result = Maps.newHashMap(); - for (CsvRow row : csv.rows()) { - String redCodeText = row.getField("RedCode"); - String conventionText = row.getField("Convention"); - result.put(MarkitRedCode.of(redCodeText), CdsConvention.of(conventionText)); + // parses the static data file of RED code to convention + private static Map parseStaticData(CharSource source) { + CsvFile csv = CsvFile.of(source, true); + Map result = Maps.newHashMap(); + for (CsvRow row : csv.rows()) { + String redCodeText = row.getField("RedCode"); + String conventionText = row.getField("Convention"); + result.put(MarkitRedCode.of(redCodeText), CdsConvention.of(conventionText)); + } + return result; } - return result; - } - // Converts from a string percentage rate with a percent sign to a double rate - // e.g. 0.12% => 0.0012d - private static double parseRate(String input) { - return Double.parseDouble(input.replace("%", "")) / 100d; - } + // Converts from a string percentage rate with a percent sign to a double rate + // e.g. 0.12% => 0.0012d + private static double parseRate(String input) { + return Double.parseDouble(input.replace("%", "")) / 100d; + } } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitYieldCurveDataParser.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitYieldCurveDataParser.java index a928a36a07..c47caacf54 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitYieldCurveDataParser.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/MarkitYieldCurveDataParser.java @@ -1,6 +1,6 @@ /** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. */ package com.opengamma.strata.examples.marketdata.credit.markit; @@ -31,104 +31,105 @@ import java.util.Map; */ public class MarkitYieldCurveDataParser { - private static final String DATE = "Valuation Date"; - private static final String TENOR = "Tenor"; - private static final String INSTRUMENT = "Instrument Type"; - private static final String RATE = "Rate"; - private static final String CONVENTION = "Curve Convention"; + private static final String DATE = "Valuation Date"; + private static final String TENOR = "Tenor"; + private static final String INSTRUMENT = "Instrument Type"; + private static final String RATE = "Rate"; + private static final String CONVENTION = "Curve Convention"; - /** - * Parses the specified source. - * - * @param source the source to parse - * @return the map of parsed yield curve par rates - */ - public static Map parse(CharSource source) { - // parse the curve data - Map> curveData = Maps.newHashMap(); - CsvFile csv = CsvFile.of(source, true); - for (CsvRow row : csv.rows()) { - String dateText = row.getField(DATE); - String tenorText = row.getField(TENOR); - String instrumentText = row.getField(INSTRUMENT); - String rateText = row.getField(RATE); - String conventionText = row.getField(CONVENTION); + /** + * Parses the specified source. + * + * @param source the source to parse + * @return the map of parsed yield curve par rates + */ + public static Map parse(CharSource source) { + // parse the curve data + Map> curveData = Maps.newHashMap(); + CsvFile csv = CsvFile.of(source, true); + for (CsvRow row : csv.rows()) { + String dateText = row.getField(DATE); + String tenorText = row.getField(TENOR); + String instrumentText = row.getField(INSTRUMENT); + String rateText = row.getField(RATE); + String conventionText = row.getField(CONVENTION); - Point point = new Point( - Tenor.parse(tenorText), - LocalDate.parse(dateText, DateTimeFormatter.ISO_LOCAL_DATE), - mapUnderlyingType(instrumentText), - Double.parseDouble(rateText)); - IsdaYieldCurveConvention convention = IsdaYieldCurveConvention.of(conventionText); + Point point = new Point( + Tenor.parse(tenorText), + LocalDate.parse(dateText, DateTimeFormatter.ISO_LOCAL_DATE), + mapUnderlyingType(instrumentText), + Double.parseDouble(rateText)); + IsdaYieldCurveConvention convention = IsdaYieldCurveConvention.of(conventionText); - List points = curveData.get(convention); - if (points == null) { - points = Lists.newArrayList(); - curveData.put(convention, points); - } - points.add(point); + List points = curveData.get(convention); + if (points == null) { + points = Lists.newArrayList(); + curveData.put(convention, points); + } + points.add(point); + } + + // convert the curve data into the result map + Map result = Maps.newHashMap(); + for (IsdaYieldCurveConvention convention : curveData.keySet()) { + List points = curveData.get(convention); + result.put(IsdaYieldCurveInputsId.of(convention.getCurrency()), + IsdaYieldCurveInputs.of( + CurveName.of(convention.getName()), + points.stream().map(s -> s.getTenor().getPeriod()).toArray(Period[]::new), + points.stream().map(s -> s.getDate()).toArray(LocalDate[]::new), + points.stream().map(s -> s.getInstrumentType()).toArray(IsdaYieldCurveUnderlyingType[]::new), + points.stream().mapToDouble(s -> s.getRate()).toArray(), + convention)); + } + return result; } - // convert the curve data into the result map - Map result = Maps.newHashMap(); - for (IsdaYieldCurveConvention convention : curveData.keySet()) { - List points = curveData.get(convention); - result.put(IsdaYieldCurveInputsId.of(convention.getCurrency()), - IsdaYieldCurveInputs.of( - CurveName.of(convention.getName()), - points.stream().map(s -> s.getTenor().getPeriod()).toArray(Period[]::new), - points.stream().map(s -> s.getDate()).toArray(LocalDate[]::new), - points.stream().map(s -> s.getInstrumentType()).toArray(IsdaYieldCurveUnderlyingType[]::new), - points.stream().mapToDouble(s -> s.getRate()).toArray(), - convention)); - } - return result; - } - - // parse the M/S instrument type flag - private static IsdaYieldCurveUnderlyingType mapUnderlyingType(String type) { - switch (type) { - case "M": - return IsdaYieldCurveUnderlyingType.ISDA_MONEY_MARKET; - case "S": - return IsdaYieldCurveUnderlyingType.ISDA_SWAP; - default: - throw new IllegalStateException("Unknown underlying type, only M or S allowed: " + type); - } - } - - //------------------------------------------------------------------------- - /** - * Stores the parsed data points. - */ - private static class Point { - private final Tenor tenor; - private final LocalDate date; - private final IsdaYieldCurveUnderlyingType instrumentType; - private final double rate; - - private Point(Tenor tenor, LocalDate baseDate, IsdaYieldCurveUnderlyingType instrumentType, double rate) { - this.tenor = tenor; - this.date = baseDate.plus(tenor.getPeriod()); - this.instrumentType = instrumentType; - this.rate = rate; + // parse the M/S instrument type flag + private static IsdaYieldCurveUnderlyingType mapUnderlyingType(String type) { + switch (type) { + case "M": + return IsdaYieldCurveUnderlyingType.ISDA_MONEY_MARKET; + case "S": + return IsdaYieldCurveUnderlyingType.ISDA_SWAP; + default: + throw new IllegalStateException("Unknown underlying type, only M or S allowed: " + type); + } } - public Tenor getTenor() { - return tenor; - } + //------------------------------------------------------------------------- - public LocalDate getDate() { - return date; - } + /** + * Stores the parsed data points. + */ + private static class Point { + private final Tenor tenor; + private final LocalDate date; + private final IsdaYieldCurveUnderlyingType instrumentType; + private final double rate; - public IsdaYieldCurveUnderlyingType getInstrumentType() { - return instrumentType; - } + private Point(Tenor tenor, LocalDate baseDate, IsdaYieldCurveUnderlyingType instrumentType, double rate) { + this.tenor = tenor; + this.date = baseDate.plus(tenor.getPeriod()); + this.instrumentType = instrumentType; + this.rate = rate; + } - public double getRate() { - return rate; + public Tenor getTenor() { + return tenor; + } + + public LocalDate getDate() { + return date; + } + + public IsdaYieldCurveUnderlyingType getInstrumentType() { + return instrumentType; + } + + public double getRate() { + return rate; + } } - } } diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/package-info.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/package-info.java index e05d86d71e..9e92d72356 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/package-info.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/credit/markit/package-info.java @@ -1,7 +1,9 @@ /** * Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. + *

+ * Credit market data for examples. */ /** diff --git a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/package-info.java b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/package-info.java index a0688333c4..c286a8db4b 100644 --- a/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/package-info.java +++ b/samples/simm-valuation-demo/src/main/java/com/opengamma/strata/examples/marketdata/package-info.java @@ -1,7 +1,9 @@ /** * Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies - * + *

* Please see distribution for license. + *

+ * Market data for examples. */ /** diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt index a10b756319..3fb9118fd5 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt @@ -254,13 +254,14 @@ class PortfolioApi(val rpc: CordaRPCOps) { val parties = rpc.networkMapSnapshot() val notaries = rpc.notaryIdentities() // TODO We are not able to filter by network map node now - val counterParties = parties.filterNot { it.legalIdentities.any { it in notaries } - || ownParty in it.legalIdentities + val counterParties = parties.filterNot { + it.legalIdentities.any { it in notaries } + || ownParty in it.legalIdentities } return AvailableParties( self = ApiParty(ownParty.owningKey.toBase58String(), ownParty.name), // TODO It will show all identities including service identities. - counterparties = counterParties.flatMap { it.legalIdentitiesAndCerts.map { ApiParty(it.owningKey.toBase58String(), it.name) }} + counterparties = counterParties.flatMap { it.legalIdentitiesAndCerts.map { ApiParty(it.owningKey.toBase58String(), it.name) } } ) } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt index eb1198a881..cfccafbc4d 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt @@ -70,6 +70,7 @@ object SimmFlow { private val existing: StateAndRef?) : FlowLogic>() { constructor(otherParty: Party, valuationDate: LocalDate) : this(otherParty, valuationDate, null) + lateinit var notary: Party lateinit var otherPartySession: FlowSession @@ -318,7 +319,7 @@ object SimmFlow { logger.info("Handshake finished, awaiting Simm update") replyToSession.send(Ack) // Hack to state that this party is ready. subFlow(object : StateRevisionFlow.Receiver(replyToSession) { - override fun verifyProposal(stx:SignedTransaction, proposal: Proposal) { + override fun verifyProposal(stx: SignedTransaction, proposal: Proposal) { super.verifyProposal(stx, proposal) if (proposal.modification.portfolio != portfolio.refs) throw StateReplacementException() } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/StateRevisionFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/StateRevisionFlow.kt index 49918f85c3..7616b9e932 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/StateRevisionFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/StateRevisionFlow.kt @@ -15,7 +15,7 @@ import net.corda.vega.contracts.RevisionedState */ object StateRevisionFlow { open class Requester(curStateRef: StateAndRef>, - updatedData: T) : AbstractStateReplacementFlow.Instigator, RevisionedState, T>(curStateRef, updatedData) { + updatedData: T) : AbstractStateReplacementFlow.Instigator, RevisionedState, T>(curStateRef, updatedData) { override fun assembleTx(): AbstractStateReplacementFlow.UpgradeTx { val state = originalState.state.data val tx = state.generateRevision(originalState.state.notary, originalState, modification) diff --git a/samples/simm-valuation-demo/src/test/java/net/corda/vega/SwapExampleX.java b/samples/simm-valuation-demo/src/test/java/net/corda/vega/SwapExampleX.java index 56a2dd2e6e..dfd18bbbd8 100644 --- a/samples/simm-valuation-demo/src/test/java/net/corda/vega/SwapExampleX.java +++ b/samples/simm-valuation-demo/src/test/java/net/corda/vega/SwapExampleX.java @@ -48,97 +48,97 @@ import static java.util.stream.Collectors.toList; */ public class SwapExampleX { - public static final LocalDate VALUATION_DATE = LocalDate.of(2016, 6, 6); + public static final LocalDate VALUATION_DATE = LocalDate.of(2016, 6, 6); - public static void main(String[] args) { - CurveGroupDefinition curveGroupDefinition = loadCurveGroup(); - MarketData marketData = loadMarketData(); - List trades = ImmutableList.of(createVanillaFixedVsLibor3mSwap(), createVanillaFixedVsLibor6mSwap()); - CurveCalibrator calibrator = CurveCalibrator.of(1e-9, 1e-9, 100, CalibrationMeasures.PAR_SPREAD); - ImmutableRatesProvider ratesProvider = calibrator.calibrate(curveGroupDefinition, marketData, ReferenceData.standard()); - MarketDataFxRateProvider fxRateProvider = MarketDataFxRateProvider.of(marketData); - ImmutableRatesProvider combinedRatesProvider = ImmutableRatesProvider.combined(fxRateProvider, ratesProvider); + public static void main(String[] args) { + CurveGroupDefinition curveGroupDefinition = loadCurveGroup(); + MarketData marketData = loadMarketData(); + List trades = ImmutableList.of(createVanillaFixedVsLibor3mSwap(), createVanillaFixedVsLibor6mSwap()); + CurveCalibrator calibrator = CurveCalibrator.of(1e-9, 1e-9, 100, CalibrationMeasures.PAR_SPREAD); + ImmutableRatesProvider ratesProvider = calibrator.calibrate(curveGroupDefinition, marketData, ReferenceData.standard()); + MarketDataFxRateProvider fxRateProvider = MarketDataFxRateProvider.of(marketData); + ImmutableRatesProvider combinedRatesProvider = ImmutableRatesProvider.combined(fxRateProvider, ratesProvider); - List resolvedTrades = trades.stream().map(trade -> trade.resolve(ReferenceData.standard())).collect(toList()); - DiscountingSwapProductPricer pricer = DiscountingSwapProductPricer.DEFAULT; + List resolvedTrades = trades.stream().map(trade -> trade.resolve(ReferenceData.standard())).collect(toList()); + DiscountingSwapProductPricer pricer = DiscountingSwapProductPricer.DEFAULT; - CurrencyParameterSensitivities totalSensitivities = CurrencyParameterSensitivities.empty(); - MultiCurrencyAmount totalCurrencyExposure = MultiCurrencyAmount.empty(); + CurrencyParameterSensitivities totalSensitivities = CurrencyParameterSensitivities.empty(); + MultiCurrencyAmount totalCurrencyExposure = MultiCurrencyAmount.empty(); - for (ResolvedSwapTrade resolvedTrade : resolvedTrades) { - ResolvedSwap swap = resolvedTrade.getProduct(); + for (ResolvedSwapTrade resolvedTrade : resolvedTrades) { + ResolvedSwap swap = resolvedTrade.getProduct(); - PointSensitivities pointSensitivities = pricer.presentValueSensitivity(swap, combinedRatesProvider).build(); - CurrencyParameterSensitivities sensitivities = combinedRatesProvider.parameterSensitivity(pointSensitivities); - MultiCurrencyAmount currencyExposure = pricer.currencyExposure(swap, combinedRatesProvider); + PointSensitivities pointSensitivities = pricer.presentValueSensitivity(swap, combinedRatesProvider).build(); + CurrencyParameterSensitivities sensitivities = combinedRatesProvider.parameterSensitivity(pointSensitivities); + MultiCurrencyAmount currencyExposure = pricer.currencyExposure(swap, combinedRatesProvider); - totalSensitivities = totalSensitivities.combinedWith(sensitivities); - totalCurrencyExposure = totalCurrencyExposure.plus(currencyExposure); + totalSensitivities = totalSensitivities.combinedWith(sensitivities); + totalCurrencyExposure = totalCurrencyExposure.plus(currencyExposure); + } + //PortfolioNormalizer normalizer = new PortfolioNormalizer(Currency.EUR, combinedRatesProvider); + //RwamBimmNotProductClassesCalculator calculatorTotal = new RwamBimmNotProductClassesCalculator( + // fxRateProvider, + // Currency.EUR, + // IsdaConfiguration.INSTANCE); +// + //Triple margin = BimmAnalysisUtils.computeMargin( + // combinedRatesProvider, + // normalizer, + // calculatorTotal, + // totalSensitivities, + // totalCurrencyExposure); +// + //System.out.println(margin); } - //PortfolioNormalizer normalizer = new PortfolioNormalizer(Currency.EUR, combinedRatesProvider); - //RwamBimmNotProductClassesCalculator calculatorTotal = new RwamBimmNotProductClassesCalculator( - // fxRateProvider, - // Currency.EUR, - // IsdaConfiguration.INSTANCE); -// - //Triple margin = BimmAnalysisUtils.computeMargin( - // combinedRatesProvider, - // normalizer, - // calculatorTotal, - // totalSensitivities, - // totalCurrencyExposure); -// - //System.out.println(margin); - } - //-------------------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------------------- - /** - * Load the market quotes and FX rates from data files. - */ - private static MarketData loadMarketData() { - Path dataDir = Paths.get("src/test/resources/data"); - Path quotesFile = dataDir.resolve("BIMM-MARKET-QUOTES-20160606.csv"); - Path fxFile = dataDir.resolve("BIMM-FX-RATES-20160606.csv"); + /** + * Load the market quotes and FX rates from data files. + */ + private static MarketData loadMarketData() { + Path dataDir = Paths.get("src/test/resources/data"); + Path quotesFile = dataDir.resolve("BIMM-MARKET-QUOTES-20160606.csv"); + Path fxFile = dataDir.resolve("BIMM-FX-RATES-20160606.csv"); - Map quotes = QuotesCsvLoader.load(VALUATION_DATE, ImmutableList.of(ResourceLocator.ofPath(quotesFile))); - Map fxRates = FxRatesCsvLoader.load(VALUATION_DATE, ResourceLocator.ofPath(fxFile)); - return ImmutableMarketData.builder(VALUATION_DATE).addValueMap(quotes).addValueMap(fxRates).build(); - } + Map quotes = QuotesCsvLoader.load(VALUATION_DATE, ImmutableList.of(ResourceLocator.ofPath(quotesFile))); + Map fxRates = FxRatesCsvLoader.load(VALUATION_DATE, ResourceLocator.ofPath(fxFile)); + return ImmutableMarketData.builder(VALUATION_DATE).addValueMap(quotes).addValueMap(fxRates).build(); + } - /** - * Loads the curve group definition from data files. - * - * A curve group maps from curve name to index for forward curves and curve name to currency for discount curves. - */ - private static CurveGroupDefinition loadCurveGroup() { - Path settingsDir = Paths.get("src/test/resources/settings"); - Map curveGroups = RatesCalibrationCsvLoader.load( - ResourceLocator.ofPath(settingsDir.resolve("BIMM-groups-EUR.csv")), - ResourceLocator.ofPath(settingsDir.resolve("BIMM-settings-EUR.csv")), - ResourceLocator.ofPath(settingsDir.resolve("BIMM-nodes-EUR.csv"))); - return curveGroups.get(CurveGroupName.of("BIMM")); - } + /** + * Loads the curve group definition from data files. + *

+ * A curve group maps from curve name to index for forward curves and curve name to currency for discount curves. + */ + private static CurveGroupDefinition loadCurveGroup() { + Path settingsDir = Paths.get("src/test/resources/settings"); + Map curveGroups = RatesCalibrationCsvLoader.load( + ResourceLocator.ofPath(settingsDir.resolve("BIMM-groups-EUR.csv")), + ResourceLocator.ofPath(settingsDir.resolve("BIMM-settings-EUR.csv")), + ResourceLocator.ofPath(settingsDir.resolve("BIMM-nodes-EUR.csv"))); + return curveGroups.get(CurveGroupName.of("BIMM")); + } - //-------------------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------------------- - private static SwapTrade createVanillaFixedVsLibor3mSwap() { - return FixedIborSwapConventions.EUR_FIXED_1Y_EURIBOR_3M.createTrade( - VALUATION_DATE, - Tenor.TENOR_4Y, - BuySell.BUY, - 200_000_000, - 0.015, - ReferenceData.standard()); - } + private static SwapTrade createVanillaFixedVsLibor3mSwap() { + return FixedIborSwapConventions.EUR_FIXED_1Y_EURIBOR_3M.createTrade( + VALUATION_DATE, + Tenor.TENOR_4Y, + BuySell.BUY, + 200_000_000, + 0.015, + ReferenceData.standard()); + } - private static SwapTrade createVanillaFixedVsLibor6mSwap() { - return FixedIborSwapConventions.EUR_FIXED_1Y_EURIBOR_6M.createTrade( - VALUATION_DATE, - Tenor.TENOR_10Y, - BuySell.SELL, - 100_000_000, - 0.013, - ReferenceData.standard()); - } + private static SwapTrade createVanillaFixedVsLibor6mSwap() { + return FixedIborSwapConventions.EUR_FIXED_1Y_EURIBOR_6M.createTrade( + VALUATION_DATE, + Tenor.TENOR_10Y, + BuySell.SELL, + 100_000_000, + 0.013, + ReferenceData.standard()); + } } diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt index e373de677d..101171880c 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt @@ -27,19 +27,21 @@ import java.util.* * Interface for communicating with nodes running the trader demo. */ class TraderDemoClientApi(val rpc: CordaRPCOps) { - val cashCount: Long get() { - val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() } - val countCriteria = QueryCriteria.VaultCustomQueryCriteria(count) - return rpc.vaultQueryBy(countCriteria).otherResults.single() as Long - } + val cashCount: Long + get() { + val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() } + val countCriteria = QueryCriteria.VaultCustomQueryCriteria(count) + return rpc.vaultQueryBy(countCriteria).otherResults.single() as Long + } val dollarCashBalance: Amount get() = rpc.getCashBalance(USD) - val commercialPaperCount: Long get() { - val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() } - val countCriteria = QueryCriteria.VaultCustomQueryCriteria(count) - return rpc.vaultQueryBy(countCriteria).otherResults.single() as Long - } + val commercialPaperCount: Long + get() { + val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() } + val countCriteria = QueryCriteria.VaultCustomQueryCriteria(count) + return rpc.vaultQueryBy(countCriteria).otherResults.single() as Long + } fun runIssuer(amount: Amount, buyerName: CordaX500Name, sellerName: CordaX500Name) { val ref = OpaqueBytes.of(1) diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt index 297f033ca1..cd1e7fed4b 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt @@ -31,7 +31,9 @@ class CommercialPaperIssueFlow(private val amount: Amount, companion object { val PROSPECTUS_HASH = SecureHash.parse("decd098666b9657314870e192ced0c3519c2c9d395507a238338f8d003929de9") + object ISSUING : ProgressTracker.Step("Issuing and timestamping some commercial paper") + fun tracker() = ProgressTracker(ISSUING) } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt index 1a17d02f3a..73e36aba5e 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt @@ -39,11 +39,13 @@ class PredefinedTestNode internal constructor(party: Party, driver: DriverDSLExp * for it: you won't have [ALICE_KEY]. */ fun DriverDSLExposedInterface.alice(): PredefinedTestNode = PredefinedTestNode(ALICE, this, null) + /** * Returns a plain, entirely stock node pre-configured with the [BOB] identity. Note that a random key will be generated * for it: you won't have [BOB_KEY]. */ fun DriverDSLExposedInterface.bob(): PredefinedTestNode = PredefinedTestNode(BOB, this, null) + /** * Returns a plain single node notary pre-configured with the [DUMMY_NOTARY] identity. Note that a random key will be generated * for it: you won't have [DUMMY_NOTARY_KEY]. diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/NodeTestUtils.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/NodeTestUtils.kt index 7f8069e919..7fe3ee5c09 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/NodeTestUtils.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/NodeTestUtils.kt @@ -20,7 +20,8 @@ import java.nio.file.Path * Creates and tests a ledger built by the passed in dsl. The provided services can be customised, otherwise a default * of a freshly built [MockServices] is used. */ -@JvmOverloads fun ledger( +@JvmOverloads +fun ledger( services: ServiceHub = MockServices(), initialiseSerialization: Boolean = true, dsl: LedgerDSL.() -> Unit @@ -40,7 +41,8 @@ import java.nio.file.Path * * @see LedgerDSLInterpreter._transaction */ -@JvmOverloads fun transaction( +@JvmOverloads +fun transaction( transactionLabel: String? = null, transactionBuilder: TransactionBuilder = TransactionBuilder(notary = DUMMY_NOTARY), initialiseSerialization: Boolean = true, @@ -54,6 +56,7 @@ fun testNodeConfiguration( myLegalName: CordaX500Name, notaryConfig: NotaryConfig? = null): NodeConfiguration { abstract class MockableNodeConfiguration : NodeConfiguration // Otherwise Mockito is defeated by val getters. + val nc = spy() whenever(nc.baseDirectory).thenReturn(baseDirectory) whenever(nc.myLegalName).thenReturn(myLegalName) diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/RPCDriver.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/RPCDriver.kt index 4aff94842f..c5156c16e2 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/RPCDriver.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/RPCDriver.kt @@ -64,7 +64,7 @@ interface RPCDriverExposedDSLInterface : DriverDSLExposedInterface { maxFileSize: Int = ArtemisMessagingServer.MAX_FILE_SIZE, maxBufferedBytesPerClient: Long = 10L * ArtemisMessagingServer.MAX_FILE_SIZE, configuration: RPCServerConfiguration = RPCServerConfiguration.default, - ops : I + ops: I ): CordaFuture /** @@ -110,8 +110,8 @@ interface RPCDriverExposedDSLInterface : DriverDSLExposedInterface { maxBufferedBytesPerClient: Long = 10L * ArtemisMessagingServer.MAX_FILE_SIZE, configuration: RPCServerConfiguration = RPCServerConfiguration.default, customPort: NetworkHostAndPort? = null, - ops : I - ) : CordaFuture + ops: I + ): CordaFuture /** * Starts a Netty RPC client. @@ -180,16 +180,19 @@ interface RPCDriverExposedDSLInterface : DriverDSLExposedInterface { brokerHandle: RpcBrokerHandle ): RpcServerHandle } + inline fun RPCDriverExposedDSLInterface.startInVmRpcClient( username: String = rpcTestUser.username, password: String = rpcTestUser.password, configuration: RPCClientConfiguration = RPCClientConfiguration.default ) = startInVmRpcClient(I::class.java, username, password, configuration) + inline fun RPCDriverExposedDSLInterface.startRandomRpcClient( hostAndPort: NetworkHostAndPort, username: String = rpcTestUser.username, password: String = rpcTestUser.password ) = startRandomRpcClient(I::class.java, hostAndPort, username, password) + inline fun RPCDriverExposedDSLInterface.startRpcClient( rpcAddress: NetworkHostAndPort, username: String = rpcTestUser.username, @@ -200,7 +203,8 @@ inline fun RPCDriverExposedDSLInterface.startRpcClient( interface RPCDriverInternalDSLInterface : DriverDSLInternalInterface, RPCDriverExposedDSLInterface data class RpcBrokerHandle( - val hostAndPort: NetworkHostAndPort?,/** null if this is an InVM broker */ + val hostAndPort: NetworkHostAndPort?, + /** null if this is an InVM broker */ val clientTransportConfiguration: TransportConfiguration, val serverControl: ActiveMQServerControl ) @@ -253,6 +257,7 @@ private class SingleUserSecurityManager(val rpcUser: User) : ActiveMQSecurityMan override fun validateUser(user: String?, password: String?, certificates: Array?): String? { return validate(user, password) } + override fun validateUserAndRole(user: String?, password: String?, roles: MutableSet?, checkType: CheckType?, address: String?, connection: RemotingConnection?): String? { return validate(user, password) } @@ -260,6 +265,7 @@ private class SingleUserSecurityManager(val rpcUser: User) : ActiveMQSecurityMan private fun isValid(user: String?, password: String?): Boolean { return rpcUser.username == user && rpcUser.password == password } + private fun validate(user: String?, password: String?): String? { return if (isValid(user, password)) user else null } @@ -303,6 +309,7 @@ data class RPCDriverDSL( } ) } + fun createInVmRpcServerArtemisConfig(maxFileSize: Int, maxBufferedBytesPerClient: Long): Configuration { return ConfigurationImpl().apply { acceptorConfigurations = setOf(TransportConfiguration(InVMAcceptorFactory::class.java.name)) @@ -310,6 +317,7 @@ data class RPCDriverDSL( configureCommonSettings(maxFileSize, maxBufferedBytesPerClient) } } + fun createRpcServerArtemisConfig(maxFileSize: Int, maxBufferedBytesPerClient: Long, baseDirectory: Path, hostAndPort: NetworkHostAndPort): Configuration { val connectionDirection = ConnectionDirection.Inbound(acceptorFactoryClassName = NettyAcceptorFactory::class.java.name) return ConfigurationImpl().apply { @@ -321,6 +329,7 @@ data class RPCDriverDSL( configureCommonSettings(maxFileSize, maxBufferedBytesPerClient) } } + val inVmClientTransportConfiguration = TransportConfiguration(InVMConnectorFactory::class.java.name) fun createNettyClientTransportConfiguration(hostAndPort: NetworkHostAndPort): TransportConfiguration { return ArtemisTcpTransport.tcpTransport(ConnectionDirection.Outbound(), hostAndPort, null) @@ -503,6 +512,7 @@ class RandomRpcUser { add(Generator.string()) add(Generator.int()) } + data class Call(val method: Method, val call: () -> Any?) @JvmStatic diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt index bf109863eb..4be46a59f5 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt @@ -143,7 +143,8 @@ class InMemoryMessagingNetwork( } /** This can be set to an object which can inject artificial latency between sender/recipient pairs. */ - @Volatile var latencyCalculator: LatencyCalculator? = null + @Volatile + var latencyCalculator: LatencyCalculator? = null private val timer = Timer() @Synchronized @@ -327,7 +328,7 @@ class InMemoryMessagingNetwork( while (!Thread.currentThread().isInterrupted) { try { pumpReceiveInternal(true) - } catch(e: InterruptedException) { + } catch (e: InterruptedException) { break } } @@ -452,7 +453,7 @@ class InMemoryMessagingNetwork( for (handler in deliverTo) { try { handler.callback(transfer.toReceivedMessage(), handler) - } catch(e: Exception) { + } catch (e: Exception) { log.error("Caught exception in handler for $this/${handler.topicSession}", e) } } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNetworkMapCache.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNetworkMapCache.kt index 1c357a90a6..1b82ca04c1 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNetworkMapCache.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNetworkMapCache.kt @@ -53,6 +53,6 @@ class MockNetworkMapCache(serviceHub: ServiceHubInternal) : PersistentNetworkMap */ @VisibleForTesting fun deleteRegistration(legalIdentity: Party): Boolean { - return partyNodes.removeIf { legalIdentity.owningKey in it.legalIdentitiesAndCerts.map { it.owningKey }} + return partyNodes.removeIf { legalIdentity.owningKey in it.legalIdentitiesAndCerts.map { it.owningKey } } } } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt index 52989475b3..43471696df 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt @@ -247,7 +247,9 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, // This does not indirect through the NodeInfo object so it can be called before the node is started. // It is used from the network visualiser tool. - @Suppress("unused") val place: WorldMapLocation get() = findMyLocation()!! + @Suppress("unused") + val place: WorldMapLocation + get() = findMyLocation()!! private var dbCloser: (() -> Any?)? = null override fun initialiseDatabasePersistence(schemaService: SchemaService, insideTransaction: () -> T) = super.initialiseDatabasePersistence(schemaService) { @@ -302,7 +304,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, legalName = MOCK_NET_MAP.name, notaryIdentity = null, advertisedServices = arrayOf(), - entropyRoot = BigInteger.valueOf(random63BitValue()), + entropyRoot = BigInteger.valueOf(random63BitValue()), configOverrides = {}, start = true ).started!!.apply { diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt index 6263dfbc65..3d49484fef 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt @@ -82,7 +82,9 @@ open class MockServices( fun makeTestDatabaseProperties(key: String? = null, value: String? = null): Properties { val props = Properties() props.setProperty("transactionIsolationLevel", "repeatableRead") //for other possible values see net.corda.node.utilities.CordaPeristence.parserTransactionIsolationLevel(String) - if (key != null) { props.setProperty(key, value) } + if (key != null) { + props.setProperty(key, value) + } return props } @@ -154,10 +156,11 @@ open class MockServices( override val contractUpgradeService: ContractUpgradeService get() = throw UnsupportedOperationException() override val networkMapCache: NetworkMapCache get() = throw UnsupportedOperationException() override val clock: Clock get() = Clock.systemUTC() - override val myInfo: NodeInfo get() { - val identity = getTestPartyAndCertificate(MEGA_CORP.name, key.public) - return NodeInfo(emptyList(), listOf(identity), 1, serial = 1L) - } + override val myInfo: NodeInfo + get() { + val identity = getTestPartyAndCertificate(MEGA_CORP.name, key.public) + return NodeInfo(emptyList(), listOf(identity), 1, serial = 1L) + } override val transactionVerifierService: TransactionVerifierService get() = InMemoryTransactionVerifierService(2) val mockCordappProvider: MockCordappProvider = MockCordappProvider(CordappLoader.createWithTestPackages(cordappPackages + CordappLoader.testPackages)).start(attachments) as MockCordappProvider override val cordappProvider: CordappProvider = mockCordappProvider diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/TestClock.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/TestClock.kt index 690f765c3d..e1149b1fda 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/TestClock.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/TestClock.kt @@ -25,7 +25,8 @@ class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableC /** * Advance this [Clock] by the specified [Duration] for testing purposes. */ - @Synchronized fun advanceBy(duration: Duration) { + @Synchronized + fun advanceBy(duration: Duration) { delegateClock = offset(delegateClock, duration) notifyMutationObservers() } @@ -35,7 +36,8 @@ class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableC * * This will only be approximate due to the time ticking away, but will be some time shortly after the requested [Instant]. */ - @Synchronized fun setTo(newInstant: Instant) = advanceBy(instant() until newInstant) + @Synchronized + fun setTo(newInstant: Instant) = advanceBy(instant() until newInstant) @Synchronized override fun instant(): Instant { return delegateClock.instant() diff --git a/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt b/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt index 6ab3de90d7..ae43e144db 100644 --- a/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt +++ b/testing/smoke-test-utils/src/main/kotlin/net/corda/smoketesting/NodeProcess.kt @@ -46,6 +46,7 @@ class NodeProcess( class Factory(val buildDirectory: Path = Paths.get("build"), val cordaJar: Path = Paths.get(this::class.java.getResource("/corda.jar").toURI())) { val nodesDirectory = buildDirectory / formatter.format(Instant.now()) + init { nodesDirectory.createDirectories() } @@ -95,11 +96,11 @@ class NodeProcess( private fun startNode(nodeDir: Path): Process { val builder = ProcessBuilder() - .command(javaPath.toString(), "-jar", cordaJar.toString()) - .directory(nodeDir.toFile()) + .command(javaPath.toString(), "-jar", cordaJar.toString()) + .directory(nodeDir.toFile()) builder.environment().putAll(mapOf( - "CAPSULE_CACHE_DIR" to (buildDirectory / "capsule").toString() + "CAPSULE_CACHE_DIR" to (buildDirectory / "capsule").toString() )) return builder.start() diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt index 5bec1a4aeb..4e20194249 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt @@ -117,8 +117,8 @@ fun freePort(): Int = freePortCounter.getAndAccumulate(0) { prev, _ -> 30000 + ( * to the Node, some other process else could allocate the returned ports. */ fun getFreeLocalPorts(hostName: String, numberToAlloc: Int): List { - val freePort = freePortCounter.getAndAccumulate(0) { prev, _ -> 30000 + (prev - 30000 + numberToAlloc) % 10000 } - return (freePort .. freePort + numberToAlloc - 1).map { NetworkHostAndPort(hostName, it) } + val freePort = freePortCounter.getAndAccumulate(0) { prev, _ -> 30000 + (prev - 30000 + numberToAlloc) % 10000 } + return (freePort..freePort + numberToAlloc - 1).map { NetworkHostAndPort(hostName, it) } } @JvmOverloads @@ -147,17 +147,17 @@ fun getTestPartyAndCertificate(name: CordaX500Name, publicKey: PublicKey, trustR } @Suppress("unused") -inline fun T.kryoSpecific(reason: String, function: () -> Unit) = if(!AMQP_ENABLED) { +inline fun T.kryoSpecific(reason: String, function: () -> Unit) = if (!AMQP_ENABLED) { function() } else { - loggerFor().info("Ignoring Kryo specific test, reason: $reason" ) + loggerFor().info("Ignoring Kryo specific test, reason: $reason") } @Suppress("unused") -inline fun T.amqpSpecific(reason: String, function: () -> Unit) = if(AMQP_ENABLED) { +inline fun T.amqpSpecific(reason: String, function: () -> Unit) = if (AMQP_ENABLED) { function() } else { - loggerFor().info("Ignoring AMQP specific test, reason: $reason" ) + loggerFor().info("Ignoring AMQP specific test, reason: $reason") } /** @@ -165,6 +165,7 @@ inline fun T.amqpSpecific(reason: String, function: () -> Unit * TODO: Should be removed after multiple identities are introduced. */ fun NodeInfo.chooseIdentityAndCert(): PartyAndCertificate = legalIdentitiesAndCerts.first() + fun NodeInfo.chooseIdentity(): Party = chooseIdentityAndCert().party /** Returns the identity of the first notary found on the network */ fun ServiceHub.getDefaultNotary(): Party = networkMapCache.notaryIdentities.first() diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/Eventually.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/Eventually.kt index b3a4588609..693fffeca9 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/Eventually.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/Eventually.kt @@ -6,15 +6,16 @@ import java.time.Duration * Ideas borrowed from "io.kotlintest" with some improvements made * This is meant for use from Kotlin code use only mainly due to it's inline/reified nature */ -inline fun eventually(duration: Duration, f: () -> R): R { +inline fun eventually(duration: Duration, f: () -> R): R { val end = System.nanoTime() + duration.toNanos() var times = 0 while (System.nanoTime() < end) { try { return f() } catch (e: Throwable) { - when(e) { - is E -> {}// ignore and continue + when (e) { + is E -> { + }// ignore and continue else -> throw e // unexpected exception type - rethrow } } diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/FlowStackSnapshot.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/FlowStackSnapshot.kt index d79568d693..74f622bc37 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/FlowStackSnapshot.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/FlowStackSnapshot.kt @@ -78,14 +78,15 @@ class FlowStackSnapshotFactoryImpl : FlowStackSnapshotFactory { return FlowStackSnapshot(Instant.now(), flowClass.name, frames) } - private val StackTraceElement.instrumentedAnnotation: Instrumented? get() { - Class.forName(className).methods.forEach { - if (it.name == methodName && it.isAnnotationPresent(Instrumented::class.java)) { - return it.getAnnotation(Instrumented::class.java) + private val StackTraceElement.instrumentedAnnotation: Instrumented? + get() { + Class.forName(className).methods.forEach { + if (it.name == methodName && it.isAnnotationPresent(Instrumented::class.java)) { + return it.getAnnotation(Instrumented::class.java) + } } + return null } - return null - } private fun removeConstructorStackTraceElements(stackTrace: List): List { val newStackTrace = ArrayList() diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/Measure.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/Measure.kt index 102cc0f413..91eaecf0a0 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/Measure.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/Measure.kt @@ -12,10 +12,13 @@ import kotlin.reflect.jvm.reflect fun measure(a: Iterable, f: (A) -> R) = measure(listOf(a), f.reflect()!!) { f(uncheckedCast(it[0])) } + fun measure(a: Iterable, b: Iterable, f: (A, B) -> R) = measure(listOf(a, b), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1])) } + fun measure(a: Iterable, b: Iterable, c: Iterable, f: (A, B, C) -> R) = measure(listOf(a, b, c), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1]), uncheckedCast(it[2])) } + fun measure(a: Iterable, b: Iterable, c: Iterable, d: Iterable, f: (A, B, C, D) -> R) = measure(listOf(a, b, c, d), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1]), uncheckedCast(it[2]), uncheckedCast(it[3])) } @@ -30,8 +33,8 @@ private fun measure(paramIterables: List>, kCallable: KCallab } data class MeasureResult( - val parameters: List>, - val result: R + val parameters: List>, + val result: R ) fun iterateLexical(iterables: List>): Iterable> { diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/SerializationTestHelpers.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/SerializationTestHelpers.kt index c3f5872cd7..891808e4b5 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/SerializationTestHelpers.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/SerializationTestHelpers.kt @@ -22,32 +22,32 @@ fun initialiseTestSerialization() { // Check that everything is configured for testing with mutable delegating instances. try { check(SerializationDefaults.SERIALIZATION_FACTORY is TestSerializationFactory) - } catch(e: IllegalStateException) { + } catch (e: IllegalStateException) { SerializationDefaults.SERIALIZATION_FACTORY = TestSerializationFactory() } try { check(SerializationDefaults.P2P_CONTEXT is TestSerializationContext) - } catch(e: IllegalStateException) { + } catch (e: IllegalStateException) { SerializationDefaults.P2P_CONTEXT = TestSerializationContext() } try { check(SerializationDefaults.RPC_SERVER_CONTEXT is TestSerializationContext) - } catch(e: IllegalStateException) { + } catch (e: IllegalStateException) { SerializationDefaults.RPC_SERVER_CONTEXT = TestSerializationContext() } try { check(SerializationDefaults.RPC_CLIENT_CONTEXT is TestSerializationContext) - } catch(e: IllegalStateException) { + } catch (e: IllegalStateException) { SerializationDefaults.RPC_CLIENT_CONTEXT = TestSerializationContext() } try { check(SerializationDefaults.STORAGE_CONTEXT is TestSerializationContext) - } catch(e: IllegalStateException) { + } catch (e: IllegalStateException) { SerializationDefaults.STORAGE_CONTEXT = TestSerializationContext() } try { check(SerializationDefaults.CHECKPOINT_CONTEXT is TestSerializationContext) - } catch(e: IllegalStateException) { + } catch (e: IllegalStateException) { SerializationDefaults.CHECKPOINT_CONTEXT = TestSerializationContext() } diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/TestDSL.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/TestDSL.kt index 9b4e99b752..48658ea021 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/TestDSL.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/TestDSL.kt @@ -274,7 +274,7 @@ data class TestLedgerDSLInterpreter private constructor( transactionLabel: String?, transactionBuilder: TransactionBuilder, dsl: TransactionDSL.() -> Unit - ) = recordTransactionWithTransactionMap(transactionLabel, transactionBuilder, dsl, nonVerifiedTransactionWithLocations, fillTransaction = true) + ) = recordTransactionWithTransactionMap(transactionLabel, transactionBuilder, dsl, nonVerifiedTransactionWithLocations, fillTransaction = true) override fun tweak( dsl: LedgerDSL(val interpreter: T) : Tr */ @JvmOverloads fun output(contractClassName: ContractClassName, contractState: ContractState, attachmentConstraint: AttachmentConstraint = AutomaticHashConstraint) = - _output(contractClassName,null, DUMMY_NOTARY, null, attachmentConstraint, contractState) + _output(contractClassName, null, DUMMY_NOTARY, null, attachmentConstraint, contractState) /** * Adds a command to the transaction. @@ -146,5 +146,5 @@ class TransactionDSL(val interpreter: T) : Tr */ fun attachment(contractClassName: ContractClassName) = _attachment(contractClassName) - fun attachments(vararg contractClassNames: ContractClassName) = contractClassNames.forEach { attachment(it)} + fun attachments(vararg contractClassNames: ContractClassName) = contractClassNames.forEach { attachment(it) } } diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyDealContract.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyDealContract.kt index 2fb6817d0d..b19bfac076 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyDealContract.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyDealContract.kt @@ -19,8 +19,7 @@ class DummyDealContract : Contract { data class State( override val participants: List, - override val linearId: UniqueIdentifier) : DealState, QueryableState - { + override val linearId: UniqueIdentifier) : DealState, QueryableState { constructor(participants: List = listOf(), ref: String) : this(participants, UniqueIdentifier(ref)) diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/VaultFiller.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/VaultFiller.kt index 8abe70d329..a921cd00c4 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/VaultFiller.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/VaultFiller.kt @@ -32,7 +32,7 @@ import java.util.* @JvmOverloads fun ServiceHub.fillWithSomeTestDeals(dealIds: List, participants: List = emptyList(), - notary: Party = DUMMY_NOTARY) : Vault { + notary: Party = DUMMY_NOTARY): Vault { val myKey: PublicKey = myInfo.chooseIdentity().owningKey val me = AnonymousParty(myKey) @@ -63,7 +63,7 @@ fun ServiceHub.fillWithSomeTestLinearStates(numberToCreate: Int, linearString: String = "", linearNumber: Long = 0L, linearBoolean: Boolean = false, - linearTimestamp: Instant = now()) : Vault { + linearTimestamp: Instant = now()): Vault { val myKey: PublicKey = myInfo.chooseIdentity().owningKey val me = AnonymousParty(myKey) val issuerKey = DUMMY_NOTARY_KEY @@ -196,7 +196,7 @@ fun calculateRandomlySizedAmounts(howMuch: Amount, min: Int, max: Int, fun ServiceHub.consume(states: List>, notary: Party) { // Create a txn consuming different contract types states.forEach { - val builder = TransactionBuilder(notary = notary).apply { + val builder = TransactionBuilder(notary = notary).apply { addInputState(it) addCommand(dummyCommand(notary.owningKey)) } @@ -238,7 +238,7 @@ fun ServiceHub.consumeAndProduce(states: List>, fun ServiceHub.consumeDeals(dealStates: List>, notary: Party) = consume(dealStates, notary) fun ServiceHub.consumeLinearStates(linearStates: List>, notary: Party) = consume(linearStates, notary) fun ServiceHub.evolveLinearStates(linearStates: List>, notary: Party) = consumeAndProduce(linearStates, notary) -fun ServiceHub.evolveLinearState(linearState: StateAndRef, notary: Party) : StateAndRef = consumeAndProduce(linearState, notary) +fun ServiceHub.evolveLinearState(linearState: StateAndRef, notary: Party): StateAndRef = consumeAndProduce(linearState, notary) /** * Consume cash, sending any change to the default identity for this node. Only suitable for use in test scenarios, @@ -254,7 +254,7 @@ fun ServiceHub.consumeCash(amount: Amount, to: Party = CHARLIE, notary */ @JvmOverloads fun ServiceHub.consumeCash(amount: Amount, ourIdentity: PartyAndCertificate, to: Party = CHARLIE, notary: Party): Vault.Update { - val update = vaultService.rawUpdates.toFuture() + val update = vaultService.rawUpdates.toFuture() val services = this // A tx that spends our money. diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/http/HttpApi.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/http/HttpApi.kt index 743934e921..0c283fd844 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/http/HttpApi.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/http/HttpApi.kt @@ -29,6 +29,7 @@ class HttpApi(val root: URL, val mapper: ObjectMapper = defaultMapper) { companion object { fun fromHostAndPort(hostAndPort: NetworkHostAndPort, base: String, protocol: String = "http", mapper: ObjectMapper = defaultMapper): HttpApi = HttpApi(URL("$protocol://$hostAndPort/$base/"), mapper) + private val defaultMapper: ObjectMapper by lazy { net.corda.client.jackson.JacksonSupport.createNonRpcMapper() } diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/schemas/DummyLinearStateSchemaV1.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/schemas/DummyLinearStateSchemaV1.kt index e25018bd9c..1a610c9372 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/schemas/DummyLinearStateSchemaV1.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/schemas/DummyLinearStateSchemaV1.kt @@ -20,8 +20,8 @@ object DummyLinearStateSchema object DummyLinearStateSchemaV1 : MappedSchema(schemaFamily = DummyLinearStateSchema.javaClass, version = 1, mappedTypes = listOf(PersistentDummyLinearState::class.java)) { @Entity @Table(name = "dummy_linear_states", - indexes = arrayOf(Index(name = "external_id_idx", columnList = "external_id"), - Index(name = "uuid_idx", columnList = "uuid"))) + indexes = arrayOf(Index(name = "external_id_idx", columnList = "external_id"), + Index(name = "uuid_idx", columnList = "uuid"))) class PersistentDummyLinearState( /** [ContractState] attributes */ diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/explorer/Explorer.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/explorer/Explorer.kt index 3bf445b827..a03e83d88c 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/explorer/Explorer.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/explorer/Explorer.kt @@ -88,7 +88,7 @@ class Explorer internal constructor(private val explorerController: ExplorerCont try { // Try making a symlink to make things faster and use less disk space. Files.createSymbolicLink(destPath, path) - } catch(e: UnsupportedOperationException) { + } catch (e: UnsupportedOperationException) { // OS doesn't support symbolic links? Files.copy(path, destPath, REPLACE_EXISTING) } catch (e: java.nio.file.FileAlreadyExistsException) { diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeConfig.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeConfig.kt index 03dda19564..8cde8f3bcf 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeConfig.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeConfig.kt @@ -62,7 +62,7 @@ class NodeConfig constructor( fun toText(): String = toFileConfig().root().render(renderOptions) fun moveTo(baseDir: Path) = NodeConfig( - baseDir, legalName, p2pPort, rpcPort, webPort, h2Port, extraServices, users, networkMap + baseDir, legalName, p2pPort, rpcPort, webPort, h2Port, extraServices, users, networkMap ) fun install(plugins: Collection) { diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt index 367f04b847..5bd33b700e 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt @@ -33,9 +33,10 @@ class NodeController(check: atRuntime = ::checkExists) : Controller() { private var networkMapConfig: NetworkMapConfig? = null - val activeNodes: List get() = nodes.values.filter { - (it.state == NodeState.RUNNING) || (it.state == NodeState.STARTING) - } + val activeNodes: List + get() = nodes.values.filter { + (it.state == NodeState.RUNNING) || (it.state == NodeState.STARTING) + } init { log.info("Base directory: $baseDir") diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/ServiceController.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/ServiceController.kt index 2f63b8e1c0..729f305805 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/ServiceController.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/ServiceController.kt @@ -28,8 +28,7 @@ class ServiceController(resourceName: String = "/services.conf") : Controller() val service = line.split(":").map { it.trim() } if (service.size != 2) { log.warning("Encountered corrupted line '$line' while reading services from config: $url") - } - else { + } else { map[service[1]] = service[0] log.info("Supports: $service") } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/pty/R3Pty.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/pty/R3Pty.kt index afc91bb6f4..cd82181367 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/pty/R3Pty.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/pty/R3Pty.kt @@ -21,7 +21,7 @@ class R3Pty(val name: CordaX500Name, settings: SettingsProvider, dimension: Dime val terminal = JediTermWidget(dimension, settings) - val isConnected: Boolean get() = terminal.ttyConnector?.isConnected ?: false + val isConnected: Boolean get() = terminal.ttyConnector?.isConnected == true override fun close() { log.info("Closing terminal '{}'", name) diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt index a19fcbc484..6046aa0e11 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt @@ -179,9 +179,9 @@ class NodeTerminalView : Fragment() { } private fun launchRPC(config: NodeConfig) = NodeRPC( - config = config, - start = this::initialise, - invoke = this::pollCashBalances + config = config, + start = this::initialise, + invoke = this::pollCashBalances ) private fun initialise(config: NodeConfig, ops: CordaRPCOps) { @@ -238,7 +238,10 @@ class NodeTerminalView : Fragment() { header.isDisable = true subscriptions.forEach { // Don't allow any exceptions here to halt tab destruction. - try { it.unsubscribe() } catch (e: Exception) {} + try { + it.unsubscribe() + } catch (e: Exception) { + } } webServer.close() explorer.close() diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/web/WebServer.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/web/WebServer.kt index 4ff4e23e01..4aec34a73b 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/web/WebServer.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/web/WebServer.kt @@ -98,7 +98,7 @@ class WebServer internal constructor(private val webServerController: WebServerC conn.connect() conn.disconnect() return url - } catch(e: IOException) { + } catch (e: IOException) { } } throw TimeoutException("Web server did not start within ${timeout.seconds} seconds") diff --git a/tools/demobench/src/test/kotlin/net/corda/demobench/LoggingTestSuite.kt b/tools/demobench/src/test/kotlin/net/corda/demobench/LoggingTestSuite.kt index cd662ace6a..946718c42a 100644 --- a/tools/demobench/src/test/kotlin/net/corda/demobench/LoggingTestSuite.kt +++ b/tools/demobench/src/test/kotlin/net/corda/demobench/LoggingTestSuite.kt @@ -25,7 +25,8 @@ class LoggingTestSuite { */ companion object { @BeforeClass - @JvmStatic fun `setup logging`() { + @JvmStatic + fun `setup logging`() { LoggingConfig() } } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/AmountDiff.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/AmountDiff.kt index a77205adb8..24a95ec46b 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/AmountDiff.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/AmountDiff.kt @@ -7,10 +7,11 @@ enum class Positivity { Negative } -val Positivity.sign: String get() = when (this) { - Positivity.Positive -> "" - Positivity.Negative -> "-" -} +val Positivity.sign: String + get() = when (this) { + Positivity.Positive -> "" + Positivity.Negative -> "-" + } data class AmountDiff( val positivity: Positivity, diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt index cb7f69df1f..de6a41aded 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt @@ -103,7 +103,7 @@ class Network : CordaView() { hgap = 5.0 vgap = 5.0 for (identity in identities) { - val isNotary = identity.name.commonName?.let { ServiceType.parse(it).isNotary() } ?: false + val isNotary = identity.name.commonName?.let { ServiceType.parse(it).isNotary() } == true row("${if (isNotary) "Notary " else ""}Public Key :") { copyableLabel(SimpleObjectProperty(identity.owningKey.toBase58String())) } @@ -150,7 +150,7 @@ class Network : CordaView() { } override fun onDock() { - centralLabel = mapLabels.firstOrDefault(SimpleObjectProperty(myLabel), { centralPeer?.contains(it.text, true) ?: false }) + centralLabel = mapLabels.firstOrDefault(SimpleObjectProperty(myLabel), { centralPeer?.contains(it.text, true) == true }) centralLabel.value?.let { mapScrollPane.centerLabel(it) } } @@ -160,7 +160,7 @@ class Network : CordaView() { } init { - centralLabel = mapLabels.firstOrDefault(SimpleObjectProperty(myLabel), { centralPeer?.contains(it.text, true) ?: false }) + centralLabel = mapLabels.firstOrDefault(SimpleObjectProperty(myLabel), { centralPeer?.contains(it.text, true) == true }) Bindings.bindContent(notaryList.children, notaryButtons) Bindings.bindContent(peerList.children, peerButtons) // Run once when the screen is ready. diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/SearchField.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/SearchField.kt index 2feeb8a938..ce06f65318 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/SearchField.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/SearchField.kt @@ -37,7 +37,7 @@ class SearchField(private val data: ObservableList, vararg filterCriteria: text.isNullOrBlank() || if (category == ALL) { filterCriteria.any { it.second(data, text) } } else { - filterCriteria.toMap()[category]?.invoke(data, text) ?: false + filterCriteria.toMap()[category]?.invoke(data, text) == true } } }, arrayOf(textField.textProperty(), searchCategory.valueProperty()))) diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt index f528e0ec66..128c2f221b 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt @@ -135,8 +135,8 @@ class TransactionViewer : CordaView("Transactions") { "Transaction ID" to { tx, s -> "${tx.id}".contains(s, true) }, "Input" to { tx, s -> tx.inputs.resolved.any { it.state.contract.contains(s, true) } }, "Output" to { tx, s -> tx.outputs.any { it.state.contract.contains(s, true) } }, - "Input Party" to { tx, s -> tx.inputParties.any { it.any { it.value?.name?.organisation?.contains(s, true) ?: false } } }, - "Output Party" to { tx, s -> tx.outputParties.any { it.any { it.value?.name?.organisation?.contains(s, true) ?: false } } }, + "Input Party" to { tx, s -> tx.inputParties.any { it.any { it.value?.name?.organisation?.contains(s, true) == true } } }, + "Output Party" to { tx, s -> tx.outputParties.any { it.any { it.value?.name?.organisation?.contains(s, true) == true } } }, "Command Type" to { tx, s -> tx.commandTypes.any { it.simpleName.contains(s, true) } } ) root.top = searchField.root diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/CashViewer.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/CashViewer.kt index 480ae1116e..6093a235b1 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/CashViewer.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/CashViewer.kt @@ -147,7 +147,7 @@ class CashViewer : CordaView("Cash") { */ val searchField = SearchField(cashStates, "Currency" to { state, text -> state.state.data.amount.token.product.toString().contains(text, true) }, - "Issuer" to { state, text -> state.resolveIssuer().value?.name?.organisation?.contains(text, true) ?: false } + "Issuer" to { state, text -> state.resolveIssuer().value?.name?.organisation?.contains(text, true) == true } ) root.top = hbox(5.0) { button("New Transaction", FontAwesomeIconView(FontAwesomeIcon.PLUS)) { diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/ConnectionManager.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/ConnectionManager.kt index 5b4f0f57ba..fe3e4fc621 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/ConnectionManager.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/ConnectionManager.kt @@ -47,6 +47,7 @@ fun setupJSchWithSshAgent(): JSch { override fun getSignature(data: ByteArray?) = agentProxy.sign(identity.blob, data) @Suppress("OverridingDeprecatedMember") override fun decrypt() = true + override fun getPublicKeyBlob() = identity.blob override fun setPassphrase(passphrase: ByteArray?) = true } diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt index 87aa80de90..b704f50acd 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt @@ -45,6 +45,7 @@ val isNotary = { node: NodeConnection -> val notaries = node.proxy.notaryIdentities() node.info.legalIdentities.any { it in notaries } } + fun ((A) -> Boolean).or(other: (A) -> Boolean): (A) -> Boolean = { this(it) || other(it) } fun hang(hangIntervalRange: LongRange) = Disruption("Hang randomly") { node, random -> diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt index 645b31ad67..a7751ca708 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt @@ -182,7 +182,8 @@ fun runLoadTests(configuration: LoadTestConfiguration, tests: List acc + "\n" + elem.name + ": " + elem.owningKey.toBase58String() } }.joinToString("\n") diff --git a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt index 6648fdb83d..d12dbc7a41 100644 --- a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt +++ b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt @@ -111,8 +111,8 @@ class VerifierTests { @Test fun `single verifier works with a node`() { verifierDriver( - networkMapStartStrategy = NetworkMapStartStrategy.Dedicated(startAutomatically = true), - extraCordappPackagesToScan = listOf("net.corda.finance.contracts") + networkMapStartStrategy = NetworkMapStartStrategy.Dedicated(startAutomatically = true), + extraCordappPackagesToScan = listOf("net.corda.finance.contracts") ) { val aliceFuture = startNode(providedName = ALICE.name) val notaryFuture = startNotaryNode(DUMMY_NOTARY.name, verifierType = VerifierType.OutOfProcess) diff --git a/webserver/src/main/kotlin/net/corda/webserver/internal/NodeWebServer.kt b/webserver/src/main/kotlin/net/corda/webserver/internal/NodeWebServer.kt index 462f792c52..8d5bf05a03 100644 --- a/webserver/src/main/kotlin/net/corda/webserver/internal/NodeWebServer.kt +++ b/webserver/src/main/kotlin/net/corda/webserver/internal/NodeWebServer.kt @@ -120,7 +120,7 @@ class NodeWebServer(val config: WebServerConfig) { } @Throws(IOException::class) - override fun writeErrorPageMessage(request: HttpServletRequest, writer: Writer, code: Int, message: String , uri: String) { + override fun writeErrorPageMessage(request: HttpServletRequest, writer: Writer, code: Int, message: String, uri: String) { writer.write("

Corda $safeLegalName

\n") super.writeErrorPageMessage(request, writer, code, message, uri) } @@ -135,10 +135,10 @@ class NodeWebServer(val config: WebServerConfig) { } val resourceConfig = ResourceConfig() - .register(ObjectMapperConfig(rpcObjectMapper)) - .register(ResponseFilter()) - .register(CordaConverterProvider) - .register(APIServerImpl(localRpc)) + .register(ObjectMapperConfig(rpcObjectMapper)) + .register(ResponseFilter()) + .register(CordaConverterProvider) + .register(APIServerImpl(localRpc)) val webAPIsOnClasspath = pluginRegistries.flatMap { x -> x.webApis } for (webapi in webAPIsOnClasspath) { diff --git a/webserver/src/main/kotlin/net/corda/webserver/servlets/AttachmentDownloadServlet.kt b/webserver/src/main/kotlin/net/corda/webserver/servlets/AttachmentDownloadServlet.kt index 9750f595ac..e23d420059 100644 --- a/webserver/src/main/kotlin/net/corda/webserver/servlets/AttachmentDownloadServlet.kt +++ b/webserver/src/main/kotlin/net/corda/webserver/servlets/AttachmentDownloadServlet.kt @@ -55,7 +55,7 @@ class AttachmentDownloadServlet : HttpServlet() { // Closing the output stream commits our response. We cannot change the status code after this. resp.outputStream.close() - } catch(e: FileNotFoundException) { + } catch (e: FileNotFoundException) { log.warn("404 Not Found whilst trying to handle attachment download request for ${servletContext.contextPath}/$reqPath") resp.sendError(HttpServletResponse.SC_NOT_FOUND) return diff --git a/webserver/src/main/kotlin/net/corda/webserver/servlets/CorDappInfoServlet.kt b/webserver/src/main/kotlin/net/corda/webserver/servlets/CorDappInfoServlet.kt index eba6597428..8daa446af9 100644 --- a/webserver/src/main/kotlin/net/corda/webserver/servlets/CorDappInfoServlet.kt +++ b/webserver/src/main/kotlin/net/corda/webserver/servlets/CorDappInfoServlet.kt @@ -15,7 +15,7 @@ import javax.servlet.http.HttpServletResponse * Dumps some data about the installed CorDapps. * TODO: Add registered flow initiators. */ -class CorDappInfoServlet(val plugins: List, val rpc: CordaRPCOps): HttpServlet() { +class CorDappInfoServlet(val plugins: List, val rpc: CordaRPCOps) : HttpServlet() { @Throws(IOException::class) override fun doGet(req: HttpServletRequest, resp: HttpServletResponse) { @@ -73,7 +73,7 @@ class CorDappInfoServlet(val plugins: List, val rpc: Co for (method in resource.allMethods) { if (method.type == ResourceMethod.JaxrsType.SUB_RESOURCE_LOCATOR) { - resources.add( Resource.from(resource.resourceLocator.invocable.definitionMethod.returnType)) + resources.add(Resource.from(resource.resourceLocator.invocable.definitionMethod.returnType)) } else { endpoints.add(Endpoint(method.httpMethod, "api$path", resource.path)) }