Merge commit 'fa4b5d16ba6249f85b50851c2f52dc697eebdee6' into aslemmer-merge-19-Feb

This commit is contained in:
Andras Slemmer 2018-02-20 13:26:31 +00:00
commit 6b2b7b6a3c
122 changed files with 1418 additions and 1123 deletions

View File

@ -3663,7 +3663,6 @@ public static final class net.corda.client.jackson.StringToMethodCallParser$Unpa
##
public final class net.corda.testing.driver.Driver extends java.lang.Object
public static final Object driver(net.corda.testing.driver.DriverParameters, kotlin.jvm.functions.Function1)
public static final Object driver(net.corda.testing.driver.DriverParameters, boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, Map, boolean, boolean, boolean, boolean, List, List, net.corda.testing.driver.JmxPolicy, int, kotlin.jvm.functions.Function1)
##
@net.corda.core.DoNotImplement public interface net.corda.testing.driver.DriverDSL
@org.jetbrains.annotations.NotNull public abstract java.nio.file.Path baseDirectory(net.corda.core.identity.CordaX500Name)
@ -3678,12 +3677,12 @@ public final class net.corda.testing.driver.Driver extends java.lang.Object
##
public final class net.corda.testing.driver.DriverParameters extends java.lang.Object
public <init>()
public <init>(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, Map, boolean, boolean, boolean, boolean, List, List, net.corda.testing.driver.JmxPolicy, int)
public <init>(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, Map, boolean, boolean, boolean, boolean, List, List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters)
public final boolean component1()
@org.jetbrains.annotations.NotNull public final List component10()
@org.jetbrains.annotations.NotNull public final List component11()
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.JmxPolicy component12()
public final int component13()
@org.jetbrains.annotations.NotNull public final net.corda.core.node.NetworkParameters component13()
@org.jetbrains.annotations.NotNull public final java.nio.file.Path component2()
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.PortAllocation component3()
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.PortAllocation component4()
@ -3692,14 +3691,14 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O
public final boolean component7()
public final boolean component8()
public final boolean component9()
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters copy(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, Map, boolean, boolean, boolean, boolean, List, List, net.corda.testing.driver.JmxPolicy, int)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters copy(boolean, java.nio.file.Path, net.corda.testing.driver.PortAllocation, net.corda.testing.driver.PortAllocation, Map, boolean, boolean, boolean, boolean, List, List, net.corda.testing.driver.JmxPolicy, net.corda.core.node.NetworkParameters)
public boolean equals(Object)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.PortAllocation getDebugPortAllocation()
@org.jetbrains.annotations.NotNull public final java.nio.file.Path getDriverDirectory()
@org.jetbrains.annotations.NotNull public final List getExtraCordappPackagesToScan()
public final boolean getInitialiseSerialization()
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.JmxPolicy getJmxPolicy()
public final int getMaxTransactionSize()
@org.jetbrains.annotations.NotNull public final net.corda.core.node.NetworkParameters getNetworkParameters()
@org.jetbrains.annotations.NotNull public final List getNotarySpecs()
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.PortAllocation getPortAllocation()
public final boolean getStartNodesInProcess()
@ -3714,6 +3713,7 @@ public final class net.corda.testing.driver.DriverParameters extends java.lang.O
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters setInitialiseSerialization(boolean)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters setIsDebug(boolean)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters setJmxPolicy(net.corda.testing.driver.JmxPolicy)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters setNetworkParameters(net.corda.core.node.NetworkParameters)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters setNotarySpecs(List)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters setPortAllocation(net.corda.testing.driver.PortAllocation)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.DriverParameters setStartNodesInProcess(boolean)
@ -3722,6 +3722,10 @@ 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.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)
@ -3734,61 +3738,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, String)
@ -3810,12 +3768,12 @@ public final class net.corda.testing.driver.NodeParameters extends java.lang.Obj
@org.jetbrains.annotations.NotNull public final net.corda.node.services.config.VerifierType getVerifierType()
public int hashCode()
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.NodeParameters setCustomerOverrides(Map)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.NodeParameters setLogLevel(String)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.NodeParameters setMaximumHeapSize(String)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.NodeParameters setProvidedName(net.corda.core.identity.CordaX500Name)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.NodeParameters setRpcUsers(List)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.NodeParameters setStartInSameProcess(Boolean)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.NodeParameters setVerifierType(net.corda.node.services.config.VerifierType)
@org.jetbrains.annotations.NotNull public final net.corda.testing.driver.NodeParameters ssetLogLevel(String)
public String toString()
##
public final class net.corda.testing.driver.NotaryHandle extends java.lang.Object
@ -3831,6 +3789,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()
@ -3978,7 +3939,7 @@ public final class net.corda.testing.node.MockKeyManagementService extends net.c
@org.jetbrains.annotations.NotNull public Iterable filterMyKeys(Iterable)
@org.jetbrains.annotations.NotNull public java.security.PublicKey freshKey()
@org.jetbrains.annotations.NotNull public net.corda.core.identity.PartyAndCertificate freshKeyAndCert(net.corda.core.identity.PartyAndCertificate, boolean)
@org.jetbrains.annotations.NotNull public final net.corda.node.services.api.IdentityServiceInternal getIdentityService()
@org.jetbrains.annotations.NotNull public final net.corda.core.node.services.IdentityService getIdentityService()
@org.jetbrains.annotations.NotNull public Set getKeys()
@org.jetbrains.annotations.NotNull public net.corda.core.crypto.TransactionSignature sign(net.corda.core.crypto.SignableData, java.security.PublicKey)
@org.jetbrains.annotations.NotNull public net.corda.core.crypto.DigitalSignature$WithKey sign(byte[], java.security.PublicKey)
@ -3986,144 +3947,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$ServiceAffinityExecutor 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()
@org.jetbrains.annotations.Nullable public net.corda.node.services.config.GraphiteOptions getGraphiteOptions()
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)
@ -4148,9 +4032,9 @@ public final class net.corda.testing.node.MockNodeParameters extends java.lang.O
##
public class net.corda.testing.node.MockServices extends java.lang.Object implements net.corda.core.node.StateLoader, net.corda.core.node.ServiceHub
public <init>(List, net.corda.core.identity.CordaX500Name)
public <init>(List, net.corda.node.services.api.IdentityServiceInternal, net.corda.core.identity.CordaX500Name)
public <init>(List, net.corda.core.node.services.IdentityService, net.corda.core.identity.CordaX500Name)
public <init>(net.corda.core.identity.CordaX500Name)
public <init>(net.corda.node.services.api.IdentityServiceInternal, net.corda.core.identity.CordaX500Name)
public <init>(net.corda.core.node.services.IdentityService, net.corda.core.identity.CordaX500Name)
@org.jetbrains.annotations.NotNull public net.corda.core.transactions.SignedTransaction addSignature(net.corda.core.transactions.SignedTransaction)
@org.jetbrains.annotations.NotNull public net.corda.core.transactions.SignedTransaction addSignature(net.corda.core.transactions.SignedTransaction, java.security.PublicKey)
@org.jetbrains.annotations.NotNull public net.corda.core.serialization.SerializeAsToken cordaService(Class)
@ -4163,7 +4047,7 @@ public class net.corda.testing.node.MockServices extends java.lang.Object implem
@org.jetbrains.annotations.NotNull public net.corda.core.node.services.ContractUpgradeService getContractUpgradeService()
@org.jetbrains.annotations.NotNull public net.corda.core.cordapp.CordappProvider getCordappProvider()
@org.jetbrains.annotations.NotNull public final com.google.common.collect.MutableClassToInstanceMap getCordappServices()
@org.jetbrains.annotations.NotNull public net.corda.node.services.api.IdentityServiceInternal getIdentityService()
@org.jetbrains.annotations.NotNull public net.corda.core.node.services.IdentityService getIdentityService()
@org.jetbrains.annotations.NotNull public net.corda.core.node.services.KeyManagementService getKeyManagementService()
@org.jetbrains.annotations.NotNull public static final net.corda.node.VersionInfo getMOCK_VERSION_INFO()
@org.jetbrains.annotations.NotNull public final net.corda.testing.services.MockCordappProvider getMockCordappProvider()
@ -4275,11 +4159,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

@ -201,6 +201,10 @@ allprojects {
systemProperty(it, property)
}
}
if (System.getProperty("test.maxParallelForks") != null) {
maxParallelForks = Integer.valueOf(System.getProperty("test.maxParallelForks"))
}
}
group 'com.r3.corda'

View File

@ -29,11 +29,12 @@ import net.corda.finance.flows.CashPaymentFlow
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.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.node.User
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
import net.corda.testing.internal.toDatabaseSchemaName
import net.corda.testing.node.User
import org.junit.ClassRule
import org.junit.Test
import rx.Observable
@ -61,7 +62,7 @@ class NodeMonitorModelTest : IntegrationTest() {
}
private fun setup(runTest: () -> Unit) {
driver(extraCordappPackagesToScan = listOf("net.corda.finance")) {
driver(DriverParameters(extraCordappPackagesToScan = listOf("net.corda.finance"))) {
val cashUser = User("user1", "test", permissions = setOf(
startFlow<CashIssueFlow>(),
startFlow<CashPaymentFlow>(),
@ -85,7 +86,7 @@ class NodeMonitorModelTest : IntegrationTest() {
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
@ -93,7 +94,7 @@ class NodeMonitorModelTest : IntegrationTest() {
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

@ -9,6 +9,7 @@ import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.getOrThrow
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
@ -36,7 +37,7 @@ class BlacklistKotlinClosureTest : IntegrationTest() {
@Test
fun `closure sent via RPC`() {
driver(startNodesInProcess = true) {
driver(DriverParameters(startNodesInProcess = true)) {
val rpc = startNode(providedName = ALICE_NAME).getOrThrow().rpc
val packet = Packet { EVIL }
assertThatExceptionOfType(KryoException::class.java)

View File

@ -27,12 +27,11 @@ class X509EdDSAEngine : Signature {
override fun engineInitSign(privateKey: PrivateKey, random: SecureRandom) = engine.initSign(privateKey, random)
override fun engineInitVerify(publicKey: PublicKey) {
val parsedKey = if (publicKey is sun.security.x509.X509Key) {
EdDSAPublicKey(X509EncodedKeySpec(publicKey.encoded))
} else {
publicKey
val parsedKey = try {
publicKey as? EdDSAPublicKey ?: EdDSAPublicKey(X509EncodedKeySpec(publicKey.encoded))
} catch(e: Exception) {
throw (InvalidKeyException(e.message))
}
engine.initVerify(parsedKey)
}

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 org.junit.Assert.fail;
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", "net.corda.finance.schemas"))
mockNet = InternalMockNetwork(cordappPackages = listOf("net.corda.testing.contracts", "net.corda.finance.contracts.asset", "net.corda.core.flows", "net.corda.finance.schemas"))
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

@ -114,4 +114,12 @@ class X509EdDSAEngineTest {
engine.verify(signature)
}
}
/** Verify will fail if the input public key cannot be converted to EdDSA public key. */
@Test
fun `verify with non-supported key type fails`() {
val engine = EdDSAEngine()
val keyPair = Crypto.deriveKeyPairFromEntropy(Crypto.ECDSA_SECP256K1_SHA256, BigInteger.valueOf(SEED))
assertFailsWith<InvalidKeyException> { engine.initVerify(keyPair.public) }
}
}

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

@ -6,6 +6,8 @@ from previous releases. Please refer to :doc:`upgrade-notes` for detailed instru
UNRELEASED
----------
* Make the serialisation finger-printer a pluggable entity rather than hard wiring into the factory
* Removed blacklisted word checks in Corda X.500 name to allow "Server" or "Node" to be use as part of the legal name.
* Separated our pre-existing Artemis broker into an RPC broker and a P2P broker.
@ -209,6 +211,18 @@ R3 Corda 3.0 Developer Preview
* Marked ``stateMachine`` on ``FlowLogic`` as ``CordaInternal`` to make clear that is it not part of the public api and is
only for internal use
* Provided experimental support for specifying your own webserver to be used instead of the default development
webserver in ``Cordform`` using the ``webserverJar`` argument
* 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``.
* The test utils in ``Expect.kt``, ``SerializationTestHelpers.kt``, ``TestConstants.kt`` and ``TestUtils.kt`` have moved
from the ``net.corda.testing`` package to the ``net.corda.testing.core`` package, and ``FlowStackSnapshot.kt`` has moved to the
``net.corda.testing.services`` package. Moving items out of the ``net.corda.testing.*`` package will help make it clearer which
parts of the api are stable. The bash script ``tools\scripts\update-test-packages.sh`` can be used to smooth the upgrade
process for existing projects.
.. _changelog_v2:
Corda 2.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
@ -15,6 +16,7 @@ import net.corda.finance.flows.CashPaymentFlow
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.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.node.User
import net.corda.testing.internal.IntegrationTest
@ -34,8 +36,10 @@ class IntegrationTestingTutorial : IntegrationTest() {
@Test
fun `alice bob cash exchange example`() {
// START 1
driver(startNodesInProcess = true,
extraCordappPackagesToScan = listOf("net.corda.finance.contracts.asset","net.corda.finance.schemas")) {
driver(DriverParameters(
startNodesInProcess = true,
extraCordappPackagesToScan = listOf("net.corda.finance.contracts.asset","net.corda.finance.schemas")
)) {
val aliceUser = User("aliceUser", "testPassword1", permissions = setOf(
startFlow<CashIssueFlow>(),
startFlow<CashPaymentFlow>(),
@ -56,10 +60,10 @@ class IntegrationTestingTutorial : IntegrationTest() {
// 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
@ -18,6 +19,7 @@ import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.Permissions.Companion.invokeRpc
import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.node.User
import net.corda.testing.driver.driver
import org.graphstream.graph.Edge
@ -48,12 +50,12 @@ fun main(args: Array<String>) {
startFlow<CashExitFlow>(),
invokeRpc(CordaRPCOps::nodeInfo)
))
driver(driverDirectory = baseDirectory, extraCordappPackagesToScan = listOf("net.corda.finance"), waitForAllNodesToFinish = true) {
driver(DriverParameters(driverDirectory = baseDirectory, extraCordappPackagesToScan = listOf("net.corda.finance"), waitForAllNodesToFinish = true)) {
val node = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user)).get()
// 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

@ -5,6 +5,7 @@ import com.nhaarman.mockito_kotlin.whenever
import net.corda.core.contracts.TransactionVerificationException
import net.corda.core.crypto.generateKeyPair
import net.corda.core.identity.CordaX500Name
import net.corda.core.node.services.IdentityService
import net.corda.core.utilities.days
import net.corda.finance.DOLLARS
import net.corda.finance.`issued by`
@ -13,7 +14,6 @@ import net.corda.finance.contracts.CommercialPaper
import net.corda.finance.contracts.ICommercialPaperState
import net.corda.finance.contracts.asset.CASH
import net.corda.finance.contracts.asset.Cash
import net.corda.node.services.api.IdentityServiceInternal
import net.corda.testing.core.*
import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices
@ -38,7 +38,7 @@ class CommercialPaperTest {
@Rule
@JvmField
val testSerialization = SerializationEnvironmentRule()
private val ledgerServices = MockServices(emptyList(), rigorousMock<IdentityServiceInternal>().also {
private val ledgerServices = MockServices(emptyList(), rigorousMock<IdentityService>().also {
doReturn(MEGA_CORP).whenever(it).partyFromKey(MEGA_CORP_PUBKEY)
doReturn(null).whenever(it).partyFromKey(BIG_CORP_PUBKEY)
doReturn(null).whenever(it).partyFromKey(ALICE_PUBKEY)

View File

@ -137,6 +137,25 @@ a single node to run the network map service, by putting its name in the ``netwo
.. warning:: When adding nodes, make sure that there are no port clashes!
Specifying a custom webserver
-----------------------------
By default, any node listing a webport will use the default development webserver, which is not production-ready. You
can use your own webserver JAR instead by using the ``webserverJar`` argument in a ``Cordform`` ``node`` configuration
block:
.. sourcecode:: groovy
node {
name "O=PartyA,L=New York,C=US"
webPort 10005
webserverJar "lib/my_webserver.jar"
}
The webserver JAR will be copied into the node's ``build`` folder with the name ``corda-webserver.jar``.
.. warning:: This is an experimental feature. There is currently no support for reading the webserver's port from the
node's ``node.conf`` file.
Running deployNodes
-------------------
To create the nodes defined in our ``deployNodes`` task, run the following command in a terminal window from the root

View File

@ -24,7 +24,7 @@ import net.corda.node.services.transactions.ValidatingNotaryService
fun main(args: Array<String>) {
// No permissions required as we are not invoking flows.
val user = User("user1", "test", permissions = setOf())
driver(isDebug = true) {
driver(DriverParameters((isDebug = true))) {
startNode(getX509Name("Controller", "London", "root@city.uk.example"), setOf(ServiceInfo(ValidatingNotaryService.type)))
val (nodeA, nodeB, nodeC) = Futures.allAsList(
startNode(getX509Name("NodeA", "Paris", "root@city.fr.example"), rpcUsers = listOf(user)),

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

@ -38,9 +38,10 @@ class Node(private val project: Project) : CordformNode() {
private set
internal lateinit var containerName: String
private set
internal var rpcSettings: RpcSettings = RpcSettings()
private set
internal var webserverJar: String? = null
private set
/**
* Sets whether this node will use HTTPS communication.
@ -79,6 +80,17 @@ class Node(private val project: Project) : CordformNode() {
config = config.withValue("sshd.port", ConfigValueFactory.fromAnyRef(sshdPort))
}
/**
* The webserver JAR to be used by this node.
*
* If not provided, the default development webserver is used.
*
* @param webserverJar The file path of the webserver JAR to use.
*/
fun webserverJar(webserverJar: String) {
this.webserverJar = webserverJar
}
internal fun build() {
if (config.hasPath("webAddress")) {
installWebserverJar()
@ -131,7 +143,15 @@ class Node(private val project: Project) : CordformNode() {
* Installs the corda webserver JAR to the node directory
*/
private fun installWebserverJar() {
val webJar = Cordformation.verifyAndGetRuntimeJar(project, "corda-webserver")
// If no webserver JAR is provided, the default development webserver is used.
val webJar = if (webserverJar == null) {
project.logger.info("Using default development webserver.")
Cordformation.verifyAndGetRuntimeJar(project, "corda-webserver")
} else {
project.logger.info("Using custom webserver: $webserverJar.")
File(webserverJar)
}
project.copy {
it.apply {
from(webJar)

View File

@ -26,6 +26,7 @@ import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.singleIdentity
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.internal.NodeHandleInternal
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
import net.corda.testing.internal.createDevIntermediateCaCertPath
@ -110,11 +111,13 @@ class NodeRegistrationTest : IntegrationTest() {
startNode(providedName = aliceName),
defaultNotaryNode
).transpose().getOrThrow()
alice as NodeHandleInternal
notary as NodeHandleInternal
alice.onlySeesFromNetworkMap(alice, notary)
notary.onlySeesFromNetworkMap(alice, notary)
val genevieve = startNode(providedName = genevieveName).getOrThrow()
genevieve as NodeHandleInternal
// Wait for the nodes to poll again
Thread.sleep(timeoutMillis * 2)
@ -156,7 +159,7 @@ class NodeRegistrationTest : IntegrationTest() {
}
}
private fun NodeHandle.onlySeesFromNetworkMap(vararg nodes: NodeHandle) {
private fun NodeHandleInternal.onlySeesFromNetworkMap(vararg nodes: NodeHandle) {
// Make sure the nodes aren't getting the node infos from their additional directories
val nodeInfosDir = configuration.baseDirectory / CordformNode.NODE_INFO_DIRECTORY
if (nodeInfosDir.exists()) {

View File

@ -106,7 +106,7 @@ const val DEV_CA_TRUST_STORE_PASS: String = "trustpass"
internal object DevCaHelper {
fun loadDevCa(alias: String): CertificateAndKeyPair {
// TODO: Should be identity scheme
val caKeyStore = loadKeyStore(javaClass.classLoader.getResourceAsStream("certificates/$DEV_CA_KEY_STORE_FILE"), "$DEV_CA_KEY_STORE_PASS")
return caKeyStore.getCertificateAndKeyPair(alias, "$DEV_CA_PRIVATE_KEY_PASS")
val caKeyStore = loadKeyStore(javaClass.classLoader.getResourceAsStream("certificates/$DEV_CA_KEY_STORE_FILE"), DEV_CA_KEY_STORE_PASS)
return caKeyStore.getCertificateAndKeyPair(alias, DEV_CA_PRIVATE_KEY_PASS)
}
}

View File

@ -165,7 +165,7 @@ class NetworkBootstrapper {
notaries = notaryInfos,
modifiedTime = Instant.now(),
maxMessageSize = 10485760,
maxTransactionSize = 40000,
maxTransactionSize = Int.MAX_VALUE,
epoch = 1
), overwriteFile = true)

View File

@ -31,7 +31,8 @@ open class ArraySerializer(override val type: Type, factory: SerializerFactory)
"${type.componentType().typeName}$arrayType"
}
override val typeDescriptor by lazy { Symbol.valueOf("$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}") }
override val typeDescriptor by lazy {
Symbol.valueOf("$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}") }
internal val elementType: Type by lazy { type.componentType() }
internal open val typeName by lazy { calcTypeName(type) }

View File

@ -17,7 +17,9 @@ import kotlin.collections.Set
*/
class CollectionSerializer(val declaredType: ParameterizedType, factory: SerializerFactory) : AMQPSerializer<Any> {
override val type: Type = declaredType as? DeserializedParameterizedType ?: DeserializedParameterizedType.make(SerializerFactory.nameForType(declaredType))
override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}")
override val typeDescriptor by lazy {
Symbol.valueOf("$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")
}
companion object {
// NB: Order matters in this map, the most specific classes should be listed at the end

View File

@ -60,7 +60,9 @@ abstract class CustomSerializer<T : Any> : AMQPSerializer<T>, SerializerFor {
override fun isSerializerFor(clazz: Class<*>): Boolean = clazz == this.clazz
override val type: Type get() = clazz
override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${fingerprintForDescriptors(superClassSerializer.typeDescriptor.toString(), nameForType(clazz))}")
override val typeDescriptor by lazy {
Symbol.valueOf("$DESCRIPTOR_DOMAIN:${SerializerFingerPrinter().fingerprintForDescriptors(superClassSerializer.typeDescriptor.toString(), nameForType(clazz))}")
}
private val typeNotation: TypeNotation = RestrictedType(
SerializerFactory.nameForType(clazz),
null,

View File

@ -39,7 +39,8 @@ class EnumEvolutionSerializer(
factory: SerializerFactory,
private val conversions: Map<String, String>,
private val ordinals: Map<String, Int>) : AMQPSerializer<Any> {
override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}")!!
override val typeDescriptor = Symbol.valueOf(
"$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")!!
companion object {
private fun MutableMap<String, String>.mapInPlace(f: (String) -> String) {

View File

@ -11,8 +11,9 @@ import java.lang.reflect.Type
*/
class EnumSerializer(declaredType: Type, declaredClass: Class<*>, factory: SerializerFactory) : AMQPSerializer<Any> {
override val type: Type = declaredType
override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}")!!
private val typeNotation: TypeNotation
override val typeDescriptor = Symbol.valueOf(
"$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")!!
init {
typeNotation = RestrictedType(

View File

@ -0,0 +1,202 @@
package net.corda.nodeapi.internal.serialization.amqp
import com.google.common.hash.Hasher
import com.google.common.hash.Hashing
import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.toBase64
import java.io.NotSerializableException
import java.lang.reflect.*
import java.util.*
/**
* Should be implemented by classes which wish to provide plugable fingerprinting og types for a [SerializerFactory]
*/
interface FingerPrinter {
/**
* Return a unique identifier for a type, usually this will take into account the constituent elements
* of said type such that any modification to any sub element wll generate a different fingerprint
*/
fun fingerprint(type: Type): String
/**
* If required, associate an instance of the fingerprinter with a specific serializer factory
*/
fun setOwner(factory: SerializerFactory)
}
/**
* Implementation of the finger printing mechanism used by default
*/
class SerializerFingerPrinter : FingerPrinter {
private var factory: SerializerFactory? = null
private val ARRAY_HASH: String = "Array = true"
private val ENUM_HASH: String = "Enum = true"
private val ALREADY_SEEN_HASH: String = "Already seen = true"
private val NULLABLE_HASH: String = "Nullable = true"
private val NOT_NULLABLE_HASH: String = "Nullable = false"
private val ANY_TYPE_HASH: String = "Any type = true"
private val TYPE_VARIABLE_HASH: String = "Type variable = true"
private val WILDCARD_TYPE_HASH: String = "Wild card = true"
private val logger by lazy { loggerFor<Schema>() }
override fun setOwner(factory: SerializerFactory) {
this.factory = factory
}
/**
* The method generates a fingerprint for a given JVM [Type] that should be unique to the schema representation.
* Thus it only takes into account properties and types and only supports the same object graph subset as the overall
* serialization code.
*
* The idea being that even for two classes that share the same name but differ in a minor way, the fingerprint will be
* different.
*/
override fun fingerprint(type: Type): String {
return fingerprintForType(
type, null, HashSet(), Hashing.murmur3_128().newHasher(), debugIndent = 1).hash().asBytes().toBase64()
}
private fun isCollectionOrMap(type: Class<*>) =
(Collection::class.java.isAssignableFrom(type) || Map::class.java.isAssignableFrom(type))
&& !EnumSet::class.java.isAssignableFrom(type)
internal fun fingerprintForDescriptors(vararg typeDescriptors: String): String {
val hasher = Hashing.murmur3_128().newHasher()
for (typeDescriptor in typeDescriptors) {
hasher.putUnencodedChars(typeDescriptor)
}
return hasher.hash().asBytes().toBase64()
}
private fun Hasher.fingerprintWithCustomSerializerOrElse(
factory: SerializerFactory,
clazz: Class<*>,
declaredType: Type,
block: () -> Hasher): Hasher {
// Need to check if a custom serializer is applicable
val customSerializer = factory.findCustomSerializer(clazz, declaredType)
return if (customSerializer != null) {
putUnencodedChars(customSerializer.typeDescriptor)
} else {
block()
}
}
// This method concatenates various elements of the types recursively as unencoded strings into the hasher,
// effectively creating a unique string for a type which we then hash in the calling function above.
private fun fingerprintForType(type: Type, contextType: Type?, alreadySeen: MutableSet<Type>,
hasher: Hasher, debugIndent: Int = 1): Hasher {
// We don't include Example<?> and Example<T> where type is ? or T in this otherwise we
// generate different fingerprints for class Outer<T>(val a: Inner<T>) when serialising
// and deserializing (assuming deserialization is occurring in a factory that didn't
// serialise the object in the first place (and thus the cache lookup fails). This is also
// true of Any, where we need Example<A, B> and Example<?, ?> to have the same fingerprint
return if ((type in alreadySeen)
&& (type !is SerializerFactory.AnyType)
&& (type !is TypeVariable<*>)
&& (type !is WildcardType)) {
hasher.putUnencodedChars(ALREADY_SEEN_HASH)
} else {
alreadySeen += type
try {
when (type) {
is ParameterizedType -> {
// Hash the rawType + params
val clazz = type.rawType as Class<*>
val startingHash = if (isCollectionOrMap(clazz)) {
hasher.putUnencodedChars(clazz.name)
} else {
hasher.fingerprintWithCustomSerializerOrElse(factory!!, clazz, type) {
fingerprintForObject(type, type, alreadySeen, hasher, factory!!, debugIndent + 1)
}
}
// ... and concatenate the type data for each parameter type.
type.actualTypeArguments.fold(startingHash) { orig, paramType ->
fingerprintForType(paramType, type, alreadySeen, orig, debugIndent + 1)
}
}
// Previously, we drew a distinction between TypeVariable, WildcardType, and AnyType, changing
// the signature of the fingerprinted object. This, however, doesn't work as it breaks bi-
// directional fingerprints. That is, fingerprinting a concrete instance of a generic
// type (Example<Int>), creates a different fingerprint from the generic type itself (Example<T>)
//
// On serialization Example<Int> is treated as Example<T>, a TypeVariable
// On deserialisation it is seen as Example<?>, A WildcardType *and* a TypeVariable
// Note: AnyType is a special case of WildcardType used in other parts of the
// serializer so both cases need to be dealt with here
//
// If we treat these types as fundamentally different and alter the fingerprint we will
// end up breaking into the evolver when we shouldn't or, worse, evoking the carpenter.
is SerializerFactory.AnyType,
is WildcardType,
is TypeVariable<*> -> {
hasher.putUnencodedChars("?").putUnencodedChars(ANY_TYPE_HASH)
}
is Class<*> -> {
if (type.isArray) {
fingerprintForType(type.componentType, contextType, alreadySeen, hasher, debugIndent + 1)
.putUnencodedChars(ARRAY_HASH)
} else if (SerializerFactory.isPrimitive(type)) {
hasher.putUnencodedChars(type.name)
} else if (isCollectionOrMap(type)) {
hasher.putUnencodedChars(type.name)
} else if (type.isEnum) {
// ensures any change to the enum (adding constants) will trigger the need for evolution
hasher.apply {
type.enumConstants.forEach {
putUnencodedChars(it.toString())
}
}.putUnencodedChars(type.name).putUnencodedChars(ENUM_HASH)
} else {
hasher.fingerprintWithCustomSerializerOrElse(factory!!, type, type) {
if (type.kotlin.objectInstance != null) {
// TODO: name collision is too likely for kotlin objects, we need to introduce some reference
// to the CorDapp but maybe reference to the JAR in the short term.
hasher.putUnencodedChars(type.name)
} else {
fingerprintForObject(type, type, alreadySeen, hasher, factory!!, debugIndent + 1)
}
}
}
}
// Hash the element type + some array hash
is GenericArrayType -> {
fingerprintForType(type.genericComponentType, contextType, alreadySeen,
hasher, debugIndent + 1).putUnencodedChars(ARRAY_HASH)
}
else -> throw NotSerializableException("Don't know how to hash")
}
} catch (e: NotSerializableException) {
val msg = "${e.message} -> $type"
logger.error(msg, e)
throw NotSerializableException(msg)
}
}
}
private fun fingerprintForObject(
type: Type,
contextType: Type?,
alreadySeen: MutableSet<Type>,
hasher: Hasher,
factory: SerializerFactory,
debugIndent: Int = 0): Hasher {
// Hash the class + properties + interfaces
val name = type.asClass()?.name
?: throw NotSerializableException("Expected only Class or ParameterizedType but found $type")
propertiesForSerialization(constructorForDeserialization(type), contextType ?: type, factory)
.serializationOrder
.fold(hasher.putUnencodedChars(name)) { orig, prop ->
fingerprintForType(prop.getter.resolvedType, type, alreadySeen, orig, debugIndent + 1)
.putUnencodedChars(prop.getter.name)
.putUnencodedChars(if (prop.getter.mandatory) NOT_NULLABLE_HASH else NULLABLE_HASH)
}
interfacesForSerialization(type, factory).map { fingerprintForType(it, type, alreadySeen, hasher, debugIndent + 1) }
return hasher
}
}

View File

@ -19,7 +19,8 @@ private typealias MapCreationFunction = (Map<*, *>) -> Map<*, *>
*/
class MapSerializer(private val declaredType: ParameterizedType, factory: SerializerFactory) : AMQPSerializer<Any> {
override val type: Type = declaredType as? DeserializedParameterizedType ?: DeserializedParameterizedType.make(SerializerFactory.nameForType(declaredType))
override val typeDescriptor: Symbol = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}")
override val typeDescriptor: Symbol = Symbol.valueOf(
"$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")
companion object {
// NB: Order matters in this map, the most specific classes should be listed at the end

View File

@ -31,7 +31,8 @@ open class ObjectSerializer(val clazz: Type, factory: SerializerFactory) : AMQPS
private val typeName = nameForType(clazz)
override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}")
override val typeDescriptor = Symbol.valueOf(
"$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")
// We restrict to only those annotated or whitelisted
private val interfaces = interfacesForSerialization(clazz, factory)

View File

@ -1,19 +1,13 @@
package net.corda.nodeapi.internal.serialization.amqp
import com.google.common.hash.Hasher
import com.google.common.hash.Hashing
import net.corda.core.internal.uncheckedCast
import net.corda.nodeapi.internal.serialization.CordaSerializationMagic
import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.toBase64
import org.apache.qpid.proton.amqp.DescribedType
import org.apache.qpid.proton.amqp.Symbol
import org.apache.qpid.proton.amqp.UnsignedInteger
import org.apache.qpid.proton.amqp.UnsignedLong
import org.apache.qpid.proton.codec.DescribedTypeConstructor
import java.io.NotSerializableException
import java.lang.reflect.*
import java.util.*
import net.corda.nodeapi.internal.serialization.carpenter.Field as CarpenterField
import net.corda.nodeapi.internal.serialization.carpenter.Schema as CarpenterSchema
@ -92,7 +86,14 @@ data class Descriptor(val name: Symbol?, val code: UnsignedLong? = null) : Descr
}
}
data class Field(val name: String, val type: String, val requires: List<String>, val default: String?, val label: String?, val mandatory: Boolean, val multiple: Boolean) : DescribedType {
data class Field(
val name: String,
val type: String,
val requires: List<String>,
val default: String?,
val label: String?,
val mandatory: Boolean,
val multiple: Boolean) : DescribedType {
companion object : DescribedTypeConstructor<Field> {
val DESCRIPTOR = AMQPDescriptorRegistry.FIELD.amqpDescriptor
@ -302,162 +303,4 @@ data class ReferencedObject(private val refCounter: Int) : DescribedType {
override fun toString(): String = "<refObject refCounter=$refCounter/>"
}
private val ARRAY_HASH: String = "Array = true"
private val ENUM_HASH: String = "Enum = true"
private val ALREADY_SEEN_HASH: String = "Already seen = true"
private val NULLABLE_HASH: String = "Nullable = true"
private val NOT_NULLABLE_HASH: String = "Nullable = false"
private val ANY_TYPE_HASH: String = "Any type = true"
private val TYPE_VARIABLE_HASH: String = "Type variable = true"
private val WILDCARD_TYPE_HASH: String = "Wild card = true"
private val logger by lazy { loggerFor<Schema>() }
/**
* The method generates a fingerprint for a given JVM [Type] that should be unique to the schema representation.
* Thus it only takes into account properties and types and only supports the same object graph subset as the overall
* serialization code.
*
* The idea being that even for two classes that share the same name but differ in a minor way, the fingerprint will be
* different.
*/
// TODO: write tests
internal fun fingerprintForType(type: Type, factory: SerializerFactory): String {
return fingerprintForType(type, null, HashSet(), Hashing.murmur3_128().newHasher(), factory).hash().asBytes().toBase64()
}
internal fun fingerprintForDescriptors(vararg typeDescriptors: String): String {
val hasher = Hashing.murmur3_128().newHasher()
for (typeDescriptor in typeDescriptors) {
hasher.putUnencodedChars(typeDescriptor)
}
return hasher.hash().asBytes().toBase64()
}
private fun Hasher.fingerprintWithCustomSerializerOrElse(factory: SerializerFactory, clazz: Class<*>, declaredType: Type, block: () -> Hasher): Hasher {
// Need to check if a custom serializer is applicable
val customSerializer = factory.findCustomSerializer(clazz, declaredType)
return if (customSerializer != null) {
putUnencodedChars(customSerializer.typeDescriptor)
} else {
block()
}
}
// This method concatenates various elements of the types recursively as unencoded strings into the hasher, effectively
// creating a unique string for a type which we then hash in the calling function above.
private fun fingerprintForType(type: Type, contextType: Type?, alreadySeen: MutableSet<Type>,
hasher: Hasher, factory: SerializerFactory, debugIndent: Int = 1): Hasher {
// We don't include Example<?> and Example<T> where type is ? or T in this otherwise we
// generate different fingerprints for class Outer<T>(val a: Inner<T>) when serialising
// and deserializing (assuming deserialization is occurring in a factory that didn't
// serialise the object in the first place (and thus the cache lookup fails). This is also
// true of Any, where we need Example<A, B> and Example<?, ?> to have the same fingerprint
return if ((type in alreadySeen)
&& (type !is SerializerFactory.AnyType)
&& (type !is TypeVariable<*>)
&& (type !is WildcardType)) {
hasher.putUnencodedChars(ALREADY_SEEN_HASH)
} else {
alreadySeen += type
try {
when (type) {
is ParameterizedType -> {
// Hash the rawType + params
val clazz = type.rawType as Class<*>
val startingHash = if (isCollectionOrMap(clazz)) {
hasher.putUnencodedChars(clazz.name)
} else {
hasher.fingerprintWithCustomSerializerOrElse(factory, clazz, type) {
fingerprintForObject(type, type, alreadySeen, hasher, factory, debugIndent+1)
}
}
// ... and concatenate the type data for each parameter type.
type.actualTypeArguments.fold(startingHash) { orig, paramType ->
fingerprintForType(paramType, type, alreadySeen, orig, factory, debugIndent+1)
}
}
// Previously, we drew a distinction between TypeVariable, WildcardType, and AnyType, changing
// the signature of the fingerprinted object. This, however, doesn't work as it breaks bi-
// directional fingerprints. That is, fingerprinting a concrete instance of a generic
// type (Example<Int>), creates a different fingerprint from the generic type itself (Example<T>)
//
// On serialization Example<Int> is treated as Example<T>, a TypeVariable
// On deserialisation it is seen as Example<?>, A WildcardType *and* a TypeVariable
// Note: AnyType is a special case of WildcardType used in other parts of the
// serializer so both cases need to be dealt with here
//
// If we treat these types as fundamentally different and alter the fingerprint we will
// end up breaking into the evolver when we shouldn't or, worse, evoking the carpenter.
is SerializerFactory.AnyType,
is WildcardType,
is TypeVariable<*> -> {
hasher.putUnencodedChars("?").putUnencodedChars(ANY_TYPE_HASH)
}
is Class<*> -> {
if (type.isArray) {
fingerprintForType(type.componentType, contextType, alreadySeen, hasher, factory, debugIndent+1)
.putUnencodedChars(ARRAY_HASH)
} else if (SerializerFactory.isPrimitive(type)) {
hasher.putUnencodedChars(type.name)
} else if (isCollectionOrMap(type)) {
hasher.putUnencodedChars(type.name)
} else if (type.isEnum) {
// ensures any change to the enum (adding constants) will trigger the need for evolution
hasher.apply {
type.enumConstants.forEach {
putUnencodedChars(it.toString())
}
}.putUnencodedChars(type.name).putUnencodedChars(ENUM_HASH)
} else {
hasher.fingerprintWithCustomSerializerOrElse(factory, type, type) {
if (type.kotlin.objectInstance != null) {
// TODO: name collision is too likely for kotlin objects, we need to introduce some reference
// to the CorDapp but maybe reference to the JAR in the short term.
hasher.putUnencodedChars(type.name)
} else {
fingerprintForObject(type, type, alreadySeen, hasher, factory, debugIndent+1)
}
}
}
}
// Hash the element type + some array hash
is GenericArrayType -> {
fingerprintForType(type.genericComponentType, contextType, alreadySeen,
hasher, factory, debugIndent+1).putUnencodedChars(ARRAY_HASH)
}
else -> throw NotSerializableException("Don't know how to hash")
}
} catch (e: NotSerializableException) {
val msg = "${e.message} -> $type"
logger.error(msg, e)
throw NotSerializableException(msg)
}
}
}
private fun isCollectionOrMap(type: Class<*>) = (Collection::class.java.isAssignableFrom(type) || Map::class.java.isAssignableFrom(type)) &&
!EnumSet::class.java.isAssignableFrom(type)
private fun fingerprintForObject(
type: Type,
contextType: Type?,
alreadySeen: MutableSet<Type>,
hasher: Hasher,
factory: SerializerFactory,
debugIndent: Int = 0): Hasher {
// Hash the class + properties + interfaces
val name = type.asClass()?.name ?: throw NotSerializableException("Expected only Class or ParameterizedType but found $type")
propertiesForSerialization(constructorForDeserialization(type), contextType ?: type, factory)
.serializationOrder
.fold(hasher.putUnencodedChars(name)) { orig, prop ->
fingerprintForType(prop.getter.resolvedType, type, alreadySeen, orig, factory, debugIndent+1)
.putUnencodedChars(prop.getter.name)
.putUnencodedChars(if (prop.getter.mandatory) NOT_NULLABLE_HASH else NULLABLE_HASH)
}
interfacesForSerialization(type, factory).map { fingerprintForType(it, type, alreadySeen, hasher, factory, debugIndent+1) }
return hasher
}

View File

@ -40,7 +40,13 @@ data class FactorySchemaAndDescriptor(val schemas: SerializationSchemas, val typ
open class SerializerFactory(
val whitelist: ClassWhitelist,
cl: ClassLoader,
private val evolutionSerializerGetter: EvolutionSerializerGetterBase = EvolutionSerializerGetter()) {
private val evolutionSerializerGetter: EvolutionSerializerGetterBase = EvolutionSerializerGetter(),
val fingerPrinter: FingerPrinter = SerializerFingerPrinter()) {
init {
fingerPrinter.setOwner(this)
}
private val serializersByType = ConcurrentHashMap<Type, AMQPSerializer<Any>>()
private val serializersByDescriptor = ConcurrentHashMap<Any, AMQPSerializer<Any>>()
private val customSerializers = CopyOnWriteArrayList<SerializerFor>()

View File

@ -10,7 +10,8 @@ import java.lang.reflect.Type
* want converting back to that singleton instance on the receiving JVM.
*/
class SingletonSerializer(override val type: Class<*>, val singleton: Any, factory: SerializerFactory) : AMQPSerializer<Any> {
override val typeDescriptor = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}")
override val typeDescriptor = Symbol.valueOf(
"$DESCRIPTOR_DOMAIN:${factory.fingerPrinter.fingerprint(type)}")
private val interfaces = interfacesForSerialization(type, factory)

View File

@ -32,10 +32,12 @@ public class ErrorMessageTests {
@Test
public void testJavaConstructorAnnotations() {
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
SerializerFactory factory1 = new SerializerFactory(
AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(),
evolutionSerialiserGetter);
evolutionSerialiserGetter,
fingerPrinter);
SerializationOutput ser = new SerializationOutput(factory1);

View File

@ -29,7 +29,8 @@ public class JavaGenericsTest {
SerializerFactory factory = new SerializerFactory(
AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(),
new EvolutionSerializerGetter());
new EvolutionSerializerGetter(),
new SerializerFingerPrinter());
SerializationOutput ser = new SerializationOutput(factory);
SerializedBytes<?> bytes = ser.serialize(a1);
@ -44,7 +45,8 @@ public class JavaGenericsTest {
SerializerFactory factory = new SerializerFactory(
AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(),
new EvolutionSerializerGetter());
new EvolutionSerializerGetter(),
new SerializerFingerPrinter());
return (new SerializationOutput(factory)).serialize(a);
}
@ -59,7 +61,8 @@ public class JavaGenericsTest {
SerializerFactory factory = new SerializerFactory(
AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(),
new EvolutionSerializerGetter());
new EvolutionSerializerGetter(),
new SerializerFingerPrinter());
DeserializationInput des = new DeserializationInput(factory);
return des.deserialize(bytes, A.class);
@ -83,7 +86,8 @@ public class JavaGenericsTest {
SerializerFactory factory = new SerializerFactory(
AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(),
new EvolutionSerializerGetter());
new EvolutionSerializerGetter(),
new SerializerFingerPrinter());
SerializedBytes<?> bytes = forceWildcardSerializeFactory(new A(new Inner(29)), factory);
Inner i = (Inner)forceWildcardDeserializeFactory(bytes, factory).getT();

View File

@ -76,9 +76,9 @@ public class JavaPrivatePropertyTests {
@Test
public void singlePrivateBooleanWithConstructor() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
EvolutionSerializerGetterBase evolutionSerializerGetter = new EvolutionSerializerGetter();
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
evolutionSerializerGetter);
new EvolutionSerializerGetter(),
new SerializerFingerPrinter());
SerializationOutput ser = new SerializationOutput(factory);
DeserializationInput des = new DeserializationInput(factory);
@ -89,9 +89,10 @@ public class JavaPrivatePropertyTests {
@Test
public void singlePrivateBooleanWithNoConstructor() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
EvolutionSerializerGetterBase evolutionSerializerGetter = new EvolutionSerializerGetter();
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
evolutionSerializerGetter);
new EvolutionSerializerGetter(),
new SerializerFingerPrinter());
SerializationOutput ser = new SerializationOutput(factory);
DeserializationInput des = new DeserializationInput(factory);
@ -103,9 +104,9 @@ public class JavaPrivatePropertyTests {
@Test
public void testCapitilsationOfIs() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
EvolutionSerializerGetterBase evolutionSerializerGetter = new EvolutionSerializerGetter();
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
evolutionSerializerGetter);
new EvolutionSerializerGetter(),
new SerializerFingerPrinter());
SerializationOutput ser = new SerializationOutput(factory);
DeserializationInput des = new DeserializationInput(factory);
@ -119,9 +120,9 @@ public class JavaPrivatePropertyTests {
@Test
public void singlePrivateIntWithBoolean() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
EvolutionSerializerGetterBase evolutionSerializerGetter = new EvolutionSerializerGetter();
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
evolutionSerializerGetter);
new EvolutionSerializerGetter(),
new SerializerFingerPrinter());
SerializationOutput ser = new SerializationOutput(factory);
DeserializationInput des = new DeserializationInput(factory);
@ -134,9 +135,10 @@ public class JavaPrivatePropertyTests {
@Test
public void singlePrivateWithConstructor() throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
EvolutionSerializerGetterBase evolutionSerializerGetter = new EvolutionSerializerGetter();
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
evolutionSerializerGetter);
new EvolutionSerializerGetter(),
new SerializerFingerPrinter());
SerializationOutput ser = new SerializationOutput(factory);
DeserializationInput des = new DeserializationInput(factory);
@ -164,9 +166,11 @@ public class JavaPrivatePropertyTests {
@Test
public void singlePrivateWithConstructorAndGetter()
throws NotSerializableException, NoSuchFieldException, IllegalAccessException {
EvolutionSerializerGetterBase evolutionSerializerGetter = new EvolutionSerializerGetter();
SerializerFactory factory = new SerializerFactory(AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(), evolutionSerializerGetter);
ClassLoader.getSystemClassLoader(),
new EvolutionSerializerGetter(),
new SerializerFingerPrinter());
SerializationOutput ser = new SerializationOutput(factory);
DeserializationInput des = new DeserializationInput(factory);

View File

@ -29,9 +29,9 @@ public class JavaSerialiseEnumTests {
public void testJavaConstructorAnnotations() throws NotSerializableException {
Bra bra = new Bra(Bras.UNDERWIRE);
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
SerializerFactory factory1 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
evolutionSerialiserGetter);
new EvolutionSerializerGetter(),
new SerializerFingerPrinter());
SerializationOutput ser = new SerializationOutput(factory1);
SerializedBytes<Object> bytes = ser.serialize(bra);
}

View File

@ -173,10 +173,13 @@ public class JavaSerializationOutputTests {
private Object serdes(Object obj) throws NotSerializableException {
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
SerializerFactory factory1 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
evolutionSerialiserGetter);
evolutionSerialiserGetter,
fingerPrinter);
SerializerFactory factory2 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
evolutionSerialiserGetter);
evolutionSerialiserGetter,
fingerPrinter);
SerializationOutput ser = new SerializationOutput(factory1);
SerializedBytes<Object> bytes = ser.serialize(obj);

View File

@ -125,9 +125,12 @@ public class ListsSerializationJavaTest {
// Have to have own version as Kotlin inline functions cannot be easily called from Java
private static <T> void assertEqualAfterRoundTripSerialization(T container, Class<T> clazz) throws Exception {
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
SerializerFactory factory1 = new SerializerFactory(AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
evolutionSerialiserGetter);
EvolutionSerializerGetterBase evolutionSerializerGetter = new EvolutionSerializerGetter();
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
SerializerFactory factory1 = new SerializerFactory(
AllWhitelist.INSTANCE, ClassLoader.getSystemClassLoader(),
evolutionSerializerGetter,
fingerPrinter);
SerializationOutput ser = new SerializationOutput(factory1);
SerializedBytes<Object> bytes = ser.serialize(container);
DeserializationInput des = new DeserializationInput(factory1);

View File

@ -110,10 +110,12 @@ public class SetterConstructorTests {
@Test
public void serialiseC() throws NotSerializableException {
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
SerializerFactory factory1 = new SerializerFactory(
AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(),
evolutionSerialiserGetter);
evolutionSerialiserGetter,
fingerPrinter);
SerializationOutput ser = new SerializationOutput(factory1);
@ -184,10 +186,12 @@ public class SetterConstructorTests {
@Test
public void deserialiseC() throws NotSerializableException {
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
SerializerFactory factory1 = new SerializerFactory(
AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(),
evolutionSerialiserGetter);
evolutionSerialiserGetter,
fingerPrinter);
C cPre1 = new C();
@ -251,10 +255,12 @@ public class SetterConstructorTests {
@Test
public void serialiseOuterAndInner() throws NotSerializableException {
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
SerializerFactory factory1 = new SerializerFactory(
AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(),
evolutionSerialiserGetter);
evolutionSerialiserGetter,
fingerPrinter);
Inner1 i1 = new Inner1("Hello");
Inner2 i2 = new Inner2();
@ -277,10 +283,12 @@ public class SetterConstructorTests {
@Test
public void typeMistmatch() throws NotSerializableException {
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
SerializerFactory factory1 = new SerializerFactory(
AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(),
evolutionSerialiserGetter);
evolutionSerialiserGetter,
fingerPrinter);
TypeMismatch tm = new TypeMismatch();
tm.setA(10);
@ -293,10 +301,12 @@ public class SetterConstructorTests {
@Test
public void typeMistmatch2() throws NotSerializableException {
EvolutionSerializerGetterBase evolutionSerialiserGetter = new EvolutionSerializerGetter();
FingerPrinter fingerPrinter = new SerializerFingerPrinter();
SerializerFactory factory1 = new SerializerFactory(
AllWhitelist.INSTANCE,
ClassLoader.getSystemClassLoader(),
evolutionSerialiserGetter);
evolutionSerialiserGetter,
fingerPrinter);
TypeMismatch2 tm = new TypeMismatch2();
tm.setA("10");

View File

@ -0,0 +1,55 @@
package net.corda.nodeapi.internal.serialization.amqp
import org.junit.Test
import java.lang.reflect.Type
import kotlin.test.assertEquals
import net.corda.nodeapi.internal.serialization.AllWhitelist
class FingerPrinterTesting : FingerPrinter {
private var index = 0
private val cache = mutableMapOf<Type, String>()
override fun fingerprint(type: Type): String {
return cache.computeIfAbsent(type) { index++.toString() }
}
override fun setOwner(factory: SerializerFactory) {
return
}
@Suppress("UNUSED")
fun changeFingerprint(type: Type) {
cache.computeIfAbsent(type) { "" }.apply { index++.toString() }
}
}
class FingerPrinterTestingTests {
companion object {
val VERBOSE = true
}
@Test
fun testingTest() {
val fpt = FingerPrinterTesting()
assertEquals ("0", fpt.fingerprint(Integer::class.java))
assertEquals ("1", fpt.fingerprint(String::class.java))
assertEquals ("0", fpt.fingerprint(Integer::class.java))
assertEquals ("1", fpt.fingerprint(String::class.java))
}
@Test
fun worksAsReplacement() {
data class C (val a: Int, val b: Long)
val factory = SerializerFactory(
AllWhitelist,
ClassLoader.getSystemClassLoader(),
EvolutionSerializerGetterTesting(),
FingerPrinterTesting())
val blob = TestSerializationOutput(VERBOSE, factory).serializeAndReturnSchema(C(1, 2L))
assertEquals (1, blob.schema.types.size)
assertEquals ("<descriptor name=\"net.corda:0\"/>", blob.schema.types[0].descriptor.toString())
}
}

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
@ -13,6 +14,7 @@ import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
@ -37,7 +39,7 @@ class BootTests : IntegrationTest() {
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")
}
@ -47,9 +49,9 @@ class BootTests : IntegrationTest() {
fun `double node start doesn't write into log file`() {
val logConfigFile = projectRootDir / "config" / "dev" / "log4j2.xml"
assertThat(logConfigFile).isRegularFile()
driver(isDebug = true, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString())) {
driver(DriverParameters(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
@ -36,7 +37,7 @@ class CordappScanningDriverTest : IntegrationTest() {
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

@ -9,6 +9,7 @@ import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
@ -27,7 +28,7 @@ class NodeKeystoreCheckTest : IntegrationTest() {
@Test
fun `starting node in non-dev mode with no key store`() {
driver(startNodesInProcess = true, notarySpecs = emptyList()) {
driver(DriverParameters(startNodesInProcess = true, notarySpecs = emptyList())) {
assertThatThrownBy {
startNode(customOverrides = mapOf("devMode" to false)).getOrThrow()
}.hasMessageContaining("Identity certificate not found")
@ -36,7 +37,7 @@ class NodeKeystoreCheckTest : IntegrationTest() {
@Test
fun `node should throw exception if cert path doesn't chain to the trust root`() {
driver(startNodesInProcess = true, notarySpecs = emptyList()) {
driver(DriverParameters(startNodesInProcess = true, notarySpecs = emptyList())) {
// Create keystores
val keystorePassword = "password"
val config = object : SSLConfiguration {

View File

@ -6,6 +6,7 @@ import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.getOrThrow
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
@ -25,7 +26,7 @@ class NodeUnloadHandlerTests : IntegrationTest() {
@Test
fun `should be able to register run on stop lambda`() {
driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.node"), isDebug = true) {
driver(DriverParameters(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.node"), isDebug = true)) {
startNode(providedName = DUMMY_BANK_A_NAME).getOrThrow()
// just want to fall off the end of this for the mo...
}

View File

@ -14,6 +14,7 @@ import net.corda.core.utilities.unwrap
import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
@ -101,7 +102,7 @@ class SSHServerTest : IntegrationTest() {
fun `ssh respects permissions`() {
val user = User("u", "p", setOf(startFlow<FlowICanRun>()))
// The driver will automatically pick up the annotated flows below
driver(isDebug = true) {
driver(DriverParameters(isDebug = true)) {
val node = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user),
customOverrides = mapOf("sshd" to mapOf("port" to 2222)))
node.getOrThrow()
@ -131,7 +132,7 @@ class SSHServerTest : IntegrationTest() {
fun `ssh runs flows`() {
val user = User("u", "p", setOf(startFlow<FlowICanRun>()))
// The driver will automatically pick up the annotated flows below
driver(isDebug = true) {
driver(DriverParameters(isDebug = true)) {
val node = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user),
customOverrides = mapOf("sshd" to mapOf("port" to 2222)))
node.getOrThrow()

View File

@ -19,7 +19,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
@ -33,7 +32,7 @@ import net.corda.testing.core.dummyCommand
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
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
@ -53,7 +52,7 @@ class BFTNotaryServiceTests : IntegrationTest() {
private lateinit var mockNet: MockNetwork
private lateinit var notary: Party
private lateinit var node: StartedNode<MockNode>
private lateinit var node: StartedMockNode
@Before
fun before() {
@ -163,7 +162,7 @@ class BFTNotaryServiceTests : IntegrationTest() {
}
}
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
@ -14,7 +15,9 @@ import net.corda.finance.flows.CashPaymentFlow
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.DriverParameters
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.OutOfProcess
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
@ -32,7 +35,7 @@ import java.util.*
class DistributedServiceTests : IntegrationTest() {
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>>
@ -48,7 +51,7 @@ class DistributedServiceTests : IntegrationTest() {
invokeRpc(CordaRPCOps::nodeInfo),
invokeRpc(CordaRPCOps::stateMachinesFeed))
)
driver(
driver(DriverParameters(
extraCordappPackagesToScan = listOf("net.corda.finance.contracts", "net.corda.finance.schemas"),
notarySpecs = listOf(
NotarySpec(
@ -56,10 +59,10 @@ class DistributedServiceTests : IntegrationTest() {
rpcUsers = listOf(testUser),
cluster = DummyClusterSpec(clusterSize = 3, compositeServiceIdentity = compositeIdentity))
)
) {
)) {
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)
@ -72,7 +75,7 @@ class DistributedServiceTests : IntegrationTest() {
// 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

@ -13,7 +13,6 @@ import net.corda.core.identity.Party
import net.corda.core.node.NotaryInfo
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.getOrThrow
import net.corda.node.internal.StartedNode
import net.corda.node.services.config.MySQLConfiguration
import net.corda.node.services.config.NotaryConfig
import net.corda.nodeapi.internal.DevIdentityGenerator
@ -24,11 +23,8 @@ import net.corda.testing.core.chooseIdentity
import net.corda.testing.core.dummyCommand
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
import net.corda.testing.node.MockNetwork
import net.corda.testing.node.MockNodeParameters
import net.corda.testing.node.*
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.testing.node.inMemoryH2DataSourceConfig
import net.corda.testing.node.startFlow
import org.junit.After
import org.junit.Before
import org.junit.ClassRule
@ -46,9 +42,9 @@ class MySQLNotaryServiceTests : IntegrationTest() {
}
private lateinit var mockNet: MockNetwork
private lateinit var node: StartedNode<MockNetwork.MockNode>
private lateinit var node: StartedMockNode
private lateinit var notaryParty: Party
private lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
private lateinit var notaryNode: StartedMockNode
@Before
fun before() {
@ -127,7 +123,7 @@ class MySQLNotaryServiceTests : IntegrationTest() {
checkSignature(signatureRetry)
}
private fun createNotaryNode(): MockNetwork.MockNode {
private fun createNotaryNode(): UnstartedMockNode {
val dataStoreProperties = makeTestDataSourceProperties(configSupplier = ::inMemoryH2DataSourceConfig).apply {
setProperty("autoCommit", "false")
}
@ -143,7 +139,7 @@ class MySQLNotaryServiceTests : IntegrationTest() {
)
}
private fun issueState(node: StartedNode<*>, notary: Party): StateAndRef<*> {
private fun issueState(node: StartedMockNode, 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)

View File

@ -10,16 +10,16 @@ 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.contracts.DummyContract
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.core.dummyCommand
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.driver.internal.InProcessImpl
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
import net.corda.testing.internal.toDatabaseSchemaName
import net.corda.testing.core.dummyCommand
import net.corda.testing.node.ClusterSpec
import net.corda.testing.node.NotarySpec
import net.corda.testing.node.startFlow
@ -39,12 +39,12 @@ class RaftNotaryServiceTests : IntegrationTest() {
@Test
fun `detect double spend`() {
driver(
driver(DriverParameters(
startNodesInProcess = true,
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 InProcessImpl) }.getOrThrow()
val inputState = issueState(bankA, defaultNotaryIdentity)
val firstTxBuilder = TransactionBuilder(defaultNotaryIdentity)
@ -56,7 +56,7 @@ class RaftNotaryServiceTests : IntegrationTest() {
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
@ -70,11 +70,12 @@ class RaftNotaryServiceTests : IntegrationTest() {
}
}
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: InProcessImpl, 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

@ -69,7 +69,7 @@ class NetworkMapTest : IntegrationTest() {
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()
@ -153,7 +153,7 @@ class NetworkMapTest : IntegrationTest() {
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
@ -9,6 +10,7 @@ import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.driver
import net.corda.testing.internal.*
@ -41,9 +43,9 @@ class RpcSslTest : IntegrationTest() {
withKeyStores(server, client) { nodeSslOptions, clientSslOptions ->
var successful = false
driver(isDebug = true, startNodesInProcess = true, portAllocation = PortAllocation.RandomFree) {
driver(DriverParameters(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
@ -60,9 +62,9 @@ class RpcSslTest : IntegrationTest() {
fun rpc_client_not_using_ssl() {
val user = User("mark", "dadada", setOf(all()))
var successful = false
driver(isDebug = true, startNodesInProcess = true, portAllocation = PortAllocation.RandomFree) {
driver(DriverParameters(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
@ -11,6 +12,7 @@ import net.corda.core.utilities.getOrThrow
import net.corda.testing.contracts.DummyContract
import net.corda.testing.contracts.DummyState
import net.corda.testing.core.*
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
@ -77,10 +79,10 @@ class LargeTransactionsTest : IntegrationTest() {
val bigFile2 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024 * 3, 1)
val bigFile3 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024 * 3, 2)
val bigFile4 = InputStreamAndHash.createInMemoryTestZip(1024 * 1024 * 3, 3)
driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.testing.contracts"), portAllocation = PortAllocation.RandomFree) {
driver(DriverParameters(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,14 @@ 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.DriverParameters
import net.corda.testing.driver.InProcess
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
@ -51,13 +50,14 @@ class P2PMessagingTest : IntegrationTest() {
}
}
@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"
@ -83,7 +83,7 @@ class P2PMessagingTest : IntegrationTest() {
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"
@ -96,7 +96,7 @@ class P2PMessagingTest : IntegrationTest() {
// 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)
@ -106,7 +106,7 @@ class P2PMessagingTest : IntegrationTest() {
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()
@ -116,15 +116,19 @@ class P2PMessagingTest : IntegrationTest() {
}
}
private fun startDriverWithDistributedService(dsl: DriverDSL.(List<StartedNode<Node>>) -> 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 })
private fun startDriverWithDistributedService(dsl: DriverDSL.(List<InProcess>) -> Unit) {
driver(DriverParameters(
startNodesInProcess = true,
notarySpecs = listOf(NotarySpec(DISTRIBUTED_SERVICE_NAME, cluster = ClusterSpec.Raft(clusterSize = 2)))
)) {
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()
}
@ -140,7 +144,7 @@ class P2PMessagingTest : IntegrationTest() {
* 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),
@ -148,8 +152,8 @@ class P2PMessagingTest : IntegrationTest() {
)
distributedServiceNodes.forEach {
val nodeName = it.info.chooseIdentity().name
it.network.addMessageHandler("test.request") { netMessage, _, handler ->
val nodeName = it.services.myInfo.chooseIdentity().name
it.services.networkService.addMessageHandler("test.request") { netMessage, _, handler ->
crashingNodes.requestsReceived.incrementAndGet()
crashingNodes.firstRequestReceived.countDown()
// The node which receives the first request will ignore all requests
@ -161,8 +165,8 @@ class P2PMessagingTest : IntegrationTest() {
} 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)
}
handler.acknowledge()
}
@ -170,13 +174,13 @@ class P2PMessagingTest : IntegrationTest() {
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
@ -188,24 +192,24 @@ class P2PMessagingTest : IntegrationTest() {
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, _, handle ->
private fun InProcess.respondWith(message: Any) {
services.networkService.addMessageHandler("test.request") { netMessage, _, handle ->
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)
handle.acknowledge()
}
}
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
@ -20,6 +21,7 @@ import net.corda.core.utilities.getOrThrow
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.DriverParameters
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
@ -50,13 +52,13 @@ class NodeStatePersistenceTests : IntegrationTest() {
val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery")))
val message = Message("Hello world!")
val stateAndRef: StateAndRef<MessageState>? = driver(isDebug = true, startNodesInProcess = isQuasarAgentSpecified(), portAllocation = PortAllocation.RandomFree) {
val stateAndRef: StateAndRef<MessageState>? = driver(DriverParameters(isDebug = true, startNodesInProcess = isQuasarAgentSpecified(), portAllocation = PortAllocation.RandomFree)) {
val nodeName = {
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
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()
@ -64,7 +66,7 @@ class NodeStatePersistenceTests : IntegrationTest() {
}()
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()
}
@ -84,13 +86,13 @@ class NodeStatePersistenceTests : IntegrationTest() {
val user = User("mark", "dadada", setOf(startFlow<SendMessageFlow>(), invokeRpc("vaultQuery")))
val message = Message("Hello world!")
val stateAndRef: StateAndRef<MessageState>? = driver(isDebug = true, startNodesInProcess = isQuasarAgentSpecified(), portAllocation = PortAllocation.RandomFree) {
val stateAndRef: StateAndRef<MessageState>? = driver(DriverParameters(isDebug = true, startNodesInProcess = isQuasarAgentSpecified(), portAllocation = PortAllocation.RandomFree)) {
val nodeName = {
val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow()
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()
@ -98,7 +100,7 @@ class NodeStatePersistenceTests : IntegrationTest() {
}()
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

@ -523,7 +523,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
* Builds node internal, advertised, and plugin services.
* Returns a list of tokenizable services to be added to the serialisation context.
*/
private fun makeServices(keyPairs: Set<KeyPair>, schemaService: SchemaService, transactionStorage: WritableTransactionStorage, database: CordaPersistence, info: NodeInfo, identityService: IdentityServiceInternal, networkMapCache: NetworkMapCacheInternal): MutableList<Any> {
private fun makeServices(keyPairs: Set<KeyPair>, schemaService: SchemaService, transactionStorage: WritableTransactionStorage, database: CordaPersistence, info: NodeInfo, identityService: IdentityService, networkMapCache: NetworkMapCacheInternal): MutableList<Any> {
checkpointStorage = DBCheckpointStorage()
val metrics = MetricRegistry()
attachments = NodeAttachmentService(metrics, configuration.attachmentContentCacheSizeBytes, configuration.attachmentCacheBound)
@ -628,7 +628,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
}
}
protected open fun makeKeyManagementService(identityService: IdentityServiceInternal, keyPairs: Set<KeyPair>): KeyManagementService {
protected open fun makeKeyManagementService(identityService: IdentityService, keyPairs: Set<KeyPair>): KeyManagementService {
return PersistentKeyManagementService(identityService, keyPairs)
}

View File

@ -4,11 +4,11 @@ import net.corda.core.contracts.PartyAndReference
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.*
import net.corda.core.internal.CertRole
import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.UnknownAnonymousPartyException
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.utilities.contextLogger
import net.corda.core.utilities.trace
import net.corda.node.services.api.IdentityServiceInternal
import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.crypto.x509Certificates
import java.security.InvalidAlgorithmParameterException
@ -25,7 +25,7 @@ import javax.annotation.concurrent.ThreadSafe
// TODO There is duplicated logic between this and PersistentIdentityService
@ThreadSafe
class InMemoryIdentityService(identities: Array<out PartyAndCertificate>,
override val trustRoot: X509Certificate) : SingletonSerializeAsToken(), IdentityServiceInternal {
override val trustRoot: X509Certificate) : SingletonSerializeAsToken(), IdentityService {
companion object {
private val log = contextLogger()
}

View File

@ -3,9 +3,9 @@ package net.corda.node.services.keys
import net.corda.core.crypto.*
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.ThreadBox
import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.KeyManagementService
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.node.services.api.IdentityServiceInternal
import org.bouncycastle.operator.ContentSigner
import java.security.KeyPair
import java.security.PrivateKey
@ -25,7 +25,7 @@ import javax.annotation.concurrent.ThreadSafe
* etc.
*/
@ThreadSafe
class E2ETestKeyManagementService(val identityService: IdentityServiceInternal,
class E2ETestKeyManagementService(val identityService: IdentityService,
initialKeys: Set<KeyPair>) : SingletonSerializeAsToken(), KeyManagementService {
private class InnerState {
val keys = HashMap<PublicKey, PrivateKey>()

View File

@ -3,6 +3,7 @@ package net.corda.node.services.keys
import net.corda.core.crypto.Crypto
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.CertRole
import net.corda.core.node.services.IdentityService
import net.corda.core.utilities.days
import net.corda.node.services.api.IdentityServiceInternal
import net.corda.nodeapi.internal.crypto.CertificateType
@ -27,7 +28,7 @@ import java.time.Duration
* @param revocationEnabled whether to check revocation status of certificates in the certificate path.
* @return X.509 certificate and path to the trust root.
*/
fun freshCertificate(identityService: IdentityServiceInternal,
fun freshCertificate(identityService: IdentityService,
subjectPublicKey: PublicKey,
issuer: PartyAndCertificate,
issuerSigner: ContentSigner,
@ -45,7 +46,11 @@ fun freshCertificate(identityService: IdentityServiceInternal,
window)
val ourCertPath = X509Utilities.buildCertPath(ourCertificate, issuer.certPath.x509Certificates)
val anonymisedIdentity = PartyAndCertificate(ourCertPath)
if (identityService is IdentityServiceInternal) {
identityService.justVerifyAndRegisterIdentity(anonymisedIdentity)
} else {
identityService.verifyAndRegisterIdentity(anonymisedIdentity)
}
return anonymisedIdentity
}

View File

@ -2,10 +2,10 @@ package net.corda.node.services.keys
import net.corda.core.crypto.*
import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.KeyManagementService
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import net.corda.node.services.api.IdentityServiceInternal
import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
import org.apache.commons.lang.ArrayUtils.EMPTY_BYTE_ARRAY
@ -25,7 +25,7 @@ import javax.persistence.Lob
*
* This class needs database transactions to be in-flight during method calls and init.
*/
class PersistentKeyManagementService(val identityService: IdentityServiceInternal,
class PersistentKeyManagementService(val identityService: IdentityService,
initialKeys: Set<KeyPair>) : SingletonSerializeAsToken(), KeyManagementService {
@Entity

View File

@ -57,6 +57,7 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
// Depending on 'store' method, this may insert without checking key duplication or it may avoid inserting a duplicated key.
val existingInDb = store(key, value)
if (existingInDb != null) { // Always reuse an existing value from the storage of a duplicated key.
isUnique = false
Optional.of(existingInDb)
} else {
Optional.of(value)

View File

@ -9,6 +9,7 @@ import net.corda.core.identity.AbstractParty;
import net.corda.core.identity.CordaX500Name;
import net.corda.core.identity.Party;
import net.corda.core.messaging.DataFeed;
import net.corda.core.node.services.IdentityService;
import net.corda.core.node.services.Vault;
import net.corda.core.node.services.VaultQueryException;
import net.corda.core.node.services.VaultService;
@ -74,7 +75,7 @@ public class VaultQueryJavaTests {
CashSchemaV1.class.getPackage().getName(),
DummyLinearStateSchemaV1.class.getPackage().getName()
);
IdentityServiceInternal identitySvc = makeTestIdentityService(MEGA_CORP.getIdentity(), DUMMY_CASH_ISSUER_INFO.getIdentity(), DUMMY_NOTARY.getIdentity());
IdentityService identitySvc = makeTestIdentityService(MEGA_CORP.getIdentity(), DUMMY_CASH_ISSUER_INFO.getIdentity(), DUMMY_NOTARY.getIdentity());
Pair<CordaPersistence, MockServices> databaseAndServices = makeTestDatabaseAndMockServices(
cordappPackages,
identitySvc,

View File

@ -39,9 +39,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.assertThat
@ -71,7 +71,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
@ -82,7 +82,7 @@ class CordaRPCOpsImplTest {
@Before
fun setup() {
mockNet = MockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"))
mockNet = InternalMockNetwork(cordappPackages = listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"))
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

@ -172,9 +172,22 @@ class DBTransactionStorageTests {
assertEquals(expected, actual)
}
private fun newTransactionStorage() {
@Test
fun `duplicates are detected when transaction is evicted from cache`() {
newTransactionStorage(cacheSizeBytesOverride = 0)
val transaction = newTransaction()
database.transaction {
transactionStorage = DBTransactionStorage(NodeConfiguration.defaultTransactionCacheSize)
val firstInserted = transactionStorage.addTransaction(transaction)
val secondInserted = transactionStorage.addTransaction(transaction)
require(firstInserted) { "We inserted a fresh transaction" }
require(!secondInserted) { "Second time should be redundant" }
println("$firstInserted $secondInserted")
}
}
private fun newTransactionStorage(cacheSizeBytesOverride: Long? = null) {
database.transaction {
transactionStorage = DBTransactionStorage(cacheSizeBytesOverride ?: NodeConfiguration.defaultTransactionCacheSize)
}
}

View File

@ -11,8 +11,9 @@ 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.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.driver.internal.InProcessImpl
import net.corda.testing.internal.vault.DummyLinearStateSchemaV1
import net.corda.testing.node.MockNetwork
import org.hibernate.annotations.Cascade
@ -26,7 +27,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`() {
@ -68,7 +69,7 @@ class NodeSchemaServiceTest {
*/
@Test
fun `auto scanning of custom schemas for testing with Driver`() {
driver(startNodesInProcess = true) {
driver(DriverParameters(startNodesInProcess = true)) {
val result = defaultNotaryNode.getOrThrow().rpc.startFlow(::MappedSchemasFlow)
val mappedSchemas = result.returnValue.getOrThrow()
assertTrue(mappedSchemas.contains(TestSchema.name))
@ -78,8 +79,8 @@ class NodeSchemaServiceTest {
@Test
fun `custom schemas are loaded eagerly`() {
val expected = setOf("PARENTS", "CHILDREN")
val tables = driver(startNodesInProcess = true) {
(defaultNotaryNode.getOrThrow() as NodeHandle.InProcess).node.database.transaction {
val tables = driver(DriverParameters(startNodesInProcess = true)) {
(defaultNotaryNode.getOrThrow() as InProcessImpl).database.transaction {
session.createNativeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES").list()
}
}
@ -91,7 +92,7 @@ class NodeSchemaServiceTest {
fun `check node runs with minimal core schema set using driverDSL`() {
// TODO: driver limitation: cannot restrict CorDapps that get automatically created by default,
// can ONLY specify additional ones using `extraCordappPackagesToScan` constructor argument.
driver(startNodesInProcess = true, notarySpecs = emptyList()) {
driver(DriverParameters(startNodesInProcess = true, notarySpecs = emptyList())) {
val node = startNode().getOrThrow()
val result = node.rpc.startFlow(::MappedSchemasFlow)
val mappedSchemas = result.returnValue.getOrThrow()
@ -104,7 +105,7 @@ class NodeSchemaServiceTest {
@Test
fun `check node runs inclusive of notary node schema set using driverDSL`() {
driver(startNodesInProcess = true) {
driver(DriverParameters(startNodesInProcess = true)) {
val notaryNode = defaultNotaryNode.getOrThrow().rpc.startFlow(::MappedSchemasFlow)
val mappedSchemas = notaryNode.returnValue.getOrThrow()
// check against NodeCore + NodeNotary Schemas

View File

@ -35,11 +35,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
@ -64,7 +64,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>
@ -74,7 +74,7 @@ class FlowFrameworkTests {
@Before
fun start() {
mockNet = MockNetwork(
mockNet = InternalMockNetwork(
servicePeerAllocationStrategy = RoundRobin(),
cordappPackages = listOf("net.corda.finance.contracts", "net.corda.testing.contracts")
)

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

@ -3,6 +3,7 @@ package com.r3.corda.enterprise.perftestcordapp
import co.paralleluniverse.fibers.Suspendable
import com.google.common.base.Stopwatch
import com.r3.corda.enterprise.perftestcordapp.flows.CashIssueAndPaymentNoSelection
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.StartableByRPC
import net.corda.core.messaging.startFlow
@ -14,7 +15,8 @@ import net.corda.finance.flows.CashIssueAndPaymentFlow
import net.corda.finance.flows.CashIssueFlow
import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.core.*
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.InProcess
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
@ -57,10 +59,10 @@ class NodePerformanceTests : IntegrationTest() {
@Test
fun `empty flow per second`() {
driver(startNodesInProcess = true) {
driver(DriverParameters(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 {
@ -87,11 +89,11 @@ class NodePerformanceTests : IntegrationTest() {
@Test
fun `empty flow rate`() {
driver(startNodesInProcess = true) {
driver(DriverParameters(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 as InternalDriverDSL).shutdownManager, a.services.monitoringService.metrics)
CordaRPCClient(a.rpcAddress).use("A", "A") { connection ->
startPublishingFixedRateInjector(
metricRegistry = metricRegistry,
parallelism = 16,
@ -107,11 +109,11 @@ class NodePerformanceTests : IntegrationTest() {
@Test
fun `issue flow rate`() {
driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance")) {
driver(DriverParameters( startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance"))) {
val a = startNode(rpcUsers = listOf(User("A", "A", setOf(startFlow<CashIssueFlow>())))).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 as InternalDriverDSL).shutdownManager, a.services.monitoringService.metrics)
CordaRPCClient(a.rpcAddress).use("A", "A") { connection ->
startPublishingFixedRateInjector(
metricRegistry = metricRegistry,
parallelism = 16,
@ -128,15 +130,15 @@ class NodePerformanceTests : IntegrationTest() {
@Test
fun `self pay rate`() {
val user = User("A", "A", setOf(startFlow<CashIssueAndPaymentFlow>()))
driver(
driver(DriverParameters(
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, rpcUsers = listOf(user))),
startNodesInProcess = true,
extraCordappPackagesToScan = listOf("net.corda.finance", "com.r3.corda.enterprise.perftestcordapp"),
portAllocation = PortAllocation.Incremental(20000)
) {
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 as InternalDriverDSL).shutdownManager, notary.services.monitoringService.metrics)
CordaRPCClient(notary.rpcAddress).use("A", "A") { connection ->
startPublishingFixedRateInjector(
metricRegistry = metricRegistry,
parallelism = 64,
@ -153,16 +155,16 @@ class NodePerformanceTests : IntegrationTest() {
@Test
fun `self pay rate without selection`() {
val user = User("A", "A", setOf(startFlow<CashIssueAndPaymentNoSelection>()))
driver(
driver(DriverParameters(
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME)),
startNodesInProcess = true,
portAllocation = PortAllocation.Incremental(20000)
) {
)) {
val aliceFuture = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user), startInSameProcess = true)
val alice = aliceFuture.getOrThrow() as NodeHandle.InProcess
val alice = aliceFuture.getOrThrow() as InProcess
defaultNotaryNode.getOrThrow()
val metricRegistry = startReporter((this as InternalDriverDSL).shutdownManager, alice.node.services.monitoringService.metrics)
alice.rpcClientToNode().use("A", "A") { connection ->
val metricRegistry = startReporter((this as InternalDriverDSL).shutdownManager, alice.services.monitoringService.metrics)
CordaRPCClient(alice.rpcAddress).use("A", "A") { connection ->
startPublishingFixedRateInjector(
metricRegistry = metricRegistry,
parallelism = 64,
@ -179,17 +181,17 @@ class NodePerformanceTests : IntegrationTest() {
@Test
fun `single pay`() {
val user = User("A", "A", setOf(startFlow<CashIssueAndPaymentNoSelection>()))
driver(
driver(DriverParameters(
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME)),
startNodesInProcess = true,
portAllocation = PortAllocation.Incremental(20000)
) {
)) {
val aliceFuture = startNode(providedName = ALICE_NAME, rpcUsers = listOf(user))
val bobFuture = startNode(providedName = BOB_NAME, rpcUsers = listOf(user))
val alice = aliceFuture.getOrThrow() as NodeHandle.InProcess
val bob = bobFuture.getOrThrow() as NodeHandle.InProcess
val alice = aliceFuture.getOrThrow() as InProcess
val bob = bobFuture.getOrThrow() as InProcess
defaultNotaryNode.getOrThrow()
alice.rpcClientToNode().use("A", "A") { connection ->
CordaRPCClient(alice.rpcAddress).use("A", "A") { connection ->
connection.proxy.startFlow(::CashIssueAndPaymentNoSelection, 1.DOLLARS, OpaqueBytes.of(0), bob.nodeInfo.legalIdentities[0], false, defaultNotaryIdentity).returnValue.getOrThrow()
}
}

View File

@ -1,10 +1,12 @@
package com.r3.corda.enterprise.perftestcordapp.flows
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.messaging.startFlow
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
import net.corda.finance.DOLLARS
import net.corda.node.services.Permissions
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.driver
import net.corda.testing.node.User
@ -17,14 +19,14 @@ class NoSelectionIntegrationTest {
@Test
fun `single pay no selection`() {
val aliceUser = User("A", "A", setOf(Permissions.startFlow<CashIssueAndPaymentNoSelection>()))
driver(
driver(DriverParameters(
startNodesInProcess = true,
extraCordappPackagesToScan = listOf("com.r3.corda.enterprise.perftestcordapp"),
portAllocation = PortAllocation.Incremental(20000)
) {
)) {
val alice = startNode(rpcUsers = listOf(aliceUser)).get()
defaultNotaryNode.get()
alice.rpcClientToNode().use("A", "A") { connection ->
CordaRPCClient(alice.rpcAddress).use("A", "A") { connection ->
connection.proxy.startFlow(::CashIssueAndPaymentNoSelection, 1.DOLLARS, OpaqueBytes.of(0), alice.nodeInfo.legalIdentities[0], false, defaultNotaryIdentity).returnValue.getOrThrow()
}
}

View File

@ -6,11 +6,10 @@ import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash
import net.corda.core.identity.Party
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
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

@ -9,11 +9,10 @@ import net.corda.core.node.services.trackBy
import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
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
@ -22,11 +21,10 @@ import kotlin.test.assertEquals
class CashIssueAndPaymentFlowTests {
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
private lateinit var notary: Party
@Before

View File

@ -9,11 +9,10 @@ import net.corda.core.node.services.trackBy
import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
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
@ -32,9 +31,9 @@ class CashIssueAndPayNoSelectionTests(private val anonymous: Boolean) {
private lateinit var mockNet: MockNetwork
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
private lateinit var notary: Party
@Before

View File

@ -6,11 +6,10 @@ import com.r3.corda.enterprise.perftestcordapp.contracts.asset.Cash
import net.corda.core.identity.Party
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
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.node.services.trackBy
import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
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

@ -53,6 +53,8 @@ import net.corda.testing.dsl.TestTransactionDSLInterpreter
import net.corda.testing.internal.LogHelper
import net.corda.testing.internal.rigorousMock
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
@ -95,7 +97,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() {
@ -113,7 +115,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
@ -166,7 +168,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
@ -224,7 +226,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
@ -323,10 +325,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> {
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))
@ -337,7 +339,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)
@ -441,7 +443,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)
@ -519,7 +521,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")
@ -528,7 +530,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")
@ -544,8 +546,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

@ -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
@ -7,6 +8,7 @@ import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_BANK_B_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.PortAllocation
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
@ -29,7 +31,7 @@ class AttachmentDemoTest : IntegrationTest() {
@Test
fun `attachment demo using a 10MB zip file`() {
val numOfExpectedBytes = 10_000_000
driver(isDebug = true, portAllocation = PortAllocation.Incremental(20000)) {
driver(DriverParameters(isDebug = true, portAllocation = PortAllocation.Incremental(20000))) {
val demoUser = listOf(User("demo", "demo", setOf(
startFlow<AttachmentDemoFlow>(),
invokeRpc(CordaRPCOps::attachmentExists),
@ -42,17 +44,17 @@ class AttachmentDemoTest : IntegrationTest() {
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

@ -3,8 +3,9 @@ package net.corda.attachmentdemo
import net.corda.core.internal.div
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_BANK_B_NAME
import net.corda.testing.node.User
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.node.User
/**
* This file is exclusively for being able to run your nodes through an IDE (as opposed to running deployNodes)
@ -12,7 +13,7 @@ import net.corda.testing.driver.driver
*/
fun main(args: Array<String>) {
val demoUser = listOf(User("demo", "demo", setOf("StartFlow.net.corda.flows.FinalityFlow")))
driver(isDebug = true, driverDirectory = "build" / "attachment-demo-nodes", waitForAllNodesToFinish = true) {
driver(DriverParameters(isDebug = true, driverDirectory = "build" / "attachment-demo-nodes", waitForAllNodesToFinish = true)) {
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = demoUser)
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = demoUser)
}

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
@ -12,6 +13,7 @@ import net.corda.finance.flows.CashIssueAndPaymentFlow
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.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
@ -34,7 +36,7 @@ class BankOfCordaRPCClientTest : IntegrationTest() {
invokeRpc(CordaRPCOps::wellKnownPartyFromX500Name),
invokeRpc(CordaRPCOps::notaryIdentities)
)
driver(extraCordappPackagesToScan = listOf("net.corda.finance"), isDebug = true) {
driver(DriverParameters(extraCordappPackagesToScan = listOf("net.corda.finance"), isDebug = true)) {
val bocManager = User("bocManager", "password1", permissions = setOf(
startFlow<CashIssueAndPaymentFlow>()) + commonPermissions)
val bigCorpCFO = User("bigCorpCFO", "password2", permissions = emptySet<String>() + commonPermissions)
@ -44,11 +46,11 @@ class BankOfCordaRPCClientTest : IntegrationTest() {
).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

@ -4,6 +4,7 @@ import net.corda.core.identity.CordaX500Name
import net.corda.core.utilities.getOrThrow
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_BANK_B_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
/**
@ -11,7 +12,7 @@ import net.corda.testing.driver.driver
* Do not use in a production environment.
*/
fun main(args: Array<String>) {
driver(useTestClock = true, isDebug = true, waitForAllNodesToFinish = true) {
driver(DriverParameters(useTestClock = true, isDebug = true, waitForAllNodesToFinish = true)) {
val (nodeA, nodeB) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME),
startNode(providedName = DUMMY_BANK_B_NAME),

View File

@ -15,18 +15,19 @@ 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
import net.corda.finance.plugin.registerFinanceJSONMappers
import net.corda.irs.contract.InterestRateSwap
import net.corda.irs.web.IrsDemoWebApplication
import net.corda.node.services.config.NodeConfiguration
import net.corda.test.spring.springDriver
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_BANK_B_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.chooseIdentity
import net.corda.testing.driver.DriverParameters
import net.corda.testing.http.HttpApi
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
@ -57,12 +58,12 @@ class IRSDemoTest : IntegrationTest() {
@Test
fun `runs IRS demo`() {
springDriver(
springDriver(DriverParameters(
useTestClock = true,
notarySpecs = listOf(NotarySpec(DUMMY_NOTARY_NAME, rpcUsers = rpcUsers)),
isDebug = true,
extraCordappPackagesToScan = listOf("net.corda.irs")
) {
)) {
val (nodeA, nodeB) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = rpcUsers),
startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = rpcUsers),
@ -86,7 +87,7 @@ class IRSDemoTest : IntegrationTest() {
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)
@ -110,8 +111,8 @@ class IRSDemoTest : IntegrationTest() {
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

@ -5,47 +5,23 @@ import net.corda.core.internal.concurrent.map
import net.corda.core.utilities.contextLogger
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.node.NotarySpec
import net.corda.testing.driver.internal.NodeHandleInternal
import net.corda.testing.node.internal.*
import okhttp3.OkHttpClient
import okhttp3.Request
import java.net.ConnectException
import java.net.URL
import java.nio.file.Path
import java.nio.file.Paths
import java.util.concurrent.TimeUnit
fun <A> springDriver(
defaultParameters: DriverParameters = DriverParameters(),
isDebug: Boolean = defaultParameters.isDebug,
driverDirectory: Path = defaultParameters.driverDirectory,
portAllocation: PortAllocation = defaultParameters.portAllocation,
debugPortAllocation: PortAllocation = defaultParameters.debugPortAllocation,
systemProperties: Map<String, String> = defaultParameters.systemProperties,
useTestClock: Boolean = defaultParameters.useTestClock,
initialiseSerialization: Boolean = defaultParameters.initialiseSerialization,
startNodesInProcess: Boolean = defaultParameters.startNodesInProcess,
notarySpecs: List<NotarySpec> = defaultParameters.notarySpecs,
extraCordappPackagesToScan: List<String> = defaultParameters.extraCordappPackagesToScan,
maxTransactionSize: Int = defaultParameters.maxTransactionSize,
dsl: SpringBootDriverDSL.() -> A
): A {
return genericDriver(
defaultParameters = defaultParameters,
isDebug = isDebug,
driverDirectory = driverDirectory,
portAllocation = portAllocation,
debugPortAllocation = debugPortAllocation,
systemProperties = systemProperties,
useTestClock = useTestClock,
initialiseSerialization = initialiseSerialization,
startNodesInProcess = startNodesInProcess,
extraCordappPackagesToScan = extraCordappPackagesToScan,
notarySpecs = notarySpecs,
driverDslWrapper = { driverDSL: DriverDSLImpl -> SpringBootDriverDSL(driverDSL) },
maxTransactionSize = maxTransactionSize,
coerce = { it }, dsl = dsl
)
}
@ -68,12 +44,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 +78,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 MockNetwork.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

@ -6,6 +6,7 @@ import net.corda.core.utilities.getOrThrow
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_BANK_B_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
import net.corda.testing.http.HttpApi
import net.corda.testing.internal.IntegrationTest
@ -36,7 +37,7 @@ class SimmValuationTest : IntegrationTest() {
@Test
fun `runs SIMM valuation demo`() {
driver(isDebug = true, extraCordappPackagesToScan = listOf("net.corda.vega.contracts", "net.corda.vega.plugin.customserializers")) {
driver(DriverParameters(isDebug = true, extraCordappPackagesToScan = listOf("net.corda.vega.contracts", "net.corda.vega.plugin.customserializers"))) {
val nodeAFuture = startNode(providedName = nodeALegalName)
val nodeBFuture = startNode(providedName = nodeBLegalName)
val (nodeA, nodeB) = listOf(nodeAFuture, nodeBFuture).map { it.getOrThrow() }

View File

@ -4,6 +4,7 @@ import net.corda.core.utilities.getOrThrow
import net.corda.testing.core.DUMMY_BANK_A_NAME
import net.corda.testing.core.DUMMY_BANK_B_NAME
import net.corda.testing.core.DUMMY_BANK_C_NAME
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.driver
/**
@ -12,7 +13,7 @@ import net.corda.testing.driver.driver
* via the web api.
*/
fun main(args: Array<String>) {
driver(isDebug = true, waitForAllNodesToFinish = true) {
driver(DriverParameters(isDebug = true, waitForAllNodesToFinish = true)) {
val (nodeA, nodeB, nodeC) = listOf(
startNode(providedName = DUMMY_BANK_A_NAME),
startNode(providedName = DUMMY_BANK_B_NAME),

View File

@ -9,7 +9,8 @@ import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.Permissions.Companion.all
import net.corda.node.services.Permissions.Companion.startFlow
import net.corda.testing.core.*
import net.corda.testing.driver.NodeHandle
import net.corda.testing.driver.DriverParameters
import net.corda.testing.driver.InProcess
import net.corda.testing.driver.driver
import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
@ -38,19 +39,19 @@ class TraderDemoTest : IntegrationTest() {
startFlow<CashPaymentFlow>(),
startFlow<CommercialPaperIssueFlow>(),
all()))
driver(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance")) {
driver(DriverParameters(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance"))) {
val (nodeA, nodeB, bankNode) = listOf(
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
}
@ -62,8 +63,8 @@ class TraderDemoTest : IntegrationTest() {
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)

Some files were not shown because too many files have changed in this diff Show More