CORDA-939 - Don't expose StartedNode and AbstractNode as part of public test api (#2472)

* Don't expose StartedNode via Node Driver

* Dont expose StartedNode/Abstract Node via MockNetwork

* Remove internal var from constructor as it doesn't hide from public api and change to internal initialisation method

* Update api

* Rename MockNode to StartedMockNode to avoid confusion
Update documentation
Update api-current.txt

* Fix typo

* Fix test failure

* Modify flow tests to use internal mock network and remove additional internal exposures from StartedMockNode

* Fix api-current

* Change InProcess and OutOfProcess to interfaces

* Explicitly declare MockNetwork parameters
Dont expose StateMachineManager
Move affected tests to use internal mock network

* Fix api-current

* Changes requested via review

* Fix IRS Demo address

* Fix api

* Remove internal attribute from classes in internal package

* Remove accidentally added code

* Move useHttps into NodeHandleInternal

* Remove duplicated code

* Update api-current

* Make webAddress internal on NodeHandle

* Make sure parameters in public api are explicitly specified

* Use correct address in IRS Demo

* Get webaddress from webserver handle

* Update api-current
This commit is contained in:
Anthony Keenan 2018-02-12 10:09:59 +00:00 committed by GitHub
parent 3c4212a3d6
commit 7b65b7971a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 681 additions and 554 deletions

View File

@ -1013,8 +1013,10 @@ public final class net.corda.core.crypto.SignatureScheme extends java.lang.Objec
##
@net.corda.core.serialization.CordaSerializable public final class net.corda.core.crypto.TransactionSignature extends net.corda.core.crypto.DigitalSignature
public <init>(byte[], java.security.PublicKey, net.corda.core.crypto.SignatureMetadata)
public <init>(byte[], java.security.PublicKey, net.corda.core.crypto.SignatureMetadata, net.corda.core.crypto.PartialMerkleTree)
public boolean equals(Object)
@org.jetbrains.annotations.NotNull public final java.security.PublicKey getBy()
@org.jetbrains.annotations.Nullable public final net.corda.core.crypto.PartialMerkleTree getPartialMerkleTree()
@org.jetbrains.annotations.NotNull public final net.corda.core.crypto.SignatureMetadata getSignatureMetadata()
public int hashCode()
public final boolean isValid(net.corda.core.crypto.SecureHash)
@ -3696,6 +3698,11 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters setWaitForAllNodesToFinish(boolean)
public String toString()
##
@net.corda.core.DoNotImplement public interface net.corda.testing.driver.InProcess extends net.corda.testing.driver.NodeHandle
@org.jetbrains.annotations.NotNull public abstract net.corda.nodeapi.internal.persistence.CordaPersistence getDatabase()
@org.jetbrains.annotations.NotNull public abstract net.corda.node.services.api.StartedNodeServices getServices()
@org.jetbrains.annotations.NotNull public abstract rx.Observable registerInitiatedFlow(Class)
##
public final class net.corda.testing.driver.JmxPolicy extends java.lang.Object
public <init>()
public <init>(boolean, net.corda.testing.driver.PortAllocation)
@ -3708,61 +3715,15 @@ public final class net.corda.testing.driver.JmxPolicy extends java.lang.Object
public int hashCode()
public String toString()
##
@net.corda.core.DoNotImplement public abstract class net.corda.testing.driver.NodeHandle extends java.lang.Object implements java.lang.AutoCloseable
public void close()
@org.jetbrains.annotations.NotNull public abstract net.corda.node.services.config.NodeConfiguration getConfiguration()
@net.corda.core.DoNotImplement public interface net.corda.testing.driver.NodeHandle extends java.lang.AutoCloseable
@org.jetbrains.annotations.NotNull public abstract java.nio.file.Path getBaseDirectory()
@org.jetbrains.annotations.NotNull public abstract net.corda.core.node.NodeInfo getNodeInfo()
@org.jetbrains.annotations.NotNull public abstract net.corda.core.utilities.NetworkHostAndPort getP2pAddress()
@org.jetbrains.annotations.NotNull public abstract net.corda.core.messaging.CordaRPCOps getRpc()
public abstract boolean getUseHTTPS()
@org.jetbrains.annotations.NotNull public abstract net.corda.core.utilities.NetworkHostAndPort getWebAddress()
@org.jetbrains.annotations.NotNull public final net.corda.client.rpc.CordaRPCClient rpcClientToNode()
@org.jetbrains.annotations.NotNull public final net.corda.client.rpc.CordaRPCClient rpcClientToNode(net.corda.nodeapi.internal.config.SSLConfiguration)
@org.jetbrains.annotations.NotNull public abstract net.corda.core.utilities.NetworkHostAndPort getRpcAddress()
@org.jetbrains.annotations.NotNull public abstract List getRpcUsers()
public abstract void stop()
##
public static final class net.corda.testing.driver.NodeHandle$InProcess extends net.corda.testing.driver.NodeHandle
public <init>(net.corda.core.node.NodeInfo, net.corda.core.messaging.CordaRPCOps, net.corda.node.services.config.NodeConfiguration, net.corda.core.utilities.NetworkHostAndPort, boolean, net.corda.node.internal.StartedNode, Thread, kotlin.jvm.functions.Function0)
@org.jetbrains.annotations.NotNull public final net.corda.core.node.NodeInfo component1()
@org.jetbrains.annotations.NotNull public final net.corda.core.messaging.CordaRPCOps component2()
@org.jetbrains.annotations.NotNull public final net.corda.node.services.config.NodeConfiguration component3()
@org.jetbrains.annotations.NotNull public final net.corda.core.utilities.NetworkHostAndPort component4()
public final boolean component5()
@org.jetbrains.annotations.NotNull public final net.corda.node.internal.StartedNode component6()
@org.jetbrains.annotations.NotNull public final Thread component7()
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.NodeHandle$InProcess copy(net.corda.core.node.NodeInfo, net.corda.core.messaging.CordaRPCOps, net.corda.node.services.config.NodeConfiguration, net.corda.core.utilities.NetworkHostAndPort, boolean, net.corda.node.internal.StartedNode, Thread, kotlin.jvm.functions.Function0)
public boolean equals(Object)
@org.jetbrains.annotations.NotNull public net.corda.node.services.config.NodeConfiguration getConfiguration()
@org.jetbrains.annotations.NotNull public final net.corda.node.internal.StartedNode getNode()
@org.jetbrains.annotations.NotNull public net.corda.core.node.NodeInfo getNodeInfo()
@org.jetbrains.annotations.NotNull public final Thread getNodeThread()
@org.jetbrains.annotations.NotNull public net.corda.core.messaging.CordaRPCOps getRpc()
public boolean getUseHTTPS()
@org.jetbrains.annotations.NotNull public net.corda.core.utilities.NetworkHostAndPort getWebAddress()
public int hashCode()
public void stop()
public String toString()
##
public static final class net.corda.testing.driver.NodeHandle$OutOfProcess extends net.corda.testing.driver.NodeHandle
public <init>(net.corda.core.node.NodeInfo, net.corda.core.messaging.CordaRPCOps, net.corda.node.services.config.NodeConfiguration, net.corda.core.utilities.NetworkHostAndPort, boolean, Integer, Process, kotlin.jvm.functions.Function0)
@org.jetbrains.annotations.NotNull public final net.corda.core.node.NodeInfo component1()
@org.jetbrains.annotations.NotNull public final net.corda.core.messaging.CordaRPCOps component2()
@org.jetbrains.annotations.NotNull public final net.corda.node.services.config.NodeConfiguration component3()
@org.jetbrains.annotations.NotNull public final net.corda.core.utilities.NetworkHostAndPort component4()
public final boolean component5()
@org.jetbrains.annotations.Nullable public final Integer component6()
@org.jetbrains.annotations.NotNull public final Process component7()
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.NodeHandle$OutOfProcess copy(net.corda.core.node.NodeInfo, net.corda.core.messaging.CordaRPCOps, net.corda.node.services.config.NodeConfiguration, net.corda.core.utilities.NetworkHostAndPort, boolean, Integer, Process, kotlin.jvm.functions.Function0)
public boolean equals(Object)
@org.jetbrains.annotations.NotNull public net.corda.node.services.config.NodeConfiguration getConfiguration()
@org.jetbrains.annotations.Nullable public final Integer getDebugPort()
@org.jetbrains.annotations.NotNull public net.corda.core.node.NodeInfo getNodeInfo()
@org.jetbrains.annotations.NotNull public final Process getProcess()
@org.jetbrains.annotations.NotNull public net.corda.core.messaging.CordaRPCOps getRpc()
public boolean getUseHTTPS()
@org.jetbrains.annotations.NotNull public net.corda.core.utilities.NetworkHostAndPort getWebAddress()
public int hashCode()
public void stop()
public String toString()
##
public final class net.corda.testing.driver.NodeParameters extends java.lang.Object
public <init>()
public <init>(net.corda.core.identity.CordaX500Name, List, net.corda.node.services.config.VerifierType, Map, Boolean, String)
@ -3802,6 +3763,9 @@ public final class net.corda.testing.driver.NotaryHandle extends java.lang.Objec
public int hashCode()
public String toString()
##
@net.corda.core.DoNotImplement public interface net.corda.testing.driver.OutOfProcess extends net.corda.testing.driver.NodeHandle
@org.jetbrains.annotations.NotNull public abstract Process getProcess()
##
@net.corda.core.DoNotImplement public abstract class net.corda.testing.driver.PortAllocation extends java.lang.Object
@org.jetbrains.annotations.NotNull public final net.corda.core.utilities.NetworkHostAndPort nextHostAndPort()
public abstract int nextPort()
@ -3951,143 +3915,67 @@ public final class net.corda.testing.node.MockKeyManagementService extends net.c
public class net.corda.testing.node.MockNetwork extends java.lang.Object
public <init>(List)
public <init>(List, net.corda.testing.node.MockNetworkParameters)
public <init>(List, net.corda.testing.node.MockNetworkParameters, boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, kotlin.jvm.functions.Function1, boolean, List, int)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetwork$MockNode addressToNode(net.corda.core.messaging.MessageRecipients)
public <init>(List, net.corda.testing.node.MockNetworkParameters, boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, boolean, List, int)
@org.jetbrains.annotations.NotNull public final java.nio.file.Path baseDirectory(int)
@org.jetbrains.annotations.NotNull public final net.corda.node.internal.StartedNode createNode(net.corda.testing.node.MockNodeParameters)
@org.jetbrains.annotations.NotNull public final net.corda.node.internal.StartedNode createNode(net.corda.testing.node.MockNodeParameters, kotlin.jvm.functions.Function1)
@org.jetbrains.annotations.NotNull public final net.corda.node.internal.StartedNode createPartyNode()
@org.jetbrains.annotations.NotNull public final net.corda.node.internal.StartedNode createPartyNode(net.corda.core.identity.CordaX500Name)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetwork$MockNode createUnstartedNode(net.corda.testing.node.MockNodeParameters)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetwork$MockNode createUnstartedNode(net.corda.testing.node.MockNodeParameters, kotlin.jvm.functions.Function1)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.StartedMockNode createNode(net.corda.testing.node.MockNodeParameters)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.StartedMockNode createPartyNode(net.corda.core.identity.CordaX500Name)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.UnstartedMockNode createUnstartedNode(net.corda.testing.node.MockNodeParameters)
@org.jetbrains.annotations.NotNull public final List getCordappPackages()
@org.jetbrains.annotations.NotNull public final net.corda.core.identity.Party getDefaultNotaryIdentity()
@org.jetbrains.annotations.NotNull public final net.corda.core.identity.PartyAndCertificate getDefaultNotaryIdentityAndCert()
@org.jetbrains.annotations.NotNull public final net.corda.node.internal.StartedNode getDefaultNotaryNode()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.InMemoryMessagingNetwork getMessagingNetwork()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.StartedMockNode getDefaultNotaryNode()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters getDefaultParameters()
public final boolean getInitialiseSerialization()
public final int getMaxTransactionSize()
public final boolean getNetworkSendManuallyPumped()
public final int getNextNodeId()
@org.jetbrains.annotations.NotNull public final List getNodes()
@org.jetbrains.annotations.NotNull public final List getNotaryNodes()
@org.jetbrains.annotations.NotNull public final List getNotarySpecs()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy getServicePeerAllocationStrategy()
public final boolean getThreadPerNode()
public final void runNetwork()
public final void runNetwork(int)
public final void startNodes()
public final void stopNodes()
public final void waitQuiescent()
##
public static class net.corda.testing.node.MockNetwork$MockNode extends net.corda.node.internal.AbstractNode
public <init>(net.corda.testing.node.MockNodeArgs)
protected int acceptableLiveFiberCountOnStop()
protected void checkNetworkMapIsInitialized()
public final void disableDBCloseOnStop()
@org.jetbrains.annotations.NotNull protected java.security.KeyPair generateKeyPair()
public final int getAcceptableLiveFiberCountOnStop()
@org.jetbrains.annotations.NotNull public final java.math.BigInteger getCounter()
public final int getId()
@org.jetbrains.annotations.NotNull protected org.slf4j.Logger getLog()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetwork getMockNet()
@org.jetbrains.annotations.NotNull protected rx.internal.schedulers.CachedThreadScheduler getRxIoScheduler()
@org.jetbrains.annotations.NotNull public List getSerializationWhitelists()
@org.jetbrains.annotations.NotNull protected net.corda.node.utilities.AffinityExecutor getServerThread()
@org.jetbrains.annotations.Nullable public net.corda.node.internal.StartedNode getStarted()
@org.jetbrains.annotations.NotNull public final List getTestSerializationWhitelists()
protected Object initialiseDatabasePersistence(net.corda.node.services.api.SchemaService, net.corda.core.node.services.IdentityService, kotlin.jvm.functions.Function1)
@org.jetbrains.annotations.NotNull protected net.corda.node.services.transactions.BFTSMaRt$Cluster makeBFTCluster(java.security.PublicKey, net.corda.node.services.config.BFTSMaRtConfiguration)
@org.jetbrains.annotations.NotNull protected net.corda.core.node.services.KeyManagementService makeKeyManagementService(net.corda.node.services.api.IdentityServiceInternal, Set)
@org.jetbrains.annotations.NotNull protected net.corda.node.services.messaging.MessagingService makeMessagingService(net.corda.nodeapi.internal.persistence.CordaPersistence, net.corda.core.node.NodeInfo)
@org.jetbrains.annotations.NotNull protected net.corda.node.services.transactions.InMemoryTransactionVerifierService makeTransactionVerifierService()
public final void manuallyCloseDB()
@org.jetbrains.annotations.NotNull protected List myAddresses()
public final void setAcceptableLiveFiberCountOnStop(int)
public final void setCounter(java.math.BigInteger)
public final void setMessagingServiceSpy(net.corda.testing.node.MessagingServiceSpy)
@org.jetbrains.annotations.NotNull public net.corda.node.internal.StartedNode start()
protected void startMessagingService(net.corda.core.messaging.RPCOps)
public void startShell(net.corda.core.messaging.CordaRPCOps)
public static final net.corda.testing.node.MockNetwork$MockNode$Companion Companion
##
public static final class net.corda.testing.node.MockNetwork$MockNode$Companion extends java.lang.Object
##
public static final class net.corda.testing.node.MockNetwork$MockNode$makeBFTCluster$1 extends java.lang.Object implements net.corda.node.services.transactions.BFTSMaRt$Cluster
public void waitUntilAllReplicasHaveInitialized()
##
public static final class net.corda.testing.node.MockNetwork$NotarySpec extends java.lang.Object
public final class net.corda.testing.node.MockNetworkNotarySpec extends java.lang.Object
public <init>(net.corda.core.identity.CordaX500Name)
public <init>(net.corda.core.identity.CordaX500Name, boolean)
@org.jetbrains.annotations.NotNull public final net.corda.core.identity.CordaX500Name component1()
public final boolean component2()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetwork$NotarySpec copy(net.corda.core.identity.CordaX500Name, boolean)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkNotarySpec copy(net.corda.core.identity.CordaX500Name, boolean)
public boolean equals(Object)
@org.jetbrains.annotations.NotNull public final net.corda.core.identity.CordaX500Name getName()
public final boolean getValidating()
public int hashCode()
public String toString()
##
public static final class net.corda.testing.node.MockNetwork$sharedServerThread$1 extends net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor
public boolean awaitTermination(long, concurrent.TimeUnit)
public void shutdown()
##
public final class net.corda.testing.node.MockNetworkParameters extends java.lang.Object
public <init>()
public <init>(boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, kotlin.jvm.functions.Function1, boolean, List)
public <init>(boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, boolean, List, int)
public final boolean component1()
public final boolean component2()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy component3()
@org.jetbrains.annotations.NotNull public final kotlin.jvm.functions.Function1 component4()
public final boolean component5()
@org.jetbrains.annotations.NotNull public final List component6()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters copy(boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, kotlin.jvm.functions.Function1, boolean, List)
public final boolean component4()
@org.jetbrains.annotations.NotNull public final List component5()
public final int component6()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters copy(boolean, boolean, net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy, boolean, List, int)
public boolean equals(Object)
@org.jetbrains.annotations.NotNull public final kotlin.jvm.functions.Function1 getDefaultFactory()
public final boolean getInitialiseSerialization()
public final int getMaxTransactionSize()
public final boolean getNetworkSendManuallyPumped()
@org.jetbrains.annotations.NotNull public final List getNotarySpecs()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy getServicePeerAllocationStrategy()
public final boolean getThreadPerNode()
public int hashCode()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setDefaultFactory(kotlin.jvm.functions.Function1)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setInitialiseSerialization(boolean)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setMaxTransactionSize(int)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setNetworkSendManuallyPumped(boolean)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setNotarySpecs(List)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setServicePeerAllocationStrategy(net.corda.testing.node.InMemoryMessagingNetwork$ServicePeerAllocationStrategy)
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetworkParameters setThreadPerNode(boolean)
public String toString()
##
public final class net.corda.testing.node.MockNodeArgs extends java.lang.Object
public <init>(net.corda.node.services.config.NodeConfiguration, net.corda.testing.node.MockNetwork, int, java.math.BigInteger, net.corda.node.VersionInfo)
@org.jetbrains.annotations.NotNull public final net.corda.node.services.config.NodeConfiguration component1()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetwork component2()
public final int component3()
@org.jetbrains.annotations.NotNull public final java.math.BigInteger component4()
@org.jetbrains.annotations.NotNull public final net.corda.node.VersionInfo component5()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNodeArgs copy(net.corda.node.services.config.NodeConfiguration, net.corda.testing.node.MockNetwork, int, java.math.BigInteger, net.corda.node.VersionInfo)
public boolean equals(Object)
@org.jetbrains.annotations.NotNull public final net.corda.node.services.config.NodeConfiguration getConfig()
@org.jetbrains.annotations.NotNull public final java.math.BigInteger getEntropyRoot()
public final int getId()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.MockNetwork getNetwork()
@org.jetbrains.annotations.NotNull public final net.corda.node.VersionInfo getVersion()
public int hashCode()
public String toString()
##
public final class net.corda.testing.node.MockNodeKt extends java.lang.Object
@org.jetbrains.annotations.Nullable public static final net.corda.testing.node.InMemoryMessagingNetwork$MessageTransfer pumpReceive(net.corda.node.internal.StartedNode, boolean)
public static final void setMessagingServiceSpy(net.corda.node.internal.StartedNode, net.corda.testing.node.MessagingServiceSpy)
##
@net.corda.core.DoNotImplement public abstract static class net.corda.testing.node.MockNodeKt$mockNodeConfiguration$AbstractNodeConfiguration extends java.lang.Object implements net.corda.node.services.config.NodeConfiguration
public <init>()
public long getAttachmentCacheBound()
public long getAttachmentContentCacheSizeBytes()
@org.jetbrains.annotations.NotNull public java.nio.file.Path getCertificatesDirectory()
public boolean getDetectPublicIp()
public boolean getNoLocalShell()
@org.jetbrains.annotations.NotNull public java.nio.file.Path getNodeKeystore()
@org.jetbrains.annotations.NotNull public java.nio.file.Path getSslKeystore()
public long getTransactionCacheSizeBytes()
@org.jetbrains.annotations.NotNull public java.nio.file.Path getTrustStoreFile()
public boolean getUseTestClock()
@org.jetbrains.annotations.NotNull public net.corda.nodeapi.internal.crypto.X509KeyStore loadNodeKeyStore(boolean)
@org.jetbrains.annotations.NotNull public net.corda.nodeapi.internal.crypto.X509KeyStore loadSslKeyStore(boolean)
@org.jetbrains.annotations.NotNull public net.corda.nodeapi.internal.crypto.X509KeyStore loadTrustStore(boolean)
##
public final class net.corda.testing.node.MockNodeParameters extends java.lang.Object
public <init>()
public <init>(Integer, net.corda.core.identity.CordaX500Name, java.math.BigInteger, kotlin.jvm.functions.Function1, net.corda.node.VersionInfo)
@ -4234,11 +4122,33 @@ public final class net.corda.testing.node.NotarySpec extends java.lang.Object
public int hashCode()
public String toString()
##
public final class net.corda.testing.node.StartedMockNode extends java.lang.Object
@org.jetbrains.annotations.NotNull public final List findStateMachines(Class)
@org.jetbrains.annotations.NotNull public final net.corda.nodeapi.internal.persistence.CordaPersistence getDatabase()
public final int getId()
@org.jetbrains.annotations.NotNull public final net.corda.core.node.NodeInfo getInfo()
@org.jetbrains.annotations.NotNull public final net.corda.node.services.messaging.MessagingService getNetwork()
@org.jetbrains.annotations.NotNull public final net.corda.node.services.api.StartedNodeServices getServices()
@org.jetbrains.annotations.Nullable public final net.corda.testing.node.InMemoryMessagingNetwork$MessageTransfer pumpReceive(boolean)
@org.jetbrains.annotations.NotNull public final rx.Observable registerInitiatedFlow(Class)
public final void setMessagingServiceSpy(net.corda.testing.node.MessagingServiceSpy)
public final void stop()
public static final net.corda.testing.node.StartedMockNode$Companion Companion
##
public static final class net.corda.testing.node.StartedMockNode$Companion extends java.lang.Object
##
@javax.annotation.concurrent.ThreadSafe public final class net.corda.testing.node.TestClock extends net.corda.node.internal.MutableClock
public <init>(java.time.Clock)
public synchronized final void advanceBy(java.time.Duration)
public synchronized final void setTo(java.time.Instant)
##
public final class net.corda.testing.node.UnstartedMockNode extends java.lang.Object
public final int getId()
@org.jetbrains.annotations.NotNull public final net.corda.testing.node.StartedMockNode start()
public static final net.corda.testing.node.UnstartedMockNode$Companion Companion
##
public static final class net.corda.testing.node.UnstartedMockNode$Companion extends java.lang.Object
##
public final class net.corda.testing.node.User extends java.lang.Object
public <init>(String, String, Set)
@org.jetbrains.annotations.NotNull public final String component1()

View File

@ -75,7 +75,7 @@ class NodeMonitorModelTest {
vaultUpdates = monitor.vaultUpdates.bufferUntilSubscribed()
networkMapUpdates = monitor.networkMap.bufferUntilSubscribed()
monitor.register(aliceNodeHandle.configuration.rpcOptions.address!!, cashUser.username, cashUser.password)
monitor.register(aliceNodeHandle.rpcAddress, cashUser.username, cashUser.password)
rpc = monitor.proxyObservable.value!!
notaryParty = defaultNotaryIdentity
@ -83,7 +83,7 @@ class NodeMonitorModelTest {
bobNode = bobNodeHandle.nodeInfo
val monitorBob = NodeMonitorModel()
stateMachineUpdatesBob = monitorBob.stateMachineUpdates.bufferUntilSubscribed()
monitorBob.register(bobNodeHandle.configuration.rpcOptions.address!!, cashUser.username, cashUser.password)
monitorBob.register(bobNodeHandle.rpcAddress, cashUser.username, cashUser.password)
rpcBob = monitorBob.proxyObservable.value!!
runTest()
}

View File

@ -3,9 +3,9 @@ package net.corda.core.flows;
import co.paralleluniverse.fibers.Suspendable;
import com.google.common.primitives.Primitives;
import net.corda.core.identity.Party;
import net.corda.node.internal.StartedNode;
import net.corda.testing.core.TestConstants;
import net.corda.testing.node.MockNetwork;
import net.corda.testing.node.StartedMockNode;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -21,8 +21,8 @@ import static net.corda.testing.node.NodeTestUtils.startFlow;
public class FlowsInJavaTest {
private final MockNetwork mockNet = new MockNetwork(emptyList());
private StartedNode<MockNetwork.MockNode> aliceNode;
private StartedNode<MockNetwork.MockNode> bobNode;
private StartedMockNode aliceNode;
private StartedMockNode bobNode;
private Party bob;
@Before

View File

@ -15,6 +15,7 @@ import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Before
@ -27,11 +28,11 @@ import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
class AttachmentTests {
lateinit var mockNet: MockNetwork
lateinit var mockNet: InternalMockNetwork
@Before
fun setUp() {
mockNet = MockNetwork(emptyList())
mockNet = InternalMockNetwork(emptyList())
}
@After
@ -100,7 +101,7 @@ class AttachmentTests {
fun maliciousResponse() {
// Make a node that doesn't do sanity checking at load time.
val aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME), nodeFactory = { args ->
object : MockNetwork.MockNode(args) {
object : InternalMockNetwork.MockNode(args) {
override fun start() = super.start().apply { attachments.checkAttachmentsOnLoad = false }
}
})

View File

@ -11,11 +11,11 @@ import net.corda.core.identity.groupAbstractPartyByWellKnownParty
import net.corda.core.transactions.SignedTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode
import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.*
import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.StartedMockNode
import net.corda.testing.node.MockServices
import net.corda.testing.node.startFlow
import org.junit.After
@ -30,9 +30,9 @@ class CollectSignaturesFlowTests {
}
private lateinit var mockNet: MockNetwork
private lateinit var aliceNode: StartedNode<MockNetwork.MockNode>
private lateinit var bobNode: StartedNode<MockNetwork.MockNode>
private lateinit var charlieNode: StartedNode<MockNetwork.MockNode>
private lateinit var aliceNode: StartedMockNode
private lateinit var bobNode: StartedMockNode
private lateinit var charlieNode: StartedMockNode
private lateinit var alice: Party
private lateinit var bob: Party
private lateinit var charlie: Party

View File

@ -19,17 +19,14 @@ import net.corda.finance.flows.CashIssueFlow
import net.corda.node.internal.SecureCordaRPCOps
import net.corda.node.internal.StartedNode
import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.node.User
import net.corda.testing.contracts.DummyContract
import net.corda.testing.contracts.DummyContractV2
import net.corda.testing.node.internal.RPCDriverDSL
import net.corda.testing.node.internal.rpcDriver
import net.corda.testing.node.internal.rpcTestUser
import net.corda.testing.node.internal.startRpcClient
import net.corda.testing.node.MockNetwork
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.User
import net.corda.testing.node.internal.*
import net.corda.testing.node.internal.InternalMockNetwork.MockNode
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Before
@ -40,16 +37,16 @@ import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
class ContractUpgradeFlowTest {
private lateinit var mockNet: MockNetwork
private lateinit var aliceNode: StartedNode<MockNetwork.MockNode>
private lateinit var bobNode: StartedNode<MockNetwork.MockNode>
private lateinit var mockNet: InternalMockNetwork
private lateinit var aliceNode: StartedNode<MockNode>
private lateinit var bobNode: StartedNode<MockNode>
private lateinit var notary: Party
private lateinit var alice: Party
private lateinit var bob: Party
@Before
fun setup() {
mockNet = MockNetwork(cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows"))
mockNet = InternalMockNetwork(cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows"))
aliceNode = mockNet.createPartyNode(ALICE_NAME)
bobNode = mockNet.createPartyNode(BOB_NAME)
notary = mockNet.defaultNotaryIdentity
@ -103,7 +100,7 @@ class ContractUpgradeFlowTest {
val result = resultFuture.getOrThrow()
fun check(node: StartedNode<*>) {
fun check(node: StartedNode<MockNode>) {
val nodeStx = node.database.transaction {
node.services.validatedTransactions.getTransaction(result.ref.txhash)
}
@ -123,7 +120,7 @@ class ContractUpgradeFlowTest {
check(bobNode)
}
private fun RPCDriverDSL.startProxy(node: StartedNode<*>, user: User): CordaRPCOps {
private fun RPCDriverDSL.startProxy(node: StartedNode<MockNode>, user: User): CordaRPCOps {
return startRpcClient<CordaRPCOps>(
rpcAddress = startRpcServer(
rpcUser = user,

View File

@ -5,6 +5,8 @@ import net.corda.core.utilities.UntrustworthyData
import net.corda.core.utilities.unwrap
import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.internal.StartedNode
import net.corda.testing.node.StartedMockNode
import net.corda.testing.node.internal.InternalMockNetwork
import kotlin.reflect.KClass
/**
@ -37,14 +39,14 @@ class NoAnswer(private val closure: () -> Unit = {}) : FlowLogic<Unit>() {
/**
* Allows to register a flow of type [R] against an initiating flow of type [I].
*/
inline fun <I : FlowLogic<*>, reified R : FlowLogic<*>> StartedNode<*>.registerInitiatedFlow(initiatingFlowType: KClass<I>, crossinline construct: (session: FlowSession) -> R) {
inline fun <I : FlowLogic<*>, reified R : FlowLogic<*>> StartedNode<InternalMockNetwork.MockNode>.registerInitiatedFlow(initiatingFlowType: KClass<I>, crossinline construct: (session: FlowSession) -> R) {
internalRegisterFlowFactory(initiatingFlowType.java, InitiatedFlowFactory.Core { session -> construct(session) }, R::class.javaObjectType, true)
}
/**
* Allows to register a flow of type [Answer] against an initiating flow of type [I], returning a valure of type [R].
*/
inline fun <I : FlowLogic<*>, reified R : Any> StartedNode<*>.registerAnswer(initiatingFlowType: KClass<I>, value: R) {
inline fun <I : FlowLogic<*>, reified R : Any> StartedNode<InternalMockNetwork.MockNode>.registerAnswer(initiatingFlowType: KClass<I>, value: R) {
internalRegisterFlowFactory(initiatingFlowType.java, InitiatedFlowFactory.Core { session -> Answer(session, value) }, Answer::class.javaObjectType, true)
}

View File

@ -5,15 +5,15 @@ import net.corda.core.identity.Party
import net.corda.core.utilities.UntrustworthyData
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.unwrap
import net.corda.testing.node.MockNetwork
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.startFlow
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Test
class ReceiveMultipleFlowTests {
private val mockNet = MockNetwork(emptyList())
private val mockNet = InternalMockNetwork(emptyList())
private val nodes = (0..2).map { mockNet.createPartyNode() }
@After
fun stopNodes() {

View File

@ -8,10 +8,10 @@ import net.corda.core.identity.Party
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.sequence
import net.corda.node.internal.StartedNode
import net.corda.testing.contracts.DummyContract
import net.corda.testing.node.MockNetwork
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.StartedMockNode
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Before
@ -28,9 +28,9 @@ import kotlin.test.assertNull
// DOCSTART 3
class ResolveTransactionsFlowTest {
private lateinit var mockNet: MockNetwork
private lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
private lateinit var megaCorpNode: StartedNode<MockNetwork.MockNode>
private lateinit var miniCorpNode: StartedNode<MockNetwork.MockNode>
private lateinit var notaryNode: StartedMockNode
private lateinit var megaCorpNode: StartedMockNode
private lateinit var miniCorpNode: StartedMockNode
private lateinit var megaCorp: Party
private lateinit var miniCorp: Party
private lateinit var notary: Party

View File

@ -21,6 +21,7 @@ import net.corda.testing.core.BOB_NAME
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Before
@ -63,14 +64,14 @@ private fun updateAttachment(attachmentId: SecureHash, data: ByteArray) {
}
class AttachmentSerializationTest {
private lateinit var mockNet: MockNetwork
private lateinit var server: StartedNode<MockNetwork.MockNode>
private lateinit var client: StartedNode<MockNetwork.MockNode>
private lateinit var mockNet: InternalMockNetwork
private lateinit var server: StartedNode<InternalMockNetwork.MockNode>
private lateinit var client: StartedNode<InternalMockNetwork.MockNode>
private lateinit var serverIdentity: Party
@Before
fun setUp() {
mockNet = MockNetwork(emptyList())
mockNet = InternalMockNetwork(emptyList())
server = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
client = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
client.internals.disableDBCloseOnStop() // Otherwise the in-memory database may disappear (taking the checkpoint with it) while we reboot the client.
@ -161,7 +162,7 @@ class AttachmentSerializationTest {
private fun rebootClientAndGetAttachmentContent(checkAttachmentsOnLoad: Boolean = true): String {
client.dispose()
client = mockNet.createNode(MockNodeParameters(client.internals.id, client.internals.configuration.myLegalName), { args ->
object : MockNetwork.MockNode(args) {
object : InternalMockNetwork.MockNode(args) {
override fun start() = super.start().apply { attachments.checkAttachmentsOnLoad = checkAttachmentsOnLoad }
}
})

View File

@ -183,6 +183,9 @@ UNRELEASED
* Marked ``stateMachine`` on ``FlowLogic`` as ``CordaInternal`` to make clear that is it not part of the public api and is
only for internal use
* Created new ``StartedMockNode`` and ``UnstartedMockNode`` classes which are wrappers around our MockNode implementation
that expose relevant methods for testing without exposing internals, create these using a ``MockNetwork``.
.. _changelog_v1:
Release 1.0

View File

@ -1,5 +1,6 @@
package net.corda.docs
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.internal.concurrent.transpose
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.startFlow
@ -45,10 +46,10 @@ class IntegrationTestingTutorial {
// END 1
// START 2
val aliceClient = alice.rpcClientToNode()
val aliceClient = CordaRPCClient(alice.rpcAddress)
val aliceProxy = aliceClient.start("aliceUser", "testPassword1").proxy
val bobClient = bob.rpcClientToNode()
val bobClient = CordaRPCClient(bob.rpcAddress)
val bobProxy = bobClient.start("bobUser", "testPassword2").proxy
// END 2

View File

@ -2,6 +2,7 @@
package net.corda.docs
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.contracts.Amount
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.startFlow
@ -53,7 +54,7 @@ fun main(args: Array<String>) {
// END 1
// START 2
val client = node.rpcClientToNode()
val client = CordaRPCClient(node.rpcAddress)
val proxy = client.start("user", "password").proxy
thread {

View File

@ -13,15 +13,10 @@ import net.corda.core.serialization.serialize
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.unwrap
import net.corda.node.internal.StartedNode
import net.corda.node.services.messaging.Message
import net.corda.node.services.statemachine.DataSessionMessage
import net.corda.node.services.statemachine.ExistingSessionMessage
import net.corda.testing.node.InMemoryMessagingNetwork
import net.corda.testing.node.MessagingServiceSpy
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.setMessagingServiceSpy
import net.corda.testing.node.startFlow
import net.corda.testing.node.*
import org.junit.After
import org.junit.Before
import org.junit.Rule
@ -58,8 +53,8 @@ class TutorialMockNetwork {
}
lateinit private var mockNet: MockNetwork
lateinit private var nodeA: StartedNode<MockNetwork.MockNode>
lateinit private var nodeB: StartedNode<MockNetwork.MockNode>
lateinit private var nodeA: StartedMockNode
lateinit private var nodeB: StartedMockNode
@Rule
@JvmField

View File

@ -7,9 +7,9 @@ import net.corda.core.utilities.getOrThrow
import net.corda.finance.*
import net.corda.finance.contracts.getCashBalances
import net.corda.finance.flows.CashIssueFlow
import net.corda.node.internal.StartedNode
import net.corda.testing.core.chooseIdentity
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.StartedMockNode
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Assert
@ -19,8 +19,8 @@ import java.util.*
class CustomVaultQueryTest {
private lateinit var mockNet: MockNetwork
private lateinit var nodeA: StartedNode<MockNetwork.MockNode>
private lateinit var nodeB: StartedNode<MockNetwork.MockNode>
private lateinit var nodeA: StartedMockNode
private lateinit var nodeB: StartedMockNode
private lateinit var notary: Party
@Before

View File

@ -7,9 +7,9 @@ import net.corda.core.utilities.getOrThrow
import net.corda.finance.*
import net.corda.finance.contracts.getCashBalances
import net.corda.finance.flows.CashIssueFlow
import net.corda.node.internal.StartedNode
import net.corda.testing.core.chooseIdentity
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.StartedMockNode
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Before
@ -18,8 +18,8 @@ import kotlin.test.assertEquals
class FxTransactionBuildTutorialTest {
private lateinit var mockNet: MockNetwork
private lateinit var nodeA: StartedNode<MockNetwork.MockNode>
private lateinit var nodeB: StartedNode<MockNetwork.MockNode>
private lateinit var nodeA: StartedMockNode
private lateinit var nodeB: StartedMockNode
private lateinit var notary: Party
@Before

View File

@ -6,11 +6,10 @@ import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS
import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash
import net.corda.node.internal.StartedNode
import net.corda.testing.core.BOC_NAME
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode
import net.corda.testing.node.StartedMockNode
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Before
@ -22,7 +21,7 @@ class CashExitFlowTests {
private lateinit var mockNet: MockNetwork
private val initialBalance = 2000.DOLLARS
private val ref = OpaqueBytes.of(0x01)
private lateinit var bankOfCordaNode: StartedNode<MockNode>
private lateinit var bankOfCordaNode: StartedMockNode
private lateinit var bankOfCorda: Party
private lateinit var notary: Party

View File

@ -6,11 +6,10 @@ import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS
import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash
import net.corda.node.internal.StartedNode
import net.corda.testing.core.BOC_NAME
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode
import net.corda.testing.node.StartedMockNode
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Before
@ -20,7 +19,7 @@ import kotlin.test.assertFailsWith
class CashIssueFlowTests {
private lateinit var mockNet: MockNetwork
private lateinit var bankOfCordaNode: StartedNode<MockNode>
private lateinit var bankOfCordaNode: StartedMockNode
private lateinit var bankOfCorda: Party
private lateinit var notary: Party

View File

@ -9,11 +9,10 @@ import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS
import net.corda.finance.`issued by`
import net.corda.finance.contracts.asset.Cash
import net.corda.node.internal.StartedNode
import net.corda.testing.core.*
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode
import net.corda.testing.node.StartedMockNode
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Before
@ -25,9 +24,9 @@ class CashPaymentFlowTests {
private lateinit var mockNet: MockNetwork
private val initialBalance = 2000.DOLLARS
private val ref = OpaqueBytes.of(0x01)
private lateinit var bankOfCordaNode: StartedNode<MockNode>
private lateinit var bankOfCordaNode: StartedMockNode
private lateinit var bankOfCorda: Party
private lateinit var aliceNode: StartedNode<MockNode>
private lateinit var aliceNode: StartedMockNode
@Before
fun start() {

View File

@ -1,6 +1,7 @@
package net.corda.node
import co.paralleluniverse.fibers.Suspendable
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC
import net.corda.core.internal.div
@ -25,7 +26,7 @@ class BootTests {
fun `java deserialization is disabled`() {
driver {
val user = User("u", "p", setOf(startFlow<ObjectInputStreamFlow>()))
val future = startNode(rpcUsers = listOf(user)).getOrThrow().rpcClientToNode().
val future = CordaRPCClient(startNode(rpcUsers = listOf(user)).getOrThrow().rpcAddress).
start(user.username, user.password).proxy.startFlow(::ObjectInputStreamFlow).returnValue
assertThatThrownBy { future.getOrThrow() }.isInstanceOf(InvalidClassException::class.java).hasMessage("filter status: REJECTED")
}
@ -37,7 +38,7 @@ class BootTests {
assertThat(logConfigFile).isRegularFile()
driver(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString())) {
val alice = startNode(providedName = ALICE_NAME).get()
val logFolder = alice.configuration.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME
val logFolder = alice.baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME
val logFile = logFolder.toFile().listFiles { _, name -> name.endsWith(".log") }.single()
// Start second Alice, should fail
assertThatThrownBy {

View File

@ -1,6 +1,7 @@
package net.corda.node
import co.paralleluniverse.fibers.Suspendable
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.flows.*
import net.corda.core.identity.Party
import net.corda.core.internal.concurrent.transpose
@ -25,7 +26,7 @@ class CordappScanningDriverTest {
val (alice, bob) = listOf(
startNode(providedName = ALICE_NAME, rpcUsers = listOf(user)),
startNode(providedName = BOB_NAME)).transpose().getOrThrow()
val initiatedFlowClass = alice.rpcClientToNode()
val initiatedFlowClass = CordaRPCClient(alice.rpcAddress)
.start(user.username, user.password)
.proxy
.startFlow(::ReceiveFlow, bob.nodeInfo.chooseIdentity())

View File

@ -2,6 +2,7 @@ package net.corda.node
import co.paralleluniverse.fibers.Suspendable
import com.google.common.base.Stopwatch
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC
import net.corda.core.internal.concurrent.transpose
@ -14,19 +15,18 @@ import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.driver.InProcess
import net.corda.testing.node.User
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.driver
import net.corda.testing.internal.performance.div
import net.corda.testing.node.NotarySpec
import net.corda.testing.node.internal.InternalDriverDSL
import net.corda.testing.node.internal.internalDriver
import net.corda.testing.node.internal.performance.startPublishingFixedRateInjector
import net.corda.testing.node.internal.performance.startReporter
import net.corda.testing.node.internal.performance.startTightLoopInjector
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
import java.lang.management.ManagementFactory
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.streams.toList
@ -50,7 +50,7 @@ class NodePerformanceTests {
driver(startNodesInProcess = true) {
val a = startNode(rpcUsers = listOf(User("A", "A", setOf(startFlow<EmptyFlow>())))).get()
a.rpcClientToNode().use("A", "A") { connection ->
CordaRPCClient(a.rpcAddress).use("A", "A") { connection ->
val timings = Collections.synchronizedList(ArrayList<Long>())
val N = 10000
val overallTiming = Stopwatch.createStarted().apply {
@ -77,11 +77,11 @@ class NodePerformanceTests {
@Test
fun `empty flow rate`() {
driver(startNodesInProcess = true) {
internalDriver(startNodesInProcess = true) {
val a = startNode(rpcUsers = listOf(User("A", "A", setOf(startFlow<EmptyFlow>())))).get()
a as NodeHandle.InProcess
val metricRegistry = startReporter((this as InternalDriverDSL).shutdownManager, a.node.services.monitoringService.metrics)
a.rpcClientToNode().use("A", "A") { connection ->
a as InProcess
val metricRegistry = startReporter(this.shutdownManager, a.services.monitoringService.metrics)
CordaRPCClient(a.rpcAddress).use("A", "A") { connection ->
startPublishingFixedRateInjector(metricRegistry, 8, 5.minutes, 2000L / TimeUnit.SECONDS) {
connection.proxy.startFlow(::EmptyFlow).returnValue.get()
}
@ -92,14 +92,14 @@ class NodePerformanceTests {
@Test
fun `self pay rate`() {
val user = User("A", "A", setOf(startFlow<CashIssueFlow>(), startFlow<CashPaymentFlow>()))
driver(
internalDriver(
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, rpcUsers = listOf(user))),
startNodesInProcess = true,
extraCordappPackagesToScan = listOf("net.corda.finance")
) {
val notary = defaultNotaryNode.getOrThrow() as NodeHandle.InProcess
val metricRegistry = startReporter((this as InternalDriverDSL).shutdownManager, notary.node.services.monitoringService.metrics)
notary.rpcClientToNode().use("A", "A") { connection ->
val notary = defaultNotaryNode.getOrThrow() as InProcess
val metricRegistry = startReporter(this.shutdownManager, notary.services.monitoringService.metrics)
CordaRPCClient(notary.rpcAddress).use("A", "A") { connection ->
println("ISSUING")
val doneFutures = (1..100).toList().parallelStream().map {
connection.proxy.startFlow(::CashIssueFlow, 1.DOLLARS, OpaqueBytes.of(0), defaultNotaryIdentity).returnValue

View File

@ -18,7 +18,6 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.Try
import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode
import net.corda.node.services.config.BFTSMaRtConfiguration
import net.corda.node.services.config.NotaryConfig
import net.corda.node.services.transactions.minClusterSize
@ -31,7 +30,7 @@ import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.dummyCommand
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode
import net.corda.testing.node.StartedMockNode
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.startFlow
import org.junit.After
@ -44,7 +43,7 @@ import kotlin.test.assertTrue
class BFTNotaryServiceTests {
private lateinit var mockNet: MockNetwork
private lateinit var notary: Party
private lateinit var node: StartedNode<MockNode>
private lateinit var node: StartedMockNode
@Before
fun before() {
@ -154,7 +153,7 @@ class BFTNotaryServiceTests {
}
}
private fun StartedNode<*>.signInitialTransaction(notary: Party, block: TransactionBuilder.() -> Any?): SignedTransaction {
private fun StartedMockNode.signInitialTransaction(notary: Party, block: TransactionBuilder.() -> Any?): SignedTransaction {
return services.signInitialTransaction(
TransactionBuilder(notary).apply {
addCommand(dummyCommand(services.myInfo.chooseIdentity().owningKey))

View File

@ -1,5 +1,6 @@
package net.corda.node.services
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.contracts.Amount
import net.corda.core.identity.Party
import net.corda.core.internal.bufferUntilSubscribed
@ -15,6 +16,7 @@ import net.corda.node.services.Permissions.Companion.invokeRpc
import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.core.*
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.OutOfProcess
import net.corda.testing.driver.driver
import net.corda.testing.node.NotarySpec
import net.corda.testing.node.User
@ -26,7 +28,7 @@ import java.util.*
class DistributedServiceTests {
private lateinit var alice: NodeHandle
private lateinit var notaryNodes: List<NodeHandle.OutOfProcess>
private lateinit var notaryNodes: List<OutOfProcess>
private lateinit var aliceProxy: CordaRPCOps
private lateinit var raftNotaryIdentity: Party
private lateinit var notaryStateMachines: Observable<Pair<Party, StateMachineUpdate>>
@ -49,7 +51,7 @@ class DistributedServiceTests {
) {
alice = startNode(providedName = ALICE_NAME, rpcUsers = listOf(testUser)).getOrThrow()
raftNotaryIdentity = defaultNotaryIdentity
notaryNodes = defaultNotaryHandle.nodeHandles.getOrThrow().map { it as NodeHandle.OutOfProcess }
notaryNodes = defaultNotaryHandle.nodeHandles.getOrThrow().map { it as OutOfProcess }
assertThat(notaryNodes).hasSize(3)
@ -62,7 +64,7 @@ class DistributedServiceTests {
// Connect to Alice and the notaries
fun connectRpc(node: NodeHandle): CordaRPCOps {
val client = node.rpcClientToNode()
val client = CordaRPCClient(node.rpcAddress)
return client.start("test", "test").proxy
}
aliceProxy = connectRpc(alice)

View File

@ -10,13 +10,12 @@ import net.corda.core.identity.Party
import net.corda.core.internal.concurrent.map
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.chooseIdentity
import net.corda.testing.contracts.DummyContract
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.driver
import net.corda.testing.core.dummyCommand
import net.corda.testing.driver.InProcess
import net.corda.testing.node.ClusterSpec
import net.corda.testing.node.NotarySpec
import net.corda.testing.node.startFlow
@ -35,7 +34,7 @@ class RaftNotaryServiceTests {
extraCordappPackagesToScan = listOf("net.corda.testing.contracts"),
notarySpecs = listOf(NotarySpec(notaryName, cluster = ClusterSpec.Raft(clusterSize = 3)))
) {
val bankA = startNode(providedName = DUMMY_BANK_A_NAME).map { (it as NodeHandle.InProcess).node }.getOrThrow()
val bankA = startNode(providedName = DUMMY_BANK_A_NAME).map { (it as InProcess) }.getOrThrow()
val inputState = issueState(bankA, defaultNotaryIdentity)
val firstTxBuilder = TransactionBuilder(defaultNotaryIdentity)
@ -47,7 +46,7 @@ class RaftNotaryServiceTests {
firstSpend.getOrThrow()
val secondSpendBuilder = TransactionBuilder(defaultNotaryIdentity).withItems(inputState).run {
val dummyState = DummyContract.SingleOwnerState(0, bankA.info.chooseIdentity())
val dummyState = DummyContract.SingleOwnerState(0, bankA.services.myInfo.chooseIdentity())
addOutputState(dummyState, DummyContract.PROGRAM_ID)
addCommand(dummyCommand(bankA.services.myInfo.chooseIdentity().owningKey))
this
@ -61,11 +60,12 @@ class RaftNotaryServiceTests {
}
}
private fun issueState(node: StartedNode<*>, notary: Party): StateAndRef<*> {
return node.database.transaction {
val builder = DummyContract.generateInitial(Random().nextInt(), notary, node.info.chooseIdentity().ref(0))
val stx = node.services.signInitialTransaction(builder)
node.services.recordTransactions(stx)
private fun issueState(nodeHandle: InProcess, notary: Party): StateAndRef<*> {
return nodeHandle.database.transaction {
val builder = DummyContract.generateInitial(Random().nextInt(), notary, nodeHandle.services.myInfo.chooseIdentity().ref(0))
val stx = nodeHandle.services.signInitialTransaction(builder)
nodeHandle.services.recordTransactions(stx)
StateAndRef(builder.outputStates().first(), StateRef(stx.id, 0))
}
}

View File

@ -63,7 +63,7 @@ class NetworkMapTest {
notarySpecs = emptyList()
) {
val alice = startNode(providedName = ALICE_NAME).getOrThrow()
val networkParameters = (alice.configuration.baseDirectory / NETWORK_PARAMS_FILE_NAME)
val networkParameters = (alice.baseDirectory / NETWORK_PARAMS_FILE_NAME)
.readAll()
.deserialize<SignedDataWithCert<NetworkParameters>>()
.verified()
@ -147,7 +147,7 @@ class NetworkMapTest {
private fun NodeHandle.onlySees(vararg nodes: NodeInfo) {
// Make sure the nodes aren't getting the node infos from their additional directories
val nodeInfosDir = configuration.baseDirectory / CordformNode.NODE_INFO_DIRECTORY
val nodeInfosDir = baseDirectory / CordformNode.NODE_INFO_DIRECTORY
if (nodeInfosDir.exists()) {
assertThat(nodeInfosDir.list { it.toList() }).isEmpty()
}

View File

@ -1,5 +1,6 @@
package net.corda.node.services.rpc
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.identity.CordaX500Name
import net.corda.core.utilities.getOrThrow
import net.corda.node.services.Permissions.Companion.all
@ -32,7 +33,7 @@ class RpcSslTest {
var successful = false
driver(isDebug = true, startNodesInProcess = true, portAllocation = PortAllocation.RandomFree) {
startNode(rpcUsers = listOf(user), customOverrides = nodeSslOptions.useSslRpcOverrides()).getOrThrow().use { node ->
node.rpcClientToNode(clientSslOptions).start(user.username, user.password).use { connection ->
CordaRPCClient(node.rpcAddress, sslConfiguration = clientSslOptions).start(user.username, user.password).use { connection ->
connection.proxy.apply {
nodeInfo()
successful = true
@ -51,7 +52,7 @@ class RpcSslTest {
var successful = false
driver(isDebug = true, startNodesInProcess = true, portAllocation = PortAllocation.RandomFree) {
startNode(rpcUsers = listOf(user)).getOrThrow().use { node ->
node.rpcClientToNode().start(user.username, user.password).use { connection ->
CordaRPCClient(node.rpcAddress).start(user.username, user.password).use { connection ->
connection.proxy.apply {
nodeInfo()
successful = true

View File

@ -1,6 +1,7 @@
package net.corda.node.services.statemachine
import co.paralleluniverse.fibers.Suspendable
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.crypto.SecureHash
import net.corda.core.flows.*
import net.corda.core.internal.InputStreamAndHash
@ -73,7 +74,7 @@ class LargeTransactionsTest {
driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.testing.contracts"), portAllocation = PortAllocation.RandomFree) {
val rpcUser = User("admin", "admin", setOf("ALL"))
val (alice, _) = listOf(ALICE_NAME, BOB_NAME).map { startNode(providedName = it, rpcUsers = listOf(rpcUser)) }.transpose().getOrThrow()
alice.rpcClientToNode().use(rpcUser.username, rpcUser.password) {
CordaRPCClient(alice.rpcAddress).use(rpcUser.username, rpcUser.password) {
val hash1 = it.proxy.uploadAttachment(bigFile1.inputStream)
val hash2 = it.proxy.uploadAttachment(bigFile2.inputStream)
val hash3 = it.proxy.uploadAttachment(bigFile3.inputStream)

View File

@ -12,15 +12,13 @@ import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.seconds
import net.corda.node.internal.Node
import net.corda.node.internal.StartedNode
import net.corda.node.services.messaging.MessagingService
import net.corda.node.services.messaging.ReceivedMessage
import net.corda.node.services.messaging.send
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.chooseIdentity
import net.corda.testing.driver.DriverDSL
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.InProcess
import net.corda.testing.driver.driver
import net.corda.testing.node.ClusterSpec
import net.corda.testing.node.NotarySpec
@ -44,13 +42,14 @@ class P2PMessagingTest {
}
}
@Test
fun `distributed service requests are retried if one of the nodes in the cluster goes down without sending a response`() {
startDriverWithDistributedService { distributedServiceNodes ->
val alice = startAlice()
val serviceAddress = alice.services.networkMapCache.run {
val notaryParty = notaryIdentities.randomOrNull()!!
alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!)
alice.services.networkService.getAddressOfParty(getPartyInfo(notaryParty)!!)
}
val responseMessage = "response"
@ -76,7 +75,7 @@ class P2PMessagingTest {
val alice = startAlice()
val serviceAddress = alice.services.networkMapCache.run {
val notaryParty = notaryIdentities.randomOrNull()!!
alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!)
alice.services.networkService.getAddressOfParty(getPartyInfo(notaryParty)!!)
}
val responseMessage = "response"
@ -89,7 +88,7 @@ class P2PMessagingTest {
// Wait until the first request is received
crashingNodes.firstRequestReceived.await()
// Stop alice's node after we ensured that the first request was delivered and ignored.
alice.dispose()
alice.stop()
val numberOfRequestsReceived = crashingNodes.requestsReceived.get()
assertThat(numberOfRequestsReceived).isGreaterThanOrEqualTo(1)
@ -99,7 +98,7 @@ class P2PMessagingTest {
val aliceRestarted = startAlice()
val responseFuture = openFuture<Any>()
aliceRestarted.network.runOnNextMessage("test.response") {
aliceRestarted.services.networkService.runOnNextMessage("test.response") {
responseFuture.set(it.data.deserialize())
}
val response = responseFuture.getOrThrow()
@ -109,15 +108,16 @@ class P2PMessagingTest {
}
}
private fun startDriverWithDistributedService(dsl: DriverDSL.(List<StartedNode<Node>>) -> Unit) {
private fun startDriverWithDistributedService(dsl: DriverDSL.(List<InProcess>) -> Unit) {
driver(startNodesInProcess = true, notarySpecs = listOf(NotarySpec(DISTRIBUTED_SERVICE_NAME, cluster = ClusterSpec.Raft(clusterSize = 2)))) {
dsl(defaultNotaryHandle.nodeHandles.getOrThrow().map { (it as NodeHandle.InProcess).node })
dsl(defaultNotaryHandle.nodeHandles.getOrThrow().map { (it as InProcess) })
}
}
private fun DriverDSL.startAlice(): StartedNode<Node> {
private fun DriverDSL.startAlice(): InProcess {
return startNode(providedName = ALICE_NAME, customOverrides = mapOf("messageRedeliveryDelaySeconds" to 1))
.map { (it as NodeHandle.InProcess).node }
.map { (it as InProcess) }
.getOrThrow()
}
@ -133,7 +133,7 @@ class P2PMessagingTest {
* initially set to true. This may be used to simulate scenarios where nodes receive request messages but crash
* before sending back a response.
*/
private fun simulateCrashingNodes(distributedServiceNodes: List<StartedNode<*>>, responseMessage: String): CrashingNodes {
private fun simulateCrashingNodes(distributedServiceNodes: List<InProcess>, responseMessage: String): CrashingNodes {
val crashingNodes = CrashingNodes(
requestsReceived = AtomicInteger(0),
firstRequestReceived = CountDownLatch(1),
@ -141,8 +141,8 @@ class P2PMessagingTest {
)
distributedServiceNodes.forEach {
val nodeName = it.info.chooseIdentity().name
it.network.addMessageHandler("test.request") { netMessage, _ ->
val nodeName = it.services.myInfo.chooseIdentity().name
it.services.networkService.addMessageHandler("test.request") { netMessage, _ ->
crashingNodes.requestsReceived.incrementAndGet()
crashingNodes.firstRequestReceived.countDown()
// The node which receives the first request will ignore all requests
@ -154,21 +154,21 @@ class P2PMessagingTest {
} else {
println("sending response")
val request = netMessage.data.deserialize<TestRequest>()
val response = it.network.createMessage("test.response", responseMessage.serialize().bytes)
it.network.send(response, request.replyTo)
val response = it.services.networkService.createMessage("test.response", responseMessage.serialize().bytes)
it.services.networkService.send(response, request.replyTo)
}
}
}
return crashingNodes
}
private fun assertAllNodesAreUsed(participatingServiceNodes: List<StartedNode<*>>, serviceName: CordaX500Name, originatingNode: StartedNode<*>) {
private fun assertAllNodesAreUsed(participatingServiceNodes: List<InProcess>, serviceName: CordaX500Name, originatingNode: InProcess) {
// Setup each node in the distributed service to return back it's NodeInfo so that we can know which node is being used
participatingServiceNodes.forEach { node ->
node.respondWith(node.info)
node.respondWith(node.services.myInfo)
}
val serviceAddress = originatingNode.services.networkMapCache.run {
originatingNode.network.getAddressOfParty(getPartyInfo(getNotary(serviceName)!!)!!)
originatingNode.services.networkService.getAddressOfParty(getPartyInfo(getNotary(serviceName)!!)!!)
}
val participatingNodes = HashSet<Any>()
// Try several times so that we can be fairly sure that any node not participating is not due to Artemis' selection
@ -180,23 +180,23 @@ class P2PMessagingTest {
break
}
}
assertThat(participatingNodes).containsOnlyElementsOf(participatingServiceNodes.map(StartedNode<*>::info))
assertThat(participatingNodes).containsOnlyElementsOf(participatingServiceNodes.map { it.services.myInfo })
}
private fun StartedNode<*>.respondWith(message: Any) {
network.addMessageHandler("test.request") { netMessage, _ ->
private fun InProcess.respondWith(message: Any) {
services.networkService.addMessageHandler("test.request") { netMessage, _ ->
val request = netMessage.data.deserialize<TestRequest>()
val response = network.createMessage("test.response", message.serialize().bytes)
network.send(response, request.replyTo)
val response = services.networkService.createMessage("test.response", message.serialize().bytes)
services.networkService.send(response, request.replyTo)
}
}
private fun StartedNode<*>.receiveFrom(target: MessageRecipients, retryId: Long? = null): CordaFuture<Any> {
private fun InProcess.receiveFrom(target: MessageRecipients, retryId: Long? = null): CordaFuture<Any> {
val response = openFuture<Any>()
network.runOnNextMessage("test.response") { netMessage ->
services.networkService.runOnNextMessage("test.response") { netMessage ->
response.set(netMessage.data.deserialize())
}
network.send("test.request", TestRequest(replyTo = network.myAddress), target, retryId = retryId)
services.networkService.send("test.request", TestRequest(replyTo = services.networkService.myAddress), target, retryId = retryId)
return response
}

View File

@ -1,6 +1,7 @@
package net.corda.test.node
import co.paralleluniverse.fibers.Suspendable
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.contracts.*
import net.corda.core.flows.FinalityFlow
import net.corda.core.flows.FlowLogic
@ -47,7 +48,7 @@ class NodeStatePersistenceTests {
val nodeName = nodeHandle.nodeInfo.chooseIdentity().name
// Ensure the notary node has finished starting up, before starting a flow that needs a notary
defaultNotaryNode.getOrThrow()
nodeHandle.rpcClientToNode().start(user.username, user.password).use {
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
it.proxy.startFlow(::SendMessageFlow, message, defaultNotaryIdentity).returnValue.getOrThrow()
}
nodeHandle.stop()
@ -55,7 +56,7 @@ class NodeStatePersistenceTests {
}()
val nodeHandle = startNode(providedName = nodeName, rpcUsers = listOf(user)).getOrThrow()
val result = nodeHandle.rpcClientToNode().start(user.username, user.password).use {
val result = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
val page = it.proxy.vaultQuery(MessageState::class.java)
page.states.singleOrNull()
}
@ -81,7 +82,7 @@ class NodeStatePersistenceTests {
val nodeName = nodeHandle.nodeInfo.chooseIdentity().name
// Ensure the notary node has finished starting up, before starting a flow that needs a notary
defaultNotaryNode.getOrThrow()
nodeHandle.rpcClientToNode().start(user.username, user.password).use {
CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
it.proxy.startFlow(::SendMessageFlow, message, defaultNotaryIdentity).returnValue.getOrThrow()
}
nodeHandle.stop()
@ -89,7 +90,7 @@ class NodeStatePersistenceTests {
}()
val nodeHandle = startNode(providedName = nodeName, rpcUsers = listOf(user), customOverrides = mapOf("devMode" to "false")).getOrThrow()
val result = nodeHandle.rpcClientToNode().start(user.username, user.password).use {
val result = CordaRPCClient(nodeHandle.rpcAddress).start(user.username, user.password).use {
val page = it.proxy.vaultQuery(MessageState::class.java)
page.states.singleOrNull()
}

View File

@ -37,9 +37,9 @@ import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.expect
import net.corda.testing.core.expectEvents
import net.corda.testing.core.sequence
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.InternalMockNetwork.MockNode
import net.corda.testing.node.testActor
import org.apache.commons.io.IOUtils
import org.assertj.core.api.Assertions.assertThatExceptionOfType
@ -68,7 +68,7 @@ class CordaRPCOpsImplTest {
val testJar = "net/corda/node/testing/test.jar"
}
private lateinit var mockNet: MockNetwork
private lateinit var mockNet: InternalMockNetwork
private lateinit var aliceNode: StartedNode<MockNode>
private lateinit var alice: Party
private lateinit var notary: Party
@ -79,7 +79,7 @@ class CordaRPCOpsImplTest {
@Before
fun setup() {
mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset"))
mockNet = InternalMockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset"))
aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
rpc = SecureCordaRPCOps(aliceNode.services, aliceNode.smm, aliceNode.database, aliceNode.services)
CURRENT_RPC_CONTEXT.set(RpcAuthContext(InvocationContext.rpc(testActor()), buildSubject("TEST_USER", emptySet())))

View File

@ -15,6 +15,7 @@ import net.corda.finance.DOLLARS
import net.corda.finance.flows.CashIssueFlow
import net.corda.node.internal.cordapp.DummyRPCFlow
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.StartedMockNode
import org.junit.After
import org.junit.Before
import org.junit.Test
@ -75,7 +76,7 @@ class LegacyCordaService(@Suppress("UNUSED_PARAMETER") simpleServiceHub: Service
class CordaServiceTest {
private lateinit var mockNet: MockNetwork
private lateinit var nodeA: StartedNode<MockNetwork.MockNode>
private lateinit var nodeA: StartedMockNode
@Before
fun start() {

View File

@ -27,7 +27,7 @@ class NetworkParametersTest {
private val mockNet = MockNetwork(
emptyList(),
MockNetworkParameters(networkSendManuallyPumped = true),
notarySpecs = listOf(MockNetwork.NotarySpec(DUMMY_NOTARY_NAME)))
notarySpecs = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME)))
@After
fun tearDown() {

View File

@ -48,6 +48,8 @@ import net.corda.testing.dsl.TestTransactionDSLInterpreter
import net.corda.testing.internal.rigorousMock
import net.corda.testing.internal.vault.VaultFiller
import net.corda.testing.node.*
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.pumpReceive
import org.assertj.core.api.Assertions.assertThat
import org.junit.After
import org.junit.Before
@ -83,7 +85,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
private val DUMMY_NOTARY get() = dummyNotary.party
}
private lateinit var mockNet: MockNetwork
private lateinit var mockNet: InternalMockNetwork
@Before
fun before() {
@ -101,7 +103,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
// We run this in parallel threads to help catch any race conditions that may exist. The other tests
// we run in the unit test thread exclusively to speed things up, ensure deterministic results and
// allow interruption half way through.
mockNet = MockNetwork(threadPerNode = true, cordappPackages = cordappPackages)
mockNet = InternalMockNetwork(threadPerNode = true, cordappPackages = cordappPackages)
val ledgerIdentityService = rigorousMock<IdentityServiceInternal>()
MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) {
val notaryNode = mockNet.defaultNotaryNode
@ -153,7 +155,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
@Test(expected = InsufficientBalanceException::class)
fun `trade cash for commercial paper fails using soft locking`() {
mockNet = MockNetwork(threadPerNode = true, cordappPackages = cordappPackages)
mockNet = InternalMockNetwork(threadPerNode = true, cordappPackages = cordappPackages)
val ledgerIdentityService = rigorousMock<IdentityServiceInternal>()
MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) {
val notaryNode = mockNet.defaultNotaryNode
@ -211,7 +213,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
@Test
fun `shutdown and restore`() {
mockNet = MockNetwork(cordappPackages = cordappPackages)
mockNet = InternalMockNetwork(cordappPackages = cordappPackages)
val ledgerIdentityService = rigorousMock<IdentityServiceInternal>()
MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) {
val notaryNode = mockNet.defaultNotaryNode
@ -308,11 +310,10 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
// Creates a mock node with an overridden storage service that uses a RecordingMap, that lets us test the order
// of gets and puts.
private fun makeNodeWithTracking(
name: CordaX500Name): StartedNode<MockNetwork.MockNode> {
private fun makeNodeWithTracking(name: CordaX500Name): StartedNode<InternalMockNetwork.MockNode> {
// Create a node in the mock network ...
return mockNet.createNode(MockNodeParameters(legalName = name), nodeFactory = { args ->
object : MockNetwork.MockNode(args) {
object : InternalMockNetwork.MockNode(args) {
// That constructs a recording tx storage
override fun makeTransactionStorage(database: CordaPersistence, transactionCacheSizeBytes: Long): WritableTransactionStorage {
return RecordingTransactionStorage(database, super.makeTransactionStorage(database, transactionCacheSizeBytes))
@ -323,7 +324,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
@Test
fun `check dependencies of sale asset are resolved`() {
mockNet = MockNetwork(cordappPackages = cordappPackages)
mockNet = InternalMockNetwork(cordappPackages = cordappPackages)
val notaryNode = mockNet.defaultNotaryNode
val aliceNode = makeNodeWithTracking(ALICE_NAME)
val bobNode = makeNodeWithTracking(BOB_NAME)
@ -427,7 +428,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
@Test
fun `track works`() {
mockNet = MockNetwork(cordappPackages = cordappPackages)
mockNet = InternalMockNetwork(cordappPackages = cordappPackages)
val notaryNode = mockNet.defaultNotaryNode
val aliceNode = makeNodeWithTracking(ALICE_NAME)
val bobNode = makeNodeWithTracking(BOB_NAME)
@ -505,7 +506,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
@Test
fun `dependency with error on buyer side`() {
mockNet = MockNetwork(cordappPackages = cordappPackages)
mockNet = InternalMockNetwork(cordappPackages = cordappPackages)
val ledgerIdentityService = rigorousMock<IdentityServiceInternal>()
MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) {
runWithError(ledgerIdentityService, true, false, "at least one cash input")
@ -514,7 +515,7 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
@Test
fun `dependency with error on seller side`() {
mockNet = MockNetwork(cordappPackages = cordappPackages)
mockNet = InternalMockNetwork(cordappPackages = cordappPackages)
val ledgerIdentityService = rigorousMock<IdentityServiceInternal>()
MockServices(cordappPackages, ledgerIdentityService, MEGA_CORP.name).ledger(DUMMY_NOTARY) {
runWithError(ledgerIdentityService, false, true, "Issuances have a time-window")
@ -530,8 +531,8 @@ class TwoPartyTradeFlowTests(private val anonymous: Boolean) {
private fun runBuyerAndSeller(notary: Party,
buyer: Party,
sellerNode: StartedNode<MockNetwork.MockNode>,
buyerNode: StartedNode<MockNetwork.MockNode>,
sellerNode: StartedNode<InternalMockNetwork.MockNode>,
buyerNode: StartedNode<InternalMockNetwork.MockNode>,
assetToSell: StateAndRef<OwnableState>): RunResult {
val buyerFlows: Observable<out FlowLogic<*>> = buyerNode.registerInitiatedFlow(BuyerAcceptor::class.java)
val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine }

View File

@ -12,13 +12,9 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.core.transactions.WireTransaction
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.seconds
import net.corda.node.internal.StartedNode
import net.corda.testing.contracts.DummyContract
import net.corda.testing.core.*
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.NotarySpec
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.startFlow
import net.corda.testing.node.*
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.After
import org.junit.Before
@ -30,9 +26,9 @@ import kotlin.test.assertTrue
class NotaryChangeTests {
private lateinit var mockNet: MockNetwork
private lateinit var oldNotaryNode: StartedNode<MockNetwork.MockNode>
private lateinit var clientNodeA: StartedNode<MockNetwork.MockNode>
private lateinit var clientNodeB: StartedNode<MockNetwork.MockNode>
private lateinit var oldNotaryNode: StartedMockNode
private lateinit var clientNodeA: StartedMockNode
private lateinit var clientNodeB: StartedMockNode
private lateinit var newNotaryParty: Party
private lateinit var oldNotaryParty: Party
private lateinit var clientA: Party
@ -41,7 +37,7 @@ class NotaryChangeTests {
fun setUp() {
val oldNotaryName = CordaX500Name("Regulator A", "Paris", "FR")
mockNet = MockNetwork(
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME), NotarySpec(oldNotaryName)),
notarySpecs = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME), MockNetworkNotarySpec(oldNotaryName)),
cordappPackages = listOf("net.corda.testing.contracts")
)
clientNodeA = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
@ -145,7 +141,7 @@ class NotaryChangeTests {
assertEquals(issued.state, changedNotaryBack.state)
}
private fun changeNotary(movedState: StateAndRef<DummyContract.SingleOwnerState>, node: StartedNode<*>, newNotary: Party): StateAndRef<DummyContract.SingleOwnerState> {
private fun changeNotary(movedState: StateAndRef<DummyContract.SingleOwnerState>, node: StartedMockNode, newNotary: Party): StateAndRef<DummyContract.SingleOwnerState> {
val flow = NotaryChangeFlow(movedState, newNotary)
val future = node.services.startFlow(flow)
mockNet.runNetwork()
@ -153,7 +149,7 @@ class NotaryChangeTests {
return future.getOrThrow()
}
private fun moveState(state: StateAndRef<DummyContract.SingleOwnerState>, fromNode: StartedNode<*>, toNode: StartedNode<*>): StateAndRef<DummyContract.SingleOwnerState> {
private fun moveState(state: StateAndRef<DummyContract.SingleOwnerState>, fromNode: StartedMockNode, toNode: StartedMockNode): StateAndRef<DummyContract.SingleOwnerState> {
val tx = DummyContract.move(state, toNode.info.chooseIdentity())
val stx = fromNode.services.signInitialTransaction(tx)
@ -203,7 +199,7 @@ fun issueState(services: ServiceHub, nodeIdentity: Party, notaryIdentity: Party)
return stx.tx.outRef(0)
}
fun issueMultiPartyState(nodeA: StartedNode<*>, nodeB: StartedNode<*>, notaryNode: StartedNode<*>, notaryIdentity: Party): StateAndRef<DummyContract.MultiOwnerState> {
fun issueMultiPartyState(nodeA: StartedMockNode, nodeB: StartedMockNode, notaryNode: StartedMockNode, notaryIdentity: Party): StateAndRef<DummyContract.MultiOwnerState> {
val participants = listOf(nodeA.info.chooseIdentity(), nodeB.info.chooseIdentity())
val state = TransactionState(
DummyContract.MultiOwnerState(0, participants),

View File

@ -25,8 +25,9 @@ import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.dummyCommand
import net.corda.testing.core.singleIdentity
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.InternalMockNetwork.MockNode
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Assert.*
@ -42,9 +43,9 @@ class ScheduledFlowTests {
val SORTING = Sort(listOf(Sort.SortColumn(SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF_TXN_ID), Sort.Direction.DESC)))
}
private lateinit var mockNet: MockNetwork
private lateinit var aliceNode: StartedNode<MockNetwork.MockNode>
private lateinit var bobNode: StartedNode<MockNetwork.MockNode>
private lateinit var mockNet: InternalMockNetwork
private lateinit var aliceNode: StartedNode<MockNode>
private lateinit var bobNode: StartedNode<MockNode>
private lateinit var notary: Party
private lateinit var alice: Party
private lateinit var bob: Party
@ -102,7 +103,7 @@ class ScheduledFlowTests {
@Before
fun setup() {
mockNet = MockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.testing.contracts"))
mockNet = InternalMockNetwork(threadPerNode = true, cordappPackages = listOf("net.corda.testing.contracts"))
aliceNode = mockNet.createNode(MockNodeParameters(legalName = ALICE_NAME))
bobNode = mockNet.createNode(MockNodeParameters(legalName = BOB_NAME))
notary = mockNet.defaultNotaryIdentity

View File

@ -11,7 +11,7 @@ import net.corda.core.utilities.getOrThrow
import net.corda.node.services.api.ServiceHubInternal
import net.corda.node.services.schema.NodeSchemaService.NodeCoreV1
import net.corda.node.services.schema.NodeSchemaService.NodeNotaryV1
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.InProcess
import net.corda.testing.driver.driver
import net.corda.testing.internal.vault.DummyLinearStateSchemaV1
import net.corda.testing.node.MockNetwork
@ -26,7 +26,7 @@ import kotlin.test.assertTrue
class NodeSchemaServiceTest {
/**
* Note: this test requires explicitly registering custom contract schemas with a MockNode
* Note: this test requires explicitly registering custom contract schemas with a StartedMockNode
*/
@Test
fun `registering custom schemas for testing with MockNode`() {
@ -79,7 +79,7 @@ class NodeSchemaServiceTest {
fun `custom schemas are loaded eagerly`() {
val expected = setOf("PARENTS", "CHILDREN")
val tables = driver(startNodesInProcess = true) {
(defaultNotaryNode.getOrThrow() as NodeHandle.InProcess).node.database.transaction {
(defaultNotaryNode.getOrThrow() as InProcess).database.transaction {
session.createNativeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES").list()
}
}

View File

@ -34,11 +34,11 @@ import net.corda.testing.core.*
import net.corda.testing.internal.LogHelper
import net.corda.testing.node.InMemoryMessagingNetwork.MessageTransfer
import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNetwork.MockNode
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.InternalMockNetwork.MockNode
import net.corda.testing.node.internal.pumpReceive
import net.corda.testing.node.internal.startFlow
import net.corda.testing.node.pumpReceive
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType
@ -62,7 +62,7 @@ class FlowFrameworkTests {
}
}
private lateinit var mockNet: MockNetwork
private lateinit var mockNet: InternalMockNetwork
private val receivedSessionMessages = ArrayList<SessionTransfer>()
private lateinit var aliceNode: StartedNode<MockNode>
private lateinit var bobNode: StartedNode<MockNode>
@ -76,7 +76,7 @@ class FlowFrameworkTests {
@Before
fun start() {
mockNet = MockNetwork(
mockNet = InternalMockNetwork(
servicePeerAllocationStrategy = RoundRobin(),
cordappPackages = listOf("net.corda.finance.contracts", "net.corda.testing.contracts")
)
@ -145,7 +145,7 @@ class FlowFrameworkTests {
val restoredFlow = bobNode.restartAndGetRestoredFlow<InitiatedReceiveFlow>()
assertThat(restoredFlow.receivedPayloads[0]).isEqualTo("Hello")
}
@Test
fun `flow loaded from checkpoint will respond to messages from before start`() {
aliceNode.registerFlowFactory(ReceiveFlow::class) { InitiatedSendFlow("Hello", it) }

View File

@ -30,6 +30,7 @@ import net.corda.testing.core.chooseIdentity
import net.corda.testing.node.MockNetwork
import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Test
@ -38,7 +39,7 @@ import java.util.concurrent.atomic.AtomicBoolean
import kotlin.reflect.jvm.jvmName
import kotlin.test.assertEquals
class NodePair(private val mockNet: MockNetwork) {
class NodePair(private val mockNet: InternalMockNetwork) {
private class ServerLogic(private val session: FlowSession, private val running: AtomicBoolean) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
@ -81,8 +82,8 @@ class VaultSoftLockManagerTest {
private val mockVault = rigorousMock<VaultServiceInternal>().also {
doNothing().whenever(it).softLockRelease(any(), anyOrNull())
}
private val mockNet = MockNetwork(cordappPackages = listOf(ContractImpl::class.packageName), defaultFactory = { args ->
object : MockNetwork.MockNode(args) {
private val mockNet = InternalMockNetwork(cordappPackages = listOf(ContractImpl::class.packageName), defaultFactory = { args ->
object : InternalMockNetwork.MockNode(args) {
override fun makeVaultService(keyManagementService: KeyManagementService, stateLoader: StateLoader, hibernateConfig: HibernateConfiguration): VaultServiceInternal {
val realVault = super.makeVaultService(keyManagementService, stateLoader, hibernateConfig)
return object : VaultServiceInternal by realVault {

View File

@ -1,5 +1,6 @@
package net.corda.attachmentdemo
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.utilities.getOrThrow
import net.corda.node.services.Permissions.Companion.invokeRpc
@ -9,6 +10,7 @@ import net.corda.testing.core.DUMMY_BANK_B_NAME
import net.corda.testing.node.User
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.driver
import net.corda.testing.driver.internal.NodeHandleInternal
import org.junit.Test
import java.util.concurrent.CompletableFuture.supplyAsync
@ -30,17 +32,17 @@ class AttachmentDemoTest {
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = demoUser, maximumHeapSize = "1g"),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = demoUser, maximumHeapSize = "1g")
).map { it.getOrThrow() }
startWebserver(nodeB).getOrThrow()
val webserverHandle = startWebserver(nodeB).getOrThrow()
val senderThread = supplyAsync {
nodeA.rpcClientToNode().start(demoUser[0].username, demoUser[0].password).use {
CordaRPCClient(nodeA.rpcAddress).start(demoUser[0].username, demoUser[0].password).use {
sender(it.proxy, numOfExpectedBytes)
}
}
val recipientThread = supplyAsync {
nodeB.rpcClientToNode().start(demoUser[0].username, demoUser[0].password).use {
recipient(it.proxy, nodeB.webAddress.port)
CordaRPCClient(nodeB.rpcAddress).start(demoUser[0].username, demoUser[0].password).use {
recipient(it.proxy, webserverHandle.listenAddress.port)
}
}

View File

@ -1,5 +1,6 @@
package net.corda.bank
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.startFlow
import net.corda.core.node.services.Vault
@ -37,11 +38,11 @@ class BankOfCordaRPCClientTest {
).map { it.getOrThrow() }
// Bank of Corda RPC Client
val bocClient = nodeBankOfCorda.rpcClientToNode()
val bocClient = CordaRPCClient(nodeBankOfCorda.rpcAddress)
val bocProxy = bocClient.start("bocManager", "password1").proxy
// Big Corporation RPC Client
val bigCorpClient = nodeBigCorporation.rpcClientToNode()
val bigCorpClient = CordaRPCClient(nodeBigCorporation.rpcAddress)
val bigCorpProxy = bigCorpClient.start("bigCorpCFO", "password2").proxy
// Register for Bank of Corda Vault updates

View File

@ -15,6 +15,7 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.messaging.vaultTrackBy
import net.corda.core.toFuture
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.seconds
@ -78,7 +79,7 @@ class IRSDemoTest {
registerIRSModule(mapper)
HttpApi.fromHostAndPort(it.second, "api/irs", mapper = mapper)
}
val nextFixingDates = getFixingDateObservable(nodeA.configuration)
val nextFixingDates = getFixingDateObservable(nodeA.rpcAddress)
val numADeals = getTradeCount(nodeAApi)
val numBDeals = getTradeCount(nodeBApi)
@ -102,8 +103,8 @@ class IRSDemoTest {
return getTrades(nodeApi)[0].calculation.floatingLegPaymentSchedule.count { it.value.rate.ratioUnit != null }
}
private fun getFixingDateObservable(config: NodeConfiguration): Observable<LocalDate?> {
val client = CordaRPCClient(config.rpcOptions.address!!)
private fun getFixingDateObservable(address: NetworkHostAndPort): Observable<LocalDate?> {
val client = CordaRPCClient(address)
val proxy = client.start("user", "password").proxy
val vaultUpdates = proxy.vaultTrackBy<InterestRateSwap.State>().updates

View File

@ -7,6 +7,7 @@ import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.WebserverHandle
import net.corda.testing.driver.internal.NodeHandleInternal
import net.corda.testing.node.NotarySpec
import net.corda.testing.node.internal.*
import okhttp3.OkHttpClient
@ -68,12 +69,12 @@ data class SpringBootDriverDSL(private val driverDSL: DriverDSLImpl) : InternalD
val debugPort = if (driverDSL.isDebug) driverDSL.debugPortAllocation.nextPort() else null
val process = startApplication(handle, debugPort, clazz)
driverDSL.shutdownManager.registerProcessShutdown(process)
val webReadyFuture = addressMustBeBoundFuture(driverDSL.executorService, handle.webAddress, process)
val webReadyFuture = addressMustBeBoundFuture(driverDSL.executorService, (handle as NodeHandleInternal).webAddress, process)
return webReadyFuture.map { queryWebserver(handle, process, checkUrl) }
}
private fun queryWebserver(handle: NodeHandle, process: Process, checkUrl: String): WebserverHandle {
val protocol = if (handle.useHTTPS) "https://" else "http://"
val protocol = if ((handle as NodeHandleInternal).useHTTPS) "https://" else "http://"
val url = URL(URL("$protocol${handle.webAddress}"), checkUrl)
val client = OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).build()
@ -102,19 +103,19 @@ data class SpringBootDriverDSL(private val driverDSL: DriverDSLImpl) : InternalD
className = className, // cannot directly get class for this, so just use string
jdwpPort = debugPort,
extraJvmArguments = listOf(
"-Dname=node-${handle.configuration.p2pAddress}-webserver",
"-Dname=node-${handle.p2pAddress}-webserver",
"-Djava.io.tmpdir=${System.getProperty("java.io.tmpdir")}"
// Inherit from parent process
),
classpath = ProcessUtilities.defaultClassPath,
workingDirectory = handle.configuration.baseDirectory,
workingDirectory = handle.baseDirectory,
errorLogPath = Paths.get("error.$className.log"),
arguments = listOf(
"--base-directory", handle.configuration.baseDirectory.toString(),
"--server.port=${handle.webAddress.port}",
"--corda.host=${handle.configuration.rpcOptions.address}",
"--corda.user=${handle.configuration.rpcUsers.first().username}",
"--corda.password=${handle.configuration.rpcUsers.first().password}"
"--base-directory", handle.baseDirectory.toString(),
"--server.port=${(handle as NodeHandleInternal).webAddress.port}",
"--corda.host=${handle.rpcAddress}",
"--corda.user=${handle.rpcUsers.first().username}",
"--corda.password=${handle.rpcUsers.first().password}"
),
maximumHeapSize = null
)

View File

@ -19,6 +19,7 @@ import net.corda.node.services.statemachine.*
import net.corda.testing.core.chooseIdentity
import net.corda.testing.node.InMemoryMessagingNetwork
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.internal.InternalMockNetwork
import rx.Scheduler
import rx.schedulers.Schedulers
import java.time.format.DateTimeFormatter
@ -105,8 +106,8 @@ class NetworkMapVisualiser : Application() {
}
// Fire the message bullets between nodes.
simulation.mockNet.messagingNetwork.sentMessages.observeOn(uiThread).subscribe { msg: InMemoryMessagingNetwork.MessageTransfer ->
val senderNode: MockNetwork.MockNode = simulation.mockNet.addressToNode(msg.sender)
val destNode: MockNetwork.MockNode = simulation.mockNet.addressToNode(msg.recipients)
val senderNode: InternalMockNetwork.MockNode = simulation.mockNet.addressToNode(msg.sender)
val destNode: InternalMockNetwork.MockNode = simulation.mockNet.addressToNode(msg.recipients)
if (transferIsInteresting(msg)) {
viewModel.nodesToWidgets[senderNode]!!.pulseAnim.play()
@ -114,7 +115,7 @@ class NetworkMapVisualiser : Application() {
}
}
// Pulse all parties in a trade when the trade completes
simulation.doneSteps.observeOn(uiThread).subscribe { nodes: Collection<MockNetwork.MockNode> ->
simulation.doneSteps.observeOn(uiThread).subscribe { nodes: Collection<InternalMockNetwork.MockNode> ->
nodes.forEach { viewModel.nodesToWidgets[it]!!.longPulseAnim.play() }
}

View File

@ -13,7 +13,7 @@ import net.corda.finance.utils.ScreenCoordinate
import net.corda.netmap.simulation.IRSSimulation
import net.corda.netmap.simulation.place
import net.corda.testing.core.chooseIdentity
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.internal.InternalMockNetwork
import java.util.*
class VisualiserViewModel {
@ -25,10 +25,10 @@ class VisualiserViewModel {
}
}
inner class NodeWidget(val node: MockNetwork.MockNode, val innerDot: Circle, val outerDot: Circle, val longPulseDot: Circle,
inner class NodeWidget(val node: InternalMockNetwork.MockNode, val innerDot: Circle, val outerDot: Circle, val longPulseDot: Circle,
val pulseAnim: Animation, val longPulseAnim: Animation,
val nameLabel: Label, val statusLabel: Label) {
fun position(nodeCoords: (node: MockNetwork.MockNode) -> ScreenCoordinate) {
fun position(nodeCoords: (node: InternalMockNetwork.MockNode) -> ScreenCoordinate) {
val (x, y) = nodeCoords(node)
innerDot.centerX = x
innerDot.centerY = y
@ -47,7 +47,7 @@ class VisualiserViewModel {
val trackerBoxes = HashMap<ProgressTracker, TrackerWidget>()
val doneTrackers = ArrayList<ProgressTracker>()
val nodesToWidgets = HashMap<MockNetwork.MockNode, NodeWidget>()
val nodesToWidgets = HashMap<InternalMockNetwork.MockNode, NodeWidget>()
var bankCount: Int = 0
var serviceCount: Int = 0
@ -78,7 +78,7 @@ class VisualiserViewModel {
}
}
fun nodeMapCoords(node: MockNetwork.MockNode): ScreenCoordinate {
fun nodeMapCoords(node: InternalMockNetwork.MockNode): ScreenCoordinate {
// For an image of the whole world, we use:
// return node.place.coordinate.project(mapImage.fitWidth, mapImage.fitHeight, 85.0511, -85.0511, -180.0, 180.0)
@ -128,7 +128,7 @@ class VisualiserViewModel {
}
}
fun makeNodeWidget(forNode: MockNetwork.MockNode, type: String, label: CordaX500Name = CordaX500Name(organisation = "Bank of Bologna", locality = "Bologna", country = "IT"),
fun makeNodeWidget(forNode: InternalMockNetwork.MockNode, type: String, label: CordaX500Name = CordaX500Name(organisation = "Bank of Bologna", locality = "Bologna", country = "IT"),
nodeType: NetworkMapVisualiser.NodeType, index: Int): NodeWidget {
fun emitRadarPulse(initialRadius: Double, targetRadius: Double, duration: Double): Pair<Circle, Animation> {
val pulse = Circle(initialRadius).apply {
@ -180,7 +180,7 @@ class VisualiserViewModel {
return widget
}
fun fireBulletBetweenNodes(senderNode: MockNetwork.MockNode, destNode: MockNetwork.MockNode, startType: String, endType: String) {
fun fireBulletBetweenNodes(senderNode: InternalMockNetwork.MockNode, destNode: InternalMockNetwork.MockNode, startType: String, endType: String) {
val sx = nodesToWidgets[senderNode]!!.innerDot.centerX
val sy = nodesToWidgets[senderNode]!!.innerDot.centerY
val dx = nodesToWidgets[destNode]!!.innerDot.centerX

View File

@ -10,9 +10,12 @@ import net.corda.irs.api.NodeInterestRates
import net.corda.node.internal.StartedNode
import net.corda.node.services.statemachine.StateMachineManager
import net.corda.testing.core.TestIdentity
import net.corda.testing.node.*
import net.corda.testing.node.MockNetwork.MockNode
import net.corda.testing.node.InMemoryMessagingNetwork
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.node.TestClock
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.MockNodeArgs
import rx.Observable
import rx.subjects.PublishSubject
import java.math.BigInteger
@ -24,7 +27,7 @@ import java.util.concurrent.CompletableFuture
import java.util.concurrent.CompletableFuture.allOf
import java.util.concurrent.Future
internal val MockNode.place get() = configuration.myLegalName.locality.let { CityDatabase[it] }!!
internal val InternalMockNetwork.MockNode.place get() = configuration.myLegalName.locality.let { CityDatabase[it] }!!
/**
* Base class for network simulations that are based on the unit test / mock environment.
@ -50,7 +53,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
val bankLocations = listOf(Pair("London", "GB"), Pair("Frankfurt", "DE"), Pair("Rome", "IT"))
class RatesOracleNode(args: MockNodeArgs) : MockNode(args) {
class RatesOracleNode(args: MockNodeArgs) : InternalMockNetwork.MockNode(args) {
companion object {
// TODO: Make a more realistic legal name
val RATES_SERVICE_NAME = CordaX500Name(organisation = "Rates Service Provider", locality = "Madrid", country = "ES")
@ -67,7 +70,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
}
}
val mockNet = MockNetwork(
val mockNet = InternalMockNetwork(
networkSendManuallyPumped = networkSendManuallyPumped,
threadPerNode = runAsync,
cordappPackages = listOf("net.corda.finance.contract", "net.corda.irs"))
@ -77,8 +80,8 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
val regulators = listOf(mockNet.createUnstartedNode(defaultParams.copy(legalName = DUMMY_REGULATOR.name)))
val ratesOracle = mockNet.createUnstartedNode(defaultParams.copy(legalName = RatesOracleNode.RATES_SERVICE_NAME), ::RatesOracleNode)
// All nodes must be in one of these two lists for the purposes of the visualiser tool.
val serviceProviders: List<MockNode> = listOf(mockNet.defaultNotaryNode.internals, ratesOracle)
val banks: List<MockNode> = bankLocations.mapIndexed { i, (city, country) ->
val serviceProviders: List<InternalMockNetwork.MockNode> = listOf(mockNet.defaultNotaryNode.internals, ratesOracle)
val banks: List<InternalMockNetwork.MockNode> = bankLocations.mapIndexed { i, (city, country) ->
val legalName = CordaX500Name(organisation = "Bank ${'A' + i}", locality = city, country = country)
// Use deterministic seeds so the simulation is stable. Needed so that party owning keys are stable.
mockNet.createUnstartedNode(defaultParams.copy(legalName = legalName, entropyRoot = BigInteger.valueOf(i.toLong())))
@ -86,12 +89,12 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
val clocks = (serviceProviders + regulators + banks).map { it.platformClock as TestClock }
// These are used from the network visualiser tool.
private val _allFlowSteps = PublishSubject.create<Pair<MockNode, ProgressTracker.Change>>()
private val _doneSteps = PublishSubject.create<Collection<MockNode>>()
private val _allFlowSteps = PublishSubject.create<Pair<InternalMockNetwork.MockNode, ProgressTracker.Change>>()
private val _doneSteps = PublishSubject.create<Collection<InternalMockNetwork.MockNode>>()
@Suppress("unused")
val allFlowSteps: Observable<Pair<MockNode, ProgressTracker.Change>> = _allFlowSteps
val allFlowSteps: Observable<Pair<InternalMockNetwork.MockNode, ProgressTracker.Change>> = _allFlowSteps
@Suppress("unused")
val doneSteps: Observable<Collection<MockNode>> = _doneSteps
val doneSteps: Observable<Collection<InternalMockNetwork.MockNode>> = _doneSteps
private var pumpCursor = 0
@ -120,7 +123,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
* A place for simulations to stash human meaningful text about what the node is "thinking", which might appear
* in the UI somewhere.
*/
val extraNodeLabels: MutableMap<MockNode, String> = Collections.synchronizedMap(HashMap())
val extraNodeLabels: MutableMap<InternalMockNetwork.MockNode, String> = Collections.synchronizedMap(HashMap())
/**
* Iterates the simulation by one step.
@ -151,7 +154,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
return null
}
protected fun showProgressFor(nodes: List<StartedNode<MockNode>>) {
protected fun showProgressFor(nodes: List<StartedNode<InternalMockNetwork.MockNode>>) {
nodes.forEach { node ->
node.smm.changes.filter { it is StateMachineManager.Change.Add }.subscribe {
linkFlowProgress(node.internals, it.logic)
@ -159,7 +162,7 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
}
}
private fun linkFlowProgress(node: MockNode, flow: FlowLogic<*>) {
private fun linkFlowProgress(node: InternalMockNetwork.MockNode, flow: FlowLogic<*>) {
val pt = flow.progressTracker ?: return
pt.changes.subscribe { change: ProgressTracker.Change ->
// Runs on node thread.
@ -168,14 +171,14 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
}
protected fun showConsensusFor(nodes: List<MockNode>) {
protected fun showConsensusFor(nodes: List<InternalMockNetwork.MockNode>) {
val node = nodes.first()
node.started!!.smm.changes.filter { it is StateMachineManager.Change.Add }.first().subscribe {
linkConsensus(nodes, it.logic)
}
}
private fun linkConsensus(nodes: Collection<MockNode>, flow: FlowLogic<*>) {
private fun linkConsensus(nodes: Collection<InternalMockNetwork.MockNode>, flow: FlowLogic<*>) {
flow.progressTracker?.changes?.subscribe { _: ProgressTracker.Change ->
// Runs on node thread.
if (flow.progressTracker!!.currentStep == ProgressTracker.DONE) {

View File

@ -12,7 +12,7 @@ import net.corda.testing.core.BOC_NAME
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_BANK_B_NAME
import net.corda.testing.core.chooseIdentity
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.InProcess
import net.corda.testing.driver.driver
import net.corda.testing.node.User
import net.corda.testing.node.internal.poll
@ -37,14 +37,14 @@ class TraderDemoTest {
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser)),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser)),
startNode(providedName = BOC_NAME, rpcUsers = listOf(bankUser))
).map { (it.getOrThrow() as NodeHandle.InProcess).node }
).map { (it.getOrThrow() as InProcess) }
nodeA.registerInitiatedFlow(BuyerFlow::class.java)
val (nodeARpc, nodeBRpc) = listOf(nodeA, nodeB).map {
val client = CordaRPCClient(it.internals.configuration.rpcOptions.address!!)
val client = CordaRPCClient(it.rpcAddress)
client.start(demoUser.username, demoUser.password).proxy
}
val nodeBankRpc = let {
val client = CordaRPCClient(bankNode.internals.configuration.rpcOptions.address!!)
val client = CordaRPCClient(bankNode.rpcAddress)
client.start(bankUser.username, bankUser.password).proxy
}
@ -56,8 +56,8 @@ class TraderDemoTest {
val expectedBCash = clientB.cashCount + 1
val expectedPaper = listOf(clientA.commercialPaperCount + 1, clientB.commercialPaperCount)
clientBank.runIssuer(amount = 100.DOLLARS, buyerName = nodeA.info.chooseIdentity().name, sellerName = nodeB.info.chooseIdentity().name)
clientB.runSeller(buyerName = nodeA.info.chooseIdentity().name, amount = 5.DOLLARS)
clientBank.runIssuer(amount = 100.DOLLARS, buyerName = nodeA.services.myInfo.chooseIdentity().name, sellerName = nodeB.services.myInfo.chooseIdentity().name)
clientB.runSeller(buyerName = nodeA.services.myInfo.chooseIdentity().name, amount = 5.DOLLARS)
assertThat(clientA.cashCount).isGreaterThan(originalACash)
assertThat(clientB.cashCount).isEqualTo(expectedBCash)

View File

@ -15,6 +15,7 @@ import net.corda.testing.node.internal.addressMustNotBeBound
import net.corda.testing.node.internal.internalDriver
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.driver.internal.NodeHandleInternal
import net.corda.testing.http.HttpApi
import net.corda.testing.node.NotarySpec
import org.assertj.core.api.Assertions.assertThat
@ -27,10 +28,11 @@ class DriverTests {
private companion object {
val DUMMY_REGULATOR_NAME = CordaX500Name("Regulator A", "Paris", "FR")
val executorService: ScheduledExecutorService = Executors.newScheduledThreadPool(2)
fun nodeMustBeUp(handleFuture: CordaFuture<out NodeHandle>) = handleFuture.getOrThrow().apply {
val hostAndPort = nodeInfo.addresses.single()
// Check that the port is bound
addressMustBeBound(executorService, hostAndPort, (this as? NodeHandle.OutOfProcess)?.process)
addressMustBeBound(executorService, hostAndPort, (this as? OutOfProcess)?.process)
}
fun nodeMustBeDown(handle: NodeHandle) {
@ -80,7 +82,7 @@ class DriverTests {
val logConfigFile = projectRootDir / "config" / "dev" / "log4j2.xml"
assertThat(logConfigFile).isRegularFile()
driver(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString())) {
val baseDirectory = startNode(providedName = DUMMY_BANK_A_NAME).getOrThrow().configuration.baseDirectory
val baseDirectory = startNode(providedName = DUMMY_BANK_A_NAME).getOrThrow().baseDirectory
val logFile = (baseDirectory / NodeStartup.LOGS_DIRECTORY_NAME).list { it.sorted().findFirst().get() }
val debugLinesPresent = logFile.readLines { lines -> lines.anyMatch { line -> line.startsWith("[DEBUG]") } }
assertThat(debugLinesPresent).isTrue()
@ -105,7 +107,7 @@ class DriverTests {
// First check that the process-id file is created by the node on startup, so that we can be sure our check that
// it's deleted on shutdown isn't a false-positive.
driver {
val baseDirectory = defaultNotaryNode.getOrThrow().configuration.baseDirectory
val baseDirectory = defaultNotaryNode.getOrThrow().baseDirectory
assertThat(baseDirectory / "process-id").exists()
}

View File

@ -2,6 +2,7 @@ package net.corda.testing.node
import co.paralleluniverse.fibers.Suspendable
import net.corda.client.jackson.JacksonSupport
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.flows.*
import net.corda.core.internal.div
import net.corda.core.internal.list
@ -228,7 +229,7 @@ class FlowStackSnapshotTest {
fun `flowStackSnapshot contains full frames when methods with side effects are called`() {
driver(startNodesInProcess = true) {
val a = startNode(rpcUsers = listOf(User(Constants.USER, Constants.PASSWORD, setOf(startFlow<SideEffectFlow>())))).get()
a.rpcClientToNode().use(Constants.USER, Constants.PASSWORD) { connection ->
CordaRPCClient(a.rpcAddress).use(Constants.USER, Constants.PASSWORD) { connection ->
val stackSnapshotFrames = connection.proxy.startFlow(::SideEffectFlow).returnValue.get()
val iterator = stackSnapshotFrames.listIterator()
assertFrame("run", false, iterator.next())
@ -243,7 +244,7 @@ class FlowStackSnapshotTest {
fun `flowStackSnapshot contains empty frames when methods with no side effects are called`() {
driver(startNodesInProcess = true) {
val a = startNode(rpcUsers = listOf(User(Constants.USER, Constants.PASSWORD, setOf(startFlow<NoSideEffectFlow>())))).get()
a.rpcClientToNode().use(Constants.USER, Constants.PASSWORD) { connection ->
CordaRPCClient(a.rpcAddress).use(Constants.USER, Constants.PASSWORD) { connection ->
val stackSnapshotFrames = connection.proxy.startFlow(::NoSideEffectFlow).returnValue.get()
val iterator = stackSnapshotFrames.listIterator()
assertFrame("run", false, iterator.next())
@ -258,10 +259,9 @@ class FlowStackSnapshotTest {
fun `persistFlowStackSnapshot persists empty frames to a file when methods with no side effects are called`() {
driver(startNodesInProcess = true) {
val a = startNode(rpcUsers = listOf(User(Constants.USER, Constants.PASSWORD, setOf(startFlow<PersistingNoSideEffectFlow>())))).get()
a.rpcClientToNode().use(Constants.USER, Constants.PASSWORD) { connection ->
CordaRPCClient(a.rpcAddress).use(Constants.USER, Constants.PASSWORD) { connection ->
val flowId = connection.proxy.startFlow(::PersistingNoSideEffectFlow).returnValue.get()
val snapshotFromFile = readFlowStackSnapshotFromDir(a.configuration.baseDirectory, flowId)
val snapshotFromFile = readFlowStackSnapshotFromDir(a.baseDirectory, flowId)
val stackSnapshotFrames = convertToStackSnapshotFrames(snapshotFromFile)
val iterator = stackSnapshotFrames.listIterator()
assertFrame("call", true, iterator.next())
@ -276,10 +276,10 @@ class FlowStackSnapshotTest {
driver(startNodesInProcess = true) {
val a = startNode(rpcUsers = listOf(User(Constants.USER, Constants.PASSWORD, setOf(startFlow<MultiplePersistingSideEffectFlow>())))).get()
a.rpcClientToNode().use(Constants.USER, Constants.PASSWORD) { connection ->
CordaRPCClient(a.rpcAddress).use(Constants.USER, Constants.PASSWORD) { connection ->
val numberOfFlowSnapshots = 5
val flowId = connection.proxy.startFlow(::MultiplePersistingSideEffectFlow, 5).returnValue.get()
val fileCount = countFilesInDir(a.configuration.baseDirectory, flowId)
val fileCount = countFilesInDir(a.baseDirectory, flowId)
assertEquals(numberOfFlowSnapshots, fileCount)
}
}
@ -307,9 +307,9 @@ class FlowStackSnapshotTest {
driver(startNodesInProcess = true) {
val a = startNode(rpcUsers = listOf(User(Constants.USER, Constants.PASSWORD, setOf(startFlow<PersistingSideEffectFlow>())))).get()
a.rpcClientToNode().use(Constants.USER, Constants.PASSWORD) { connection ->
CordaRPCClient(a.rpcAddress).use(Constants.USER, Constants.PASSWORD) { connection ->
val flowId = connection.proxy.startFlow(::PersistingSideEffectFlow).returnValue.get()
val snapshotFromFile = readFlowStackSnapshotFromDir(a.configuration.baseDirectory, flowId)
val snapshotFromFile = readFlowStackSnapshotFromDir(a.baseDirectory, flowId)
var inCallCount = 0
var inPersistCount = 0
snapshotFromFile.stackFrames.forEach {

View File

@ -2,6 +2,7 @@ package net.corda.testing.node
import net.corda.core.internal.div
import net.corda.testing.common.internal.ProjectStructure.projectRootDir
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.ProcessUtilities.startJavaProcess
import org.junit.Test
import kotlin.test.assertEquals

View File

@ -0,0 +1,26 @@
package net.corda.testing.node.internal
import net.corda.core.internal.div
import net.corda.testing.common.internal.ProjectStructure.projectRootDir
import net.corda.testing.node.internal.ProcessUtilities.startJavaProcess
import org.junit.Test
import kotlin.test.assertEquals
class InternalMockNetworkIntegrationTests {
companion object {
@JvmStatic
fun main(args: Array<String>) {
InternalMockNetwork(emptyList()).run {
repeat(2) { createNode() }
runNetwork()
stopNodes()
}
}
}
@Test
fun `does not leak non-daemon threads`() {
val quasar = projectRootDir / "lib" / "quasar.jar"
assertEquals(0, startJavaProcess<InternalMockNetworkIntegrationTests>(emptyList(), extraJvmArguments = listOf("-javaagent:$quasar")).waitFor())
}
}

View File

@ -2,9 +2,9 @@
package net.corda.testing.driver
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.DoNotImplement
import net.corda.core.concurrent.CordaFuture
import net.corda.core.flows.FlowLogic
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.messaging.CordaRPCOps
@ -12,15 +12,17 @@ import net.corda.core.node.NodeInfo
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.internal.Node
import net.corda.node.internal.StartedNode
import net.corda.node.services.api.StartedNodeServices
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.config.VerifierType
import net.corda.nodeapi.internal.config.SSLConfiguration
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.node.NotarySpec
import net.corda.testing.node.User
import net.corda.testing.node.internal.DriverDSLImpl
import net.corda.testing.node.internal.genericDriver
import net.corda.testing.node.internal.getTimestampAsDirectoryName
import rx.Observable
import java.net.InetSocketAddress
import java.net.ServerSocket
import java.nio.file.Path
@ -33,73 +35,37 @@ import java.util.concurrent.atomic.AtomicInteger
data class NotaryHandle(val identity: Party, val validating: Boolean, val nodeHandles: CordaFuture<List<NodeHandle>>)
@DoNotImplement
sealed class NodeHandle : AutoCloseable {
abstract val nodeInfo: NodeInfo
interface NodeHandle : AutoCloseable {
val nodeInfo: NodeInfo
/**
* Interface to the node's RPC system. The first RPC user will be used to login if are any, otherwise a default one
* will be added and that will be used.
*/
abstract val rpc: CordaRPCOps
abstract val configuration: NodeConfiguration
abstract val webAddress: NetworkHostAndPort
abstract val useHTTPS: Boolean
val rpc: CordaRPCOps
val p2pAddress: NetworkHostAndPort
val rpcAddress: NetworkHostAndPort
val rpcUsers: List<User>
val baseDirectory: Path
/**
* Stops the referenced node.
*/
abstract fun stop()
fun stop()
}
@DoNotImplement
interface OutOfProcess : NodeHandle {
val process: Process
}
@DoNotImplement
interface InProcess : NodeHandle {
val database: CordaPersistence
val services: StartedNodeServices
/**
* Closes and stops the node.
* Register a flow that is initiated by another flow
*/
override fun close() = stop()
data class OutOfProcess(
override val nodeInfo: NodeInfo,
override val rpc: CordaRPCOps,
override val configuration: NodeConfiguration,
override val webAddress: NetworkHostAndPort,
override val useHTTPS: Boolean,
val debugPort: Int?,
val process: Process,
private val onStopCallback: () -> Unit
) : NodeHandle() {
override fun stop() {
with(process) {
destroy()
waitFor()
}
onStopCallback()
}
}
data class InProcess(
override val nodeInfo: NodeInfo,
override val rpc: CordaRPCOps,
override val configuration: NodeConfiguration,
override val webAddress: NetworkHostAndPort,
override val useHTTPS: Boolean,
val node: StartedNode<Node>,
val nodeThread: Thread,
private val onStopCallback: () -> Unit
) : NodeHandle() {
override fun stop() {
node.dispose()
with(nodeThread) {
interrupt()
join()
}
onStopCallback()
}
}
/**
* Connects to node through RPC.
*
* @param sslConfiguration specifies SSL options.
*/
@JvmOverloads
fun rpcClientToNode(sslConfiguration: SSLConfiguration? = null): CordaRPCClient = CordaRPCClient(configuration.rpcOptions.address!!, sslConfiguration = sslConfiguration)
fun <T : FlowLogic<*>> registerInitiatedFlow(initiatedFlowClass: Class<T>): Observable<T>
}
data class WebserverHandle(
@ -137,12 +103,12 @@ data class NodeParameters(
val startInSameProcess: Boolean? = null,
val maximumHeapSize: String = "200m"
) {
fun setProvidedName(providedName: CordaX500Name?) = copy(providedName = providedName)
fun setRpcUsers(rpcUsers: List<User>) = copy(rpcUsers = rpcUsers)
fun setVerifierType(verifierType: VerifierType) = copy(verifierType = verifierType)
fun setCustomerOverrides(customOverrides: Map<String, Any?>) = copy(customOverrides = customOverrides)
fun setStartInSameProcess(startInSameProcess: Boolean?) = copy(startInSameProcess = startInSameProcess)
fun setMaximumHeapSize(maximumHeapSize: String) = copy(maximumHeapSize = maximumHeapSize)
fun setProvidedName(providedName: CordaX500Name?): NodeParameters = copy(providedName = providedName)
fun setRpcUsers(rpcUsers: List<User>): NodeParameters = copy(rpcUsers = rpcUsers)
fun setVerifierType(verifierType: VerifierType): NodeParameters = copy(verifierType = verifierType)
fun setCustomerOverrides(customOverrides: Map<String, Any?>): NodeParameters = copy(customOverrides = customOverrides)
fun setStartInSameProcess(startInSameProcess: Boolean?): NodeParameters = copy(startInSameProcess = startInSameProcess)
fun setMaximumHeapSize(maximumHeapSize: String): NodeParameters = copy(maximumHeapSize = maximumHeapSize)
}
data class JmxPolicy(val startJmxHttpServer: Boolean = false,

View File

@ -0,0 +1,74 @@
package net.corda.testing.driver.internal
import net.corda.core.flows.FlowLogic
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.node.NodeInfo
import net.corda.core.utilities.NetworkHostAndPort
import net.corda.node.internal.Node
import net.corda.node.internal.StartedNode
import net.corda.node.services.api.StartedNodeServices
import net.corda.node.services.config.NodeConfiguration
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.driver.InProcess
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.OutOfProcess
import net.corda.testing.node.User
import rx.Observable
import java.nio.file.Path
interface NodeHandleInternal : NodeHandle {
val configuration: NodeConfiguration
val useHTTPS: Boolean
val webAddress: NetworkHostAndPort
override val p2pAddress: NetworkHostAndPort get() = configuration.p2pAddress
override val rpcAddress: NetworkHostAndPort get() = configuration.rpcOptions.address!!
override val baseDirectory: Path get() = configuration.baseDirectory
}
data class OutOfProcessImpl(
override val nodeInfo: NodeInfo,
override val rpc: CordaRPCOps,
override val configuration: NodeConfiguration,
override val webAddress: NetworkHostAndPort,
override val useHTTPS: Boolean,
val debugPort: Int?,
override val process: Process,
private val onStopCallback: () -> Unit
) : OutOfProcess, NodeHandleInternal {
override val rpcUsers: List<User> = configuration.rpcUsers.map { User(it.username, it.password, it.permissions) }
override fun stop() {
with(process) {
destroy()
waitFor()
}
onStopCallback()
}
override fun close() = stop()
}
data class InProcessImpl(
override val nodeInfo: NodeInfo,
override val rpc: CordaRPCOps,
override val configuration: NodeConfiguration,
override val webAddress: NetworkHostAndPort,
override val useHTTPS: Boolean,
private val nodeThread: Thread,
private val onStopCallback: () -> Unit,
private val node: StartedNode<Node>
) : InProcess, NodeHandleInternal {
override val database: CordaPersistence get() = node.database
override val services: StartedNodeServices get() = node.services
override val rpcUsers: List<User> = configuration.rpcUsers.map { User(it.username, it.password, it.permissions) }
override fun stop() {
node.dispose()
with(nodeThread) {
interrupt()
join()
}
onStopCallback()
}
override fun close() = stop()
override fun <T : FlowLogic<*>> registerInitiatedFlow(initiatedFlowClass: Class<T>): Observable<T> = node.registerInitiatedFlow(initiatedFlowClass)
}

View File

@ -304,7 +304,7 @@ class InMemoryMessagingNetwork internal constructor(
override fun getAddressOfParty(partyInfo: PartyInfo): MessageRecipients {
return when (partyInfo) {
is PartyInfo.SingleNode -> peersMapping[partyInfo.party.name] ?: throw IllegalArgumentException("No MockNode for party ${partyInfo.party.name}")
is PartyInfo.SingleNode -> peersMapping[partyInfo.party.name] ?: throw IllegalArgumentException("No StartedMockNode for party ${partyInfo.party.name}")
is PartyInfo.DistributedNode -> ServiceHandle(partyInfo.party)
}
}

View File

@ -0,0 +1,178 @@
package net.corda.testing.node
import com.google.common.jimfs.Jimfs
import net.corda.core.concurrent.CordaFuture
import net.corda.core.crypto.random63BitValue
import net.corda.core.flows.FlowLogic
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.node.NodeInfo
import net.corda.node.VersionInfo
import net.corda.node.internal.StartedNode
import net.corda.node.services.api.StartedNodeServices
import net.corda.node.services.config.NodeConfiguration
import net.corda.node.services.messaging.MessagingService
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.node.internal.InternalMockNetwork
import net.corda.testing.node.internal.setMessagingServiceSpy
import rx.Observable
import java.math.BigInteger
import java.nio.file.Path
/**
* Extend this class in order to intercept and modify messages passing through the [MessagingService] when using the [InMemoryMessagingNetwork].
*/
open class MessagingServiceSpy(val messagingService: MessagingService) : MessagingService by messagingService
/**
* @param entropyRoot the initial entropy value to use when generating keys. Defaults to an (insecure) random value,
* but can be overridden to cause nodes to have stable or colliding identity/service keys.
* @param configOverrides add/override behaviour of the [NodeConfiguration] mock object.
*/
@Suppress("unused")
data class MockNodeParameters(
val forcedID: Int? = null,
val legalName: CordaX500Name? = null,
val entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()),
val configOverrides: (NodeConfiguration) -> Any? = {},
val version: VersionInfo = MockServices.MOCK_VERSION_INFO) {
fun setForcedID(forcedID: Int?): MockNodeParameters = copy(forcedID = forcedID)
fun setLegalName(legalName: CordaX500Name?): MockNodeParameters = copy(legalName = legalName)
fun setEntropyRoot(entropyRoot: BigInteger): MockNodeParameters = copy(entropyRoot = entropyRoot)
fun setConfigOverrides(configOverrides: (NodeConfiguration) -> Any?): MockNodeParameters = copy(configOverrides = configOverrides)
}
/** Helper builder for configuring a [InternalMockNetwork] from Java. */
@Suppress("unused")
data class MockNetworkParameters(
val networkSendManuallyPumped: Boolean = false,
val threadPerNode: Boolean = false,
val servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = InMemoryMessagingNetwork.ServicePeerAllocationStrategy.Random(),
val initialiseSerialization: Boolean = true,
val notarySpecs: List<MockNetworkNotarySpec> = listOf(MockNetworkNotarySpec(DUMMY_NOTARY_NAME)),
val maxTransactionSize: Int = Int.MAX_VALUE) {
fun setNetworkSendManuallyPumped(networkSendManuallyPumped: Boolean): MockNetworkParameters = copy(networkSendManuallyPumped = networkSendManuallyPumped)
fun setThreadPerNode(threadPerNode: Boolean): MockNetworkParameters = copy(threadPerNode = threadPerNode)
fun setServicePeerAllocationStrategy(servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy): MockNetworkParameters = copy(servicePeerAllocationStrategy = servicePeerAllocationStrategy)
fun setInitialiseSerialization(initialiseSerialization: Boolean): MockNetworkParameters = copy(initialiseSerialization = initialiseSerialization)
fun setNotarySpecs(notarySpecs: List<MockNetworkNotarySpec>): MockNetworkParameters = copy(notarySpecs = notarySpecs)
fun setMaxTransactionSize(maxTransactionSize: Int): MockNetworkParameters = copy(maxTransactionSize = maxTransactionSize)
}
/** Represents a node configuration for injection via [MockNetworkParameters] **/
data class MockNetworkNotarySpec(val name: CordaX500Name, val validating: Boolean = true) {
constructor(name: CordaX500Name) : this(name, validating = true)
}
/** A class that represents an unstarted mock node for testing. **/
class UnstartedMockNode private constructor(private val node: InternalMockNetwork.MockNode) {
companion object {
internal fun create(node: InternalMockNetwork.MockNode): UnstartedMockNode {
return UnstartedMockNode(node)
}
}
val id get() : Int = node.id
/** Start the node **/
fun start() = StartedMockNode.create(node.start())
}
/** A class that represents a started mock node for testing. **/
class StartedMockNode private constructor(private val node: StartedNode<InternalMockNetwork.MockNode>) {
companion object {
internal fun create(node: StartedNode<InternalMockNetwork.MockNode>): StartedMockNode {
return StartedMockNode(node)
}
}
val services get() : StartedNodeServices = node.services
val database get() : CordaPersistence = node.database
val id get() : Int = node.internals.id
val info get() : NodeInfo = node.services.myInfo
val network get() : MessagingService = node.network
/** Register a flow that is initiated by another flow **/
fun <F : FlowLogic<*>> registerInitiatedFlow(initiatedFlowClass: Class<F>): Observable<F> = node.registerInitiatedFlow(initiatedFlowClass)
/**
* Attach a [MessagingServiceSpy] to the [InternalMockNetwork.MockNode] allowing
* interception and modification of messages.
*/
fun setMessagingServiceSpy(messagingServiceSpy: MessagingServiceSpy) = node.setMessagingServiceSpy(messagingServiceSpy)
/** Stop the node **/
fun stop() = node.internals.stop()
/** Receive a message from the queue. */
fun pumpReceive(block: Boolean = false): InMemoryMessagingNetwork.MessageTransfer? {
return (services.networkService as InMemoryMessagingNetwork.TestMessagingService).pumpReceive(block)
}
/** Returns the currently live flows of type [flowClass], and their corresponding result future. */
fun <F : FlowLogic<*>> findStateMachines(flowClass: Class<F>): List<Pair<F, CordaFuture<*>>> = node.smm.findStateMachines(flowClass)
}
/**
* A mock node brings up a suite of in-memory services in a fast manner suitable for unit testing.
* Components that do IO are either swapped out for mocks, or pointed to a [Jimfs] in memory filesystem or an in
* memory H2 database instance.
*
* Mock network nodes require manual pumping by default: they will not run asynchronous. This means that
* for message exchanges to take place (and associated handlers to run), you must call the [runNetwork]
* method.
*
* You can get a printout of every message sent by using code like:
*
* LogHelper.setLevel("+messages")
*
* By default a single notary node is automatically started, which forms part of the network parameters for all the nodes.
* This node is available by calling [defaultNotaryNode].
*/
open class MockNetwork(
val cordappPackages: List<String>,
val defaultParameters: MockNetworkParameters = MockNetworkParameters(),
val networkSendManuallyPumped: Boolean = defaultParameters.networkSendManuallyPumped,
val threadPerNode: Boolean = defaultParameters.threadPerNode,
val servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy,
val initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
val notarySpecs: List<MockNetworkNotarySpec> = defaultParameters.notarySpecs,
val maxTransactionSize: Int = defaultParameters.maxTransactionSize) {
@JvmOverloads
constructor(cordappPackages: List<String>, parameters: MockNetworkParameters = MockNetworkParameters()) : this(cordappPackages, defaultParameters = parameters)
private val internalMockNetwork: InternalMockNetwork = InternalMockNetwork(cordappPackages, defaultParameters, networkSendManuallyPumped, threadPerNode, servicePeerAllocationStrategy, initialiseSerialization, notarySpecs, maxTransactionSize)
val defaultNotaryNode get() : StartedMockNode = StartedMockNode.create(internalMockNetwork.defaultNotaryNode)
val defaultNotaryIdentity get() : Party = internalMockNetwork.defaultNotaryIdentity
val notaryNodes get() : List<StartedMockNode> = internalMockNetwork.notaryNodes.map { StartedMockNode.create(it) }
val nextNodeId get() : Int = internalMockNetwork.nextNodeId
/** Create a started node with the given identity. **/
fun createPartyNode(legalName: CordaX500Name? = null): StartedMockNode = StartedMockNode.create(internalMockNetwork.createPartyNode(legalName))
/** Create a started node with the given parameters. **/
fun createNode(parameters: MockNodeParameters = MockNodeParameters()): StartedMockNode = StartedMockNode.create(internalMockNetwork.createNode(parameters))
/** Create an unstarted node with the given parameters. **/
fun createUnstartedNode(parameters: MockNodeParameters = MockNodeParameters()): UnstartedMockNode = UnstartedMockNode.create(internalMockNetwork.createUnstartedNode(parameters))
/** Start all nodes that aren't already started. **/
fun startNodes() = internalMockNetwork.startNodes()
/** Stop all nodes. **/
fun stopNodes() = internalMockNetwork.stopNodes()
/** Block until all scheduled activity, active flows and network activity has ceased. **/
fun waitQuiescent() = internalMockNetwork.waitQuiescent()
/**
* Asks every node in order to process any queued up inbound messages. This may in turn result in nodes
* sending more messages to each other, thus, a typical usage is to call runNetwork with the [rounds]
* parameter set to -1 (the default) which simply runs as many rounds as necessary to result in network
* stability (no nodes sent any messages in the last round).
*/
@JvmOverloads
fun runNetwork(rounds: Int = -1) = internalMockNetwork.runNetwork(rounds)
/** Get the base directory for the given node id. **/
fun baseDirectory(nodeId: Int): Path = internalMockNetwork.baseDirectory(nodeId)
}

View File

@ -44,6 +44,9 @@ import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.setGlobalSerialization
import net.corda.testing.driver.*
import net.corda.testing.driver.internal.InProcessImpl
import net.corda.testing.driver.internal.NodeHandleInternal
import net.corda.testing.driver.internal.OutOfProcessImpl
import net.corda.testing.node.ClusterSpec
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
import net.corda.testing.node.NotarySpec
@ -355,7 +358,7 @@ class DriverDSLImpl(
}
private fun queryWebserver(handle: NodeHandle, process: Process): WebserverHandle {
val protocol = if (handle.useHTTPS) "https://" else "http://"
val protocol = if ((handle as NodeHandleInternal).useHTTPS) "https://" else "http://"
val url = URL("$protocol${handle.webAddress}/api/status")
val client = OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build()
@ -375,7 +378,7 @@ class DriverDSLImpl(
val debugPort = if (isDebug) debugPortAllocation.nextPort() else null
val process = startWebserver(handle, debugPort, maximumHeapSize)
shutdownManager.registerProcessShutdown(process)
val webReadyFuture = addressMustBeBoundFuture(executorService, handle.webAddress, process)
val webReadyFuture = addressMustBeBoundFuture(executorService, (handle as NodeHandleInternal).webAddress, process)
return webReadyFuture.map { queryWebserver(handle, process) }
}
@ -654,7 +657,7 @@ class DriverDSLImpl(
return nodeAndThreadFuture.flatMap { (node, thread) ->
establishRpc(config, openFuture()).flatMap { rpc ->
allNodesConnected(rpc).map {
NodeHandle.InProcess(rpc.nodeInfo(), rpc, config.corda, webAddress, useHTTPS, node, thread, onNodeExit)
InProcessImpl(rpc.nodeInfo(), rpc, config.corda, webAddress, useHTTPS, thread, onNodeExit, node)
}
}
}
@ -683,7 +686,7 @@ class DriverDSLImpl(
}
processDeathFuture.cancel(false)
log.info("Node handle is ready. NodeInfo: ${rpc.nodeInfo()}, WebAddress: $webAddress")
NodeHandle.OutOfProcess(rpc.nodeInfo(), rpc, config.corda, webAddress, useHTTPS, debugPort, process, onNodeExit)
OutOfProcessImpl(rpc.nodeInfo(), rpc, config.corda, webAddress, useHTTPS, debugPort, process, onNodeExit)
}
}
}
@ -833,10 +836,10 @@ class DriverDSLImpl(
val className = "net.corda.webserver.WebServer"
return ProcessUtilities.startCordaProcess(
className = className, // cannot directly get class for this, so just use string
arguments = listOf("--base-directory", handle.configuration.baseDirectory.toString()),
arguments = listOf("--base-directory", handle.baseDirectory.toString()),
jdwpPort = debugPort,
extraJvmArguments = listOf(
"-Dname=node-${handle.configuration.p2pAddress}-webserver",
"-Dname=node-${handle.p2pAddress}-webserver",
"-Djava.io.tmpdir=${System.getProperty("java.io.tmpdir")}" // Inherit from parent process
),
errorLogPath = Paths.get("error.$className.log"),

View File

@ -1,4 +1,4 @@
package net.corda.testing.node
package net.corda.testing.node.internal
import com.google.common.jimfs.Configuration.unix
import com.google.common.jimfs.Jimfs
@ -7,6 +7,7 @@ import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.DoNotImplement
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.random63BitValue
import net.corda.core.flows.FlowLogic
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate
@ -28,6 +29,7 @@ import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.seconds
import net.corda.node.VersionInfo
import net.corda.node.internal.AbstractNode
import net.corda.node.internal.InitiatedFlowFactory
import net.corda.node.internal.StartedNode
import net.corda.node.internal.cordapp.CordappLoader
import net.corda.node.services.api.IdentityServiceInternal
@ -52,8 +54,11 @@ import net.corda.testing.internal.rigorousMock
import net.corda.testing.internal.testThreadFactory
import net.corda.testing.node.MockServices.Companion.MOCK_VERSION_INFO
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.core.setGlobalSerialization
import net.corda.testing.node.*
import org.apache.activemq.artemis.utils.ReusableLatch
import org.apache.sshd.common.util.security.SecurityUtils
import rx.Observable
import rx.internal.schedulers.CachedThreadScheduler
import java.math.BigInteger
import java.nio.file.Path
@ -63,48 +68,13 @@ import java.time.Clock
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
fun StartedNode<MockNetwork.MockNode>.pumpReceive(block: Boolean = false): InMemoryMessagingNetwork.MessageTransfer? {
fun StartedNode<InternalMockNetwork.MockNode>.pumpReceive(block: Boolean = false): InMemoryMessagingNetwork.MessageTransfer? {
return (network as InMemoryMessagingNetwork.TestMessagingService).pumpReceive(block)
}
/** Helper builder for configuring a [MockNetwork] from Java. */
@Suppress("unused")
data class MockNetworkParameters(
val networkSendManuallyPumped: Boolean = false,
val threadPerNode: Boolean = false,
val servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = InMemoryMessagingNetwork.ServicePeerAllocationStrategy.Random(),
val defaultFactory: (MockNodeArgs) -> MockNetwork.MockNode = MockNetwork::MockNode,
val initialiseSerialization: Boolean = true,
val notarySpecs: List<MockNetwork.NotarySpec> = listOf(MockNetwork.NotarySpec(DUMMY_NOTARY_NAME))) {
fun setNetworkSendManuallyPumped(networkSendManuallyPumped: Boolean) = copy(networkSendManuallyPumped = networkSendManuallyPumped)
fun setThreadPerNode(threadPerNode: Boolean) = copy(threadPerNode = threadPerNode)
fun setServicePeerAllocationStrategy(servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy) = copy(servicePeerAllocationStrategy = servicePeerAllocationStrategy)
fun setDefaultFactory(defaultFactory: (MockNodeArgs) -> MockNetwork.MockNode) = copy(defaultFactory = defaultFactory)
fun setInitialiseSerialization(initialiseSerialization: Boolean) = copy(initialiseSerialization = initialiseSerialization)
fun setNotarySpecs(notarySpecs: List<MockNetwork.NotarySpec>) = copy(notarySpecs = notarySpecs)
}
/**
* @param entropyRoot the initial entropy value to use when generating keys. Defaults to an (insecure) random value,
* but can be overridden to cause nodes to have stable or colliding identity/service keys.
* @param configOverrides add/override behaviour of the [NodeConfiguration] mock object.
*/
@Suppress("unused")
data class MockNodeParameters(
val forcedID: Int? = null,
val legalName: CordaX500Name? = null,
val entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()),
val configOverrides: (NodeConfiguration) -> Any? = {},
val version: VersionInfo = MOCK_VERSION_INFO) {
fun setForcedID(forcedID: Int?) = copy(forcedID = forcedID)
fun setLegalName(legalName: CordaX500Name?) = copy(legalName = legalName)
fun setEntropyRoot(entropyRoot: BigInteger) = copy(entropyRoot = entropyRoot)
fun setConfigOverrides(configOverrides: (NodeConfiguration) -> Any?) = copy(configOverrides = configOverrides)
}
data class MockNodeArgs(
val config: NodeConfiguration,
val network: MockNetwork,
val network: InternalMockNetwork,
val id: Int,
val entropyRoot: BigInteger,
val version: VersionInfo = MOCK_VERSION_INFO
@ -126,19 +96,15 @@ data class MockNodeArgs(
* By default a single notary node is automatically started, which forms part of the network parameters for all the nodes.
* This node is available by calling [defaultNotaryNode].
*/
open class MockNetwork(private val cordappPackages: List<String>,
defaultParameters: MockNetworkParameters = MockNetworkParameters(),
private val networkSendManuallyPumped: Boolean = defaultParameters.networkSendManuallyPumped,
private val threadPerNode: Boolean = defaultParameters.threadPerNode,
servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy,
private val defaultFactory: (MockNodeArgs) -> MockNode = defaultParameters.defaultFactory,
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
private val notarySpecs: List<NotarySpec> = defaultParameters.notarySpecs,
maxTransactionSize: Int = Int.MAX_VALUE) {
/** Helper constructor for creating a [MockNetwork] with custom parameters from Java. */
@JvmOverloads
constructor(cordappPackages: List<String>, parameters: MockNetworkParameters = MockNetworkParameters()) : this(cordappPackages, defaultParameters = parameters)
open class InternalMockNetwork(private val cordappPackages: List<String>,
defaultParameters: MockNetworkParameters = MockNetworkParameters(),
val networkSendManuallyPumped: Boolean = defaultParameters.networkSendManuallyPumped,
val threadPerNode: Boolean = defaultParameters.threadPerNode,
servicePeerAllocationStrategy: InMemoryMessagingNetwork.ServicePeerAllocationStrategy = defaultParameters.servicePeerAllocationStrategy,
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
val notarySpecs: List<MockNetworkNotarySpec> = defaultParameters.notarySpecs,
maxTransactionSize: Int = Int.MAX_VALUE,
val defaultFactory: (MockNodeArgs) -> MockNode = InternalMockNetwork::MockNode) {
init {
// Apache SSHD for whatever reason registers a SFTP FileSystemProvider - which gets loaded by JimFS.
// This SFTP support loads BouncyCastle, which we want to avoid.
@ -158,7 +124,7 @@ open class MockNetwork(private val cordappPackages: List<String>,
private val serializationEnv = try {
setGlobalSerialization(initialiseSerialization)
} catch (e: IllegalStateException) {
throw IllegalStateException("Using more than one MockNetwork simultaneously is not supported.", e)
throw IllegalStateException("Using more than one InternalMockNetwork simultaneously is not supported.", e)
}
private val sharedUserCount = AtomicInteger(0)
@ -329,12 +295,12 @@ open class MockNetwork(private val cordappPackages: List<String>,
// This is not thread safe, but node construction is done on a single thread, so that should always be fine
override fun generateKeyPair(): KeyPair {
counter = counter.add(BigInteger.ONE)
// The MockNode specifically uses EdDSA keys as they are fixed and stored in json files for some tests (e.g IRSSimulation).
// The StartedMockNode specifically uses EdDSA keys as they are fixed and stored in json files for some tests (e.g IRSSimulation).
return Crypto.deriveKeyPairFromEntropy(Crypto.EDDSA_ED25519_SHA512, counter)
}
/**
* MockNetwork will ensure nodes are connected to each other. The nodes themselves
* InternalMockNetwork will ensure nodes are connected to each other. The nodes themselves
* won't be able to tell if that happened already or not.
*/
override fun checkNetworkMapIsInitialized() = Unit
@ -478,20 +444,12 @@ open class MockNetwork(private val cordappPackages: List<String>,
busyLatch.await()
}
data class NotarySpec(val name: CordaX500Name, val validating: Boolean = true) {
constructor(name: CordaX500Name) : this(name, validating = true)
}
}
/**
* Extend this class in order to intercept and modify messages passing through the [MessagingService] when using the [InMemoryMessagingNetwork].
* Attach a [MessagingServiceSpy] to the [InternalMockNetwork.MockNode] allowing interception and modification of messages.
*/
open class MessagingServiceSpy(val messagingService: MessagingService) : MessagingService by messagingService
/**
* Attach a [MessagingServiceSpy] to the [MockNetwork.MockNode] allowing interception and modification of messages.
*/
fun StartedNode<MockNetwork.MockNode>.setMessagingServiceSpy(messagingServiceSpy: MessagingServiceSpy) {
fun StartedNode<InternalMockNetwork.MockNode>.setMessagingServiceSpy(messagingServiceSpy: MessagingServiceSpy) {
internals.setMessagingServiceSpy(messagingServiceSpy)
}

View File

@ -60,4 +60,4 @@ object ProcessUtilities {
}
val defaultClassPath: String get() = System.getProperty("java.class.path")
}
}

View File

@ -6,22 +6,15 @@ import static java.util.Collections.emptyList;
@SuppressWarnings("unused")
public class MockNodeFactoryInJavaTest {
private static class CustomNode extends MockNetwork.MockNode {
private CustomNode(@NotNull MockNodeArgs args) {
super(args);
}
}
/**
* Does not need to run, only compile.
*/
@SuppressWarnings("unused")
private static void factoryIsEasyToPassInUsingJava() {
//noinspection Convert2MethodRef
new MockNetwork(emptyList(), new MockNetworkParameters().setDefaultFactory(args -> new CustomNode(args)));
new MockNetwork(emptyList(), new MockNetworkParameters().setDefaultFactory(CustomNode::new));
new MockNetwork(emptyList());
new MockNetwork(emptyList(), new MockNetworkParameters().setInitialiseSerialization(false));
//noinspection Convert2MethodRef
new MockNetwork(emptyList()).createNode(new MockNodeParameters(), args -> new CustomNode(args));
new MockNetwork(emptyList()).createNode(new MockNodeParameters(), CustomNode::new);
new MockNetwork(emptyList()).createNode(new MockNodeParameters());
}
}

View File

@ -1,18 +1,18 @@
package net.corda.testing.node
package net.corda.testing.node.internal
import net.corda.core.serialization.internal.effectiveSerializationEnv
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test
class MockNetworkTests {
class InternalMockNetworkTests {
@Test
fun `does not leak serialization env if init fails`() {
val e = Exception("didn't work")
assertThatThrownBy {
object : MockNetwork(emptyList(), initialiseSerialization = true) {
object : InternalMockNetwork(emptyList(), initialiseSerialization = true) {
override fun createNotaries() = throw e
}
}.isSameAs(e)
assertThatThrownBy { effectiveSerializationEnv }.isInstanceOf(IllegalStateException::class.java)
}
}
}

View File

@ -4,6 +4,7 @@ import joptsimple.OptionSet
import net.corda.client.mock.ErrorFlowsEventGenerator
import net.corda.client.mock.EventGenerator
import net.corda.client.mock.Generator
import net.corda.client.rpc.CordaRPCClient
import net.corda.client.rpc.CordaRPCConnection
import net.corda.core.contracts.Amount
import net.corda.core.identity.CordaX500Name
@ -83,7 +84,7 @@ class ExplorerSimulation(private val options: OptionSet) {
issuerNodeUSD = issuerUSD.get()
arrayOf(notaryNode, aliceNode, bobNode, issuerNodeGBP, issuerNodeUSD).forEach {
println("${it.nodeInfo.legalIdentities.first()} started on ${it.configuration.rpcOptions.address}")
println("${it.nodeInfo.legalIdentities.first()} started on ${it.rpcAddress}")
}
when {
@ -95,19 +96,19 @@ class ExplorerSimulation(private val options: OptionSet) {
private fun setUpRPC() {
// Register with alice to use alice's RPC proxy to create random events.
val aliceClient = aliceNode.rpcClientToNode()
val aliceClient = CordaRPCClient(aliceNode.rpcAddress)
val aliceConnection = aliceClient.start(user.username, user.password)
val aliceRPC = aliceConnection.proxy
val bobClient = bobNode.rpcClientToNode()
val bobClient = CordaRPCClient(bobNode.rpcAddress)
val bobConnection = bobClient.start(user.username, user.password)
val bobRPC = bobConnection.proxy
val issuerClientGBP = issuerNodeGBP.rpcClientToNode()
val issuerClientGBP = CordaRPCClient(issuerNodeGBP.rpcAddress)
val issuerGBPConnection = issuerClientGBP.start(manager.username, manager.password)
val issuerRPCGBP = issuerGBPConnection.proxy
val issuerClientUSD = issuerNodeUSD.rpcClientToNode()
val issuerClientUSD = CordaRPCClient(issuerNodeUSD.rpcAddress)
val issuerUSDConnection = issuerClientUSD.start(manager.username, manager.password)
val issuerRPCUSD = issuerUSDConnection.proxy

View File

@ -28,6 +28,7 @@ import net.corda.testing.driver.JmxPolicy
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.driver
import net.corda.testing.driver.internal.NodeHandleInternal
import net.corda.testing.node.NotarySpec
import net.corda.testing.node.internal.*
import org.apache.activemq.artemis.api.core.SimpleString
@ -255,7 +256,7 @@ data class VerifierDriverDSL(private val driverDSL: DriverDSLImpl) : InternalDri
/** Starts a verifier connecting to the specified node */
fun startVerifier(nodeHandle: NodeHandle): CordaFuture<VerifierHandle> {
return startVerifier(nodeHandle.configuration.p2pAddress)
return startVerifier(nodeHandle.p2pAddress)
}
/** Starts a verifier connecting to the specified requestor */
@ -263,8 +264,8 @@ data class VerifierDriverDSL(private val driverDSL: DriverDSLImpl) : InternalDri
return startVerifier(verificationRequestorHandle.p2pAddress)
}
private fun <A> NodeHandle.connectToNode(closure: (ClientSession) -> A): A {
val transport = ArtemisTcpTransport.tcpTransport(ConnectionDirection.Outbound(), configuration.p2pAddress, configuration)
private fun <A> NodeHandleInternal.connectToNode(closure: (ClientSession) -> A): A {
val transport = ArtemisTcpTransport.tcpTransport(ConnectionDirection.Outbound(), p2pAddress, configuration)
val locator = ActiveMQClient.createServerLocatorWithoutHA(transport)
val sessionFactory = locator.createSessionFactory()
val session = sessionFactory.createSession(NODE_USER, NODE_USER, false, true, true, locator.isPreAcknowledge, locator.ackBatchSize)
@ -277,7 +278,7 @@ data class VerifierDriverDSL(private val driverDSL: DriverDSLImpl) : InternalDri
* Waits until [number] verifiers are listening for verification requests coming from the Node. Check
* [VerificationRequestorHandle.waitUntilNumberOfVerifiers] for an equivalent for requestors.
*/
fun NodeHandle.waitUntilNumberOfVerifiers(number: Int) {
fun NodeHandleInternal.waitUntilNumberOfVerifiers(number: Int) {
connectToNode { session ->
poll(driverDSL.executorService, "$number verifiers to come online") {
if (session.queueQuery(SimpleString(VerifierApi.VERIFICATION_REQUESTS_QUEUE_NAME)).consumerCount >= number) {

View File

@ -15,6 +15,7 @@ import net.corda.node.services.config.VerifierType
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.driver.internal.NodeHandleInternal
import net.corda.testing.node.NotarySpec
import org.junit.Rule
import org.junit.Test
@ -139,7 +140,7 @@ class VerifierTests {
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, verifierType = VerifierType.OutOfProcess))
) {
val aliceNode = startNode(providedName = ALICE_NAME).getOrThrow()
val notaryNode = defaultNotaryNode.getOrThrow()
val notaryNode = defaultNotaryNode.getOrThrow() as NodeHandleInternal
val alice = aliceNode.rpc.wellKnownPartyFromX500Name(ALICE_NAME)!!
startVerifier(notaryNode)
aliceNode.rpc.startFlow(::CashIssueFlow, 10.DOLLARS, OpaqueBytes.of(0), defaultNotaryIdentity).returnValue.get()