Skip to content

Commit

Permalink
* Move CompositeSignaturesWithKeys into net.corda.core.crypto package.
Browse files Browse the repository at this point in the history
* Rename and move CordaPluginRegistry to reflect its real purpose now.
* Docs: docsite improvements
* Remove discussion of webserver from 'writing a cordapp' page.
* Fixup some flow docs.
* Add a couple more package descriptions.
* Review comments - always apply default whitelist and no longer load it via ServiceLoader
* Added wording about renaming services resource file
  • Loading branch information
rick-r3 authored and Mike Hearn committed Oct 2, 2017
1 parent 12982b3 commit 9a16011
Show file tree
Hide file tree
Showing 31 changed files with 114 additions and 232 deletions.
6 changes: 3 additions & 3 deletions core/src/main/kotlin/net/corda/core/cordapp/Cordapp.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package net.corda.core.cordapp

import net.corda.core.flows.FlowLogic
import net.corda.core.node.CordaPluginRegistry
import net.corda.core.schemas.MappedSchema
import net.corda.core.serialization.SerializationWhitelist
import net.corda.core.serialization.SerializeAsToken
import java.net.URL

Expand All @@ -19,7 +19,7 @@ import java.net.URL
* @property rpcFlows List of RPC initiable flows classes
* @property schedulableFlows List of flows startable by the scheduler
* @property servies List of RPC services
* @property plugins List of Corda plugin registries
* @property serializationWhitelists List of Corda plugin registries
* @property customSchemas List of custom schemas
* @property jarPath The path to the JAR for this CorDapp
*/
Expand All @@ -30,7 +30,7 @@ interface Cordapp {
val rpcFlows: List<Class<out FlowLogic<*>>>
val schedulableFlows: List<Class<out FlowLogic<*>>>
val services: List<Class<out SerializeAsToken>>
val plugins: List<CordaPluginRegistry>
val serializationWhitelists: List<SerializationWhitelist>
val customSchemas: Set<MappedSchema>
val jarPath: URL
val cordappClasses: List<String>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package net.corda.core.crypto

import net.corda.core.crypto.composite.CompositeSignaturesWithKeys
import net.corda.core.serialization.deserialize
import java.io.ByteArrayOutputStream
import java.security.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package net.corda.core.crypto.composite
package net.corda.core.crypto

import net.corda.core.crypto.TransactionSignature
import net.corda.core.serialization.CordaSerializable

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package net.corda.core.internal.cordapp

import net.corda.core.cordapp.Cordapp
import net.corda.core.flows.FlowLogic
import net.corda.core.node.CordaPluginRegistry
import net.corda.core.schemas.MappedSchema
import net.corda.core.serialization.SerializationWhitelist
import net.corda.core.serialization.SerializeAsToken
import java.io.File
import java.net.URL
Expand All @@ -14,7 +14,7 @@ data class CordappImpl(
override val rpcFlows: List<Class<out FlowLogic<*>>>,
override val schedulableFlows: List<Class<out FlowLogic<*>>>,
override val services: List<Class<out SerializeAsToken>>,
override val plugins: List<CordaPluginRegistry>,
override val serializationWhitelists: List<SerializationWhitelist>,
override val customSchemas: Set<MappedSchema>,
override val jarPath: URL) : Cordapp {
override val name: String = File(jarPath.toURI()).name.removeSuffix(".jar")
Expand All @@ -24,5 +24,5 @@ data class CordappImpl(
*
* TODO: Also add [SchedulableFlow] as a Cordapp class
*/
override val cordappClasses = ((rpcFlows + initiatedFlows + services + plugins.map { javaClass }).map { it.name } + contractClassNames)
override val cordappClasses = ((rpcFlows + initiatedFlows + services + serializationWhitelists.map { javaClass }).map { it.name } + contractClassNames)
}
19 changes: 0 additions & 19 deletions core/src/main/kotlin/net/corda/core/node/CordaPluginRegistry.kt

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package net.corda.core.serialization

/**
* Provide a subclass of this via the [java.util.ServiceLoader] mechanism to be able to whitelist types for
* serialisation that you cannot otherwise annotate. The name of the class must appear in a text file on the
* classpath under the path META-INF/services/net.corda.core.serialization.SerializationWhitelist
*/
interface SerializationWhitelist {
/**
* Optionally whitelist types for use in object serialization, as we lock down the types that can be serialized.
*
* For example, if you add a new [net.corda.core.contracts.ContractState] it needs to be whitelisted. You can do that
* either by adding the [net.corda.core.serialization.CordaSerializable] annotation or via this method.
*/
val whitelist: List<Class<*>>
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package net.corda.core.crypto

import net.corda.core.crypto.CompositeKey.NodeAndWeight
import net.corda.core.crypto.composite.CompositeSignaturesWithKeys
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.cert
import net.corda.core.internal.declaredField
import net.corda.core.internal.div
import net.corda.core.serialization.serialize
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.internal.cert
import net.corda.core.utilities.toBase58String
import net.corda.node.utilities.*
import net.corda.testing.TestDependencyInjectionBase
Expand Down
8 changes: 4 additions & 4 deletions docs/packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ RPC client interface to Corda, for use both by user-facing client and integratio

Internal, do not use. These APIs and implementations which are currently being revised and are subject to future change.

# Package net.corda.core

Exception types and some utilities for working with observables and futures.

# Package net.corda.core.cordapp

This package contains the interface to CorDapps from within a node. A CorDapp can access its own context by using
Expand Down Expand Up @@ -60,10 +64,6 @@ processes such as handling fixing of interest rate swaps.

Data classes which model different forms of identity (potentially with supporting evidence) for legal entities and services.

# Package net.corda.core.internal

Internal, do not use. These APIs and implementations which are currently being revised and are subject to future change.

# Package net.corda.core.messaging

Data types used by the Corda messaging layer to manage state of messaging and sessions between nodes.
Expand Down
8 changes: 5 additions & 3 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,11 @@ Release 1.0
* About half of the code in test-utils has been moved to a new module ``node-driver``,
and the test scope modules are now located in a ``testing`` directory.

* Removed `requireSchemas` CordaPluginRegistry configuration item.
Custom schemas are now automatically located using classpath scanning for deployed CorDapps.
Improved support for testing custom schemas in MockNode and MockServices using explicit registration.
* CordaPluginRegistry has been renamed to SerializationWhitelist and moved to the net.corda.core.serialization
package. The API for whitelisting types that can't be annotated was slightly simplified. This class used to contain
many things, but as we switched to annotations and classpath scanning over time it hollowed out until this was
the only functionality left. You also need to rename your services resource file to the new class name.
An associated property on ``MockNode`` was renamed from ``testPluginRegistries`` to ``testSerializationWhitelists``.

* Contract Upgrades: deprecated RPC authorisation / deauthorisation API calls in favour of equivalent flows in ContractUpgradeFlow.
Implemented contract upgrade persistence using JDBC backed persistent map.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import net.corda.core.contracts.Amount
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.messaging.startFlow
import net.corda.core.messaging.vaultQueryBy
import net.corda.core.node.CordaPluginRegistry
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializationCustomization
import net.corda.core.serialization.SerializationWhitelist
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
Expand All @@ -16,9 +15,9 @@ import net.corda.finance.flows.CashExitFlow
import net.corda.finance.flows.CashIssueFlow
import net.corda.finance.flows.CashPaymentFlow
import net.corda.node.services.FlowPermissions.Companion.startFlowPermission
import net.corda.nodeapi.internal.ServiceInfo
import net.corda.node.services.transactions.ValidatingNotaryService
import net.corda.nodeapi.User
import net.corda.nodeapi.internal.ServiceInfo
import net.corda.testing.ALICE
import net.corda.testing.DUMMY_NOTARY
import net.corda.testing.driver.driver
Expand Down Expand Up @@ -142,12 +141,8 @@ data class ExampleRPCValue(val foo: String)
@CordaSerializable
data class ExampleRPCValue2(val bar: Int)

class ExampleRPCCordaPluginRegistry : CordaPluginRegistry() {
override fun customizeSerialization(custom: SerializationCustomization): Boolean {
// Add classes like this.
custom.addToWhitelist(ExampleRPCValue::class.java)
// You should return true, otherwise your plugin will be ignored for registering classes with Kryo.
return true
}
class ExampleRPCSerializationWhitelist : SerializationWhitelist {
// Add classes like this.
override val whitelist = listOf(ExampleRPCValue::class.java)
}
// END 7
37 changes: 3 additions & 34 deletions docs/source/flow-state-machines.rst
Original file line number Diff line number Diff line change
Expand Up @@ -277,40 +277,9 @@ will propagate to the other side. Any other exception will not propagate.

Taking a step back, we mentioned that the other side has to accept the session request for there to be a communication
channel. A node accepts a session request if it has registered the flow type (the fully-qualified class name) that is
making the request - each session initiation includes the initiating flow type. The registration is done by a CorDapp
which has made available the particular flow communication, using ``PluginServiceHub.registerServiceFlow``. This method
specifies a flow factory for generating the counter-flow to any given initiating flow. If this registration doesn't exist
then no further communication takes place and the initiating flow ends with an exception.

Going back to our buyer and seller flows, we need a way to initiate communication between the two. This is typically done
with one side started manually using the ``startFlowDynamic`` RPC and this initiates the counter-flow on the other side.
In this case it doesn't matter which flow is the initiator and which is the initiated. If we choose the seller side as
the initiator then the buyer side would need to register their flow, perhaps with something like:

.. container:: codeset

.. sourcecode:: kotlin

class TwoPartyTradeFlowPlugin : CordaPluginRegistry() {
override val servicePlugins = listOf(Function(TwoPartyTradeFlowService::Service))
}

object TwoPartyTradeFlowService {
class Service(services: PluginServiceHub) {
init {
services.registerServiceFlow(TwoPartyTradeFlow.Seller::class.java) {
TwoPartyTradeFlow.Buyer(
it,
notary = services.networkMapCache.notaryIdentities[0].party,
acceptablePrice = TODO(),
typeToBuy = TODO())
}
}
}
}

This is telling the buyer node to fire up an instance of ``TwoPartyTradeFlow.Buyer`` (the code in the lambda) when
they receive a message from the initiating seller side of the flow (``TwoPartyTradeFlow.Seller::class.java``).
making the request - each session initiation includes the initiating flow type. The *initiated* (server) flow must name the
*initiating* (client) flow using the ``@InitiatedBy`` annotation and passing the class name that will be starting the
flow session as the annotation parameter.

.. _subflows:

Expand Down
40 changes: 2 additions & 38 deletions docs/source/writing-cordapps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ The ``src`` directory of the Template CorDapp, where we define our CorDapp's sou
│ └── resources
│ ├── META-INF
│ │ └── services
│ │ ├── net.corda.core.node.CordaPluginRegistry
│ │ ├── net.corda.core.serialization.SerializationWhitelist
│ │ └── net.corda.webserver.services.WebServerPluginRegistry
│ ├── certificates
│ │ ├── sslkeystore.jks
Expand All @@ -58,40 +58,4 @@ The ``src`` directory of the Template CorDapp, where we define our CorDapp's sou
└── com
└── template
└── contract
└── TemplateTests.java
Defining plugins
----------------
Your CorDapp may need to define two types of plugins:

* ``CordaPluginRegistry`` subclasses, which define additional serializable classes
* ``WebServerPluginRegistry`` subclasses, which define the APIs and static web content served by your CorDapp

The fully-qualified class path of each ``CordaPluginRegistry`` subclass must then be added to the
``net.corda.core.node.CordaPluginRegistry`` file in the CorDapp's ``resources/META-INF/services`` folder. Meanwhile,
the fully-qualified class path of each ``WebServerPluginRegistry`` subclass must be added to the
``net.corda.webserver.services.WebServerPluginRegistry`` file, again in the CorDapp's ``resources/META-INF/services``
folder.

The ``CordaPluginRegistry`` class defines the following:

* ``customizeSerialization``, which can be overridden to provide a list of the classes to be whitelisted for object
serialisation, over and above those tagged with the ``@CordaSerializable`` annotation. See :doc:`serialization`

The ``WebServerPluginRegistry`` class defines the following:

* ``webApis``, which can be overridden to return a list of JAX-RS annotated REST access classes. These classes will be
constructed by the bundled web server and must have a single argument constructor taking a ``CordaRPCOps`` object.
This will allow the API to communicate with the node process via the RPC interface. These web APIs will not be
available if the bundled web server is not started

* ``staticServeDirs``, which can be overridden to map static web content to virtual paths and allow simple web demos to
be distributed within the CorDapp jars. This static content will not be available if the bundled web server is not
started

* ``customizeJSONSerialization``, which can be overridden to register custom JSON serializers if required by the REST api.

* The static web content itself should be placed inside the ``src/main/resources`` directory

To learn about how to use gradle to build your cordapp against Corda and generate an artifact please read
:doc:`cordapp-build-systems`.
└── TemplateTests.java

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

package net.corda.nodeapi.internal.serialization

import net.corda.core.node.CordaPluginRegistry
import net.corda.core.serialization.*
import net.corda.core.utilities.ByteSequence
import net.corda.nodeapi.internal.serialization.amqp.AmqpHeaderV1_0
Expand All @@ -14,12 +13,6 @@ import java.util.concurrent.ConcurrentHashMap

val AMQP_ENABLED get() = SerializationDefaults.P2P_CONTEXT.preferredSerializationVersion == AmqpHeaderV1_0

class AMQPSerializationCustomization(val factory: SerializerFactory) : SerializationCustomization {
override fun addToWhitelist(vararg types: Class<*>) {
factory.addToWhitelist(*types)
}
}

fun SerializerFactory.addToWhitelist(vararg types: Class<*>) {
require(types.toSet().size == types.size) {
val duplicates = types.toMutableList()
Expand All @@ -33,12 +26,12 @@ fun SerializerFactory.addToWhitelist(vararg types: Class<*>) {

abstract class AbstractAMQPSerializationScheme : SerializationScheme {
internal companion object {
private val pluginRegistries: List<CordaPluginRegistry> by lazy {
ServiceLoader.load(CordaPluginRegistry::class.java, this::class.java.classLoader).toList()
private val serializationWhitelists: List<SerializationWhitelist> by lazy {
ServiceLoader.load(SerializationWhitelist::class.java, this::class.java.classLoader).toList() + DefaultWhitelist
}

fun registerCustomSerializers(factory: SerializerFactory) {
factory.apply {
with(factory) {
register(net.corda.nodeapi.internal.serialization.amqp.custom.PublicKeySerializer)
register(net.corda.nodeapi.internal.serialization.amqp.custom.ThrowableSerializer(this))
register(net.corda.nodeapi.internal.serialization.amqp.custom.X500NameSerializer)
Expand Down Expand Up @@ -67,8 +60,8 @@ abstract class AbstractAMQPSerializationScheme : SerializationScheme {
register(net.corda.nodeapi.internal.serialization.amqp.custom.BitSetSerializer(this))
register(net.corda.nodeapi.internal.serialization.amqp.custom.EnumSetSerializer(this))
}
val customizer = AMQPSerializationCustomization(factory)
pluginRegistries.forEach { it.customizeSerialization(customizer) }
for (whitelistProvider in serializationWhitelists)
factory.addToWhitelist(*whitelistProvider.whitelist.toTypedArray())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ class GlobalTransientClassWhiteList(val delegate: ClassWhitelist) : MutableClass
}

/**
* A whitelist that can be customised via the [net.corda.core.node.CordaPluginRegistry], since implements [MutableClassWhitelist].
* A whitelist that can be customised via the [net.corda.core.node.SerializationWhitelist], since implements [MutableClassWhitelist].
*/
class TransientClassWhiteList(val delegate: ClassWhitelist) : MutableClassWhitelist, ClassWhitelist by delegate {
val whitelist: MutableSet<String> = Collections.synchronizedSet(mutableSetOf())
Expand Down
Loading

0 comments on commit 9a16011

Please sign in to comment.