mirror of
https://github.com/corda/corda.git
synced 2024-12-26 16:11:12 +00:00
Merge commit 'fa4b5d16ba6249f85b50851c2f52dc697eebdee6' into aslemmer-merge-19-Feb
This commit is contained in:
commit
6b2b7b6a3c
@ -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()
|
||||
|
@ -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'
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 }
|
||||
}
|
||||
})
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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) }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
})
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)),
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
|
@ -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()) {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ class NetworkBootstrapper {
|
||||
notaries = notaryInfos,
|
||||
modifiedTime = Instant.now(),
|
||||
maxMessageSize = 10485760,
|
||||
maxTransactionSize = 40000,
|
||||
maxTransactionSize = Int.MAX_VALUE,
|
||||
epoch = 1
|
||||
), overwriteFile = true)
|
||||
|
||||
|
@ -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) }
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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>()
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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())
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
|
@ -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())
|
||||
|
@ -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 {
|
||||
|
@ -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...
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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>()
|
||||
|
@ -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)
|
||||
identityService.justVerifyAndRegisterIdentity(anonymisedIdentity)
|
||||
if (identityService is IdentityServiceInternal) {
|
||||
identityService.justVerifyAndRegisterIdentity(anonymisedIdentity)
|
||||
} else {
|
||||
identityService.verifyAndRegisterIdentity(anonymisedIdentity)
|
||||
}
|
||||
return anonymisedIdentity
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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())))
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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 }
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
)
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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 }
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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() }
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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() }
|
||||
|
@ -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),
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user