Move Web API from CordaPluginRegistry to new class WebPluginRegistry (#864)

Move Web API from CordaPluginRegistry to new class WebPluginRegistry
This commit is contained in:
szymonsztuka 2017-06-20 15:29:35 +01:00 committed by GitHub
parent 4dc06ed25b
commit 4195adfb7b
15 changed files with 85 additions and 39 deletions

View File

@ -9,17 +9,16 @@ import java.util.function.Function
* to extend a Corda node with additional application services.
*/
abstract class CordaPluginRegistry {
/**
* List of lambdas returning JAX-RS objects. They may only depend on the RPC interface, as the webserver should
* potentially be able to live in a process separate from the node itself.
*/
@Suppress("unused")
@Deprecated("This is no longer in use, moved to WebServerPluginRegistry class in webserver module",
level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("net.corda.webserver.services.WebServerPluginRegistry"))
open val webApis: List<Function<CordaRPCOps, out Any>> get() = emptyList()
/**
* Map of static serving endpoints to the matching resource directory. All endpoints will be prefixed with "/web" and postfixed with "\*.
* Resource directories can be either on disk directories (especially when debugging) in the form "a/b/c". Serving from a JAR can
* be specified with: javaClass.getResource("<folder-in-jar>").toExternalForm()
*/
@Suppress("unused")
@Deprecated("This is no longer in use, moved to WebServerPluginRegistry class in webserver module",
level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("net.corda.webserver.services.WebServerPluginRegistry"))
open val staticServeDirs: Map<String, String> get() = emptyMap()
@Suppress("unused")

View File

@ -12,6 +12,14 @@ UNRELEASED
* The node driver has moved to net.corda.testing.driver in the test-utils module
Milestone 13
------------
* Web API related collections ``CordaPluginRegistry.webApis`` and ``CordaPluginRegistry.staticServeDirs`` moved to
``net.corda.webserver.services.WebServerPluginRegistry`` in ``webserver`` module.
Classes serving Web API should now extend ``WebServerPluginRegistry`` instead of ``CordaPluginRegistry``
and they should be registered in ``resources/META-INF/services/net.corda.webserver.services.WebServerPluginRegistry``.
Milestone 12
------------

View File

@ -623,7 +623,8 @@ The example CorDapp has the following directory structure:
│ │   └── resources
│ │   ├── META-INF
│ │   │   └── services
│ │   │   └── net.corda.core.node.CordaPluginRegistry
│   │   │   ├── net.corda.core.node.CordaPluginRegistry
│   │ │ └── net.corda.webserver.services.WebServerPluginRegistry
│ │   ├── certificates
│ │   │   ├── readme.txt
│ │   │   ├── sslkeystore.jks
@ -665,7 +666,8 @@ The example CorDapp has the following directory structure:
│   └── resources
│   ├── META-INF
│   │   └── services
│   │   └── net.corda.core.node.CordaPluginRegistry
   │   │   ├── net.corda.core.node.CordaPluginRegistry
   │ │ └── net.corda.webserver.services.WebServerPluginRegistry
│   ├── certificates
│   │   ├── readme.txt
│   │   ├── sslkeystore.jks
@ -808,7 +810,8 @@ Service Provider Configuration File
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you are building a CorDapp from scratch or adding a new CorDapp to the cordapp-tutorial project then you must provide
a reference to your sub-class of ``CordaPluginRegistry`` in the provider-configuration file in located in the ``resources/META-INF/services`` directory.
a reference to your sub-class of ``CordaPluginRegistry`` or ``WebServerPluginRegistry`` (for Wep API) in the provider-configuration file
located in the ``resources/META-INF/services`` directory.
Re-Deploying Your Nodes Locally
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -43,7 +43,8 @@ structure:
│ └── resources
│ ├── META-INF
│ │ └── services
│ │ └── net.corda.core.node.CordaPluginRegistry
│ │ ├── net.corda.core.node.CordaPluginRegistry
│ │ └── net.corda.webserver.services.WebServerPluginRegistry
│ ├── certificates
│ │ ├── sslkeystore.jks
│ │ └── truststore.jks
@ -60,9 +61,20 @@ structure:
Defining a plugin
-----------------
You can specify the web APIs and static web content for your CorDapp by subclassing
You can specify the transport options (between nodes and between Web Client and a node) for your CorDapp by subclassing
``net.corda.core.node.CordaPluginRegistry``:
* The ``customizeSerialization`` function allows classes to be whitelisted for object serialisation, over and
above those tagged with the ``@CordaSerializable`` annotation. For instance, new state types will need to be
explicitly registered. In general, the annotation should be preferred. See :doc:`serialization`.
The fully-qualified class path of each ``CordaPluginRegistry`` subclass must be added to the
``net.corda.core.node.CordaPluginRegistry`` file in the CorDapp's ``resources/META-INF/services`` folder. A CorDapp
can register multiple plugins in a single ``net.corda.core.node.CordaPluginRegistry`` file.
You can specify the web APIs and static web content for your CorDapp by implementing
``net.corda.webserver.services.WebServerPluginRegistry`` interface:
* The ``webApis`` property is 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
@ -73,13 +85,9 @@ You can specify the web APIs and static web content for your CorDapp by subclass
is not started.
* The static web content itself should be placed inside the ``src/main/resources`` directory
* The ``customizeSerialization`` function allows classes to be whitelisted for object serialisation, over and
above those tagged with the ``@CordaSerializable`` annotation. For instance, new state types will need to be
explicitly registered. In general, the annotation should be preferred. See :doc:`serialization`.
The fully-qualified class path of each ``CordaPluginRegistry`` subclass must be added to the
``net.corda.core.node.CordaPluginRegistry`` file in the CorDapp's ``resources/META-INF/services`` folder. A CorDapp
can register multiple plugins in a single ``net.corda.core.node.CordaPluginRegistry`` file.
The fully-qualified class path of each ``WebServerPluginRegistry`` class must be added to the
``net.corda.webserver.services.WebServerPluginRegistry`` file in the CorDapp's ``resources/META-INF/services`` folder. A CorDapp
can register multiple plugins in a single ``net.corda.webserver.services.WebServerPluginRegistry`` file.
Installing CorDapps
-------------------

View File

@ -1,10 +1,10 @@
package net.corda.bank.plugin
import net.corda.bank.api.BankOfCordaWebApi
import net.corda.core.node.CordaPluginRegistry
import net.corda.webserver.services.WebServerPluginRegistry
import java.util.function.Function
class BankOfCordaPlugin : CordaPluginRegistry() {
class BankOfCordaPlugin : WebServerPluginRegistry {
// A list of classes that expose web APIs.
override val webApis = listOf(Function(::BankOfCordaWebApi))
}

View File

@ -1,2 +0,0 @@
# Register a ServiceLoader service extending from net.corda.node.CordaPluginRegistry
net.corda.bank.plugin.BankOfCordaPlugin

View File

@ -0,0 +1,2 @@
# Register a ServiceLoader service extending from net.corda.webserver.services.WebServerPluginRegistry
net.corda.bank.plugin.BankOfCordaPlugin

View File

@ -1,10 +1,10 @@
package net.corda.irs.plugin
import net.corda.core.node.CordaPluginRegistry
import net.corda.irs.api.InterestRateSwapAPI
import net.corda.webserver.services.WebServerPluginRegistry
import java.util.function.Function
class IRSPlugin : CordaPluginRegistry() {
class IRSPlugin : WebServerPluginRegistry {
override val webApis = listOf(Function(::InterestRateSwapAPI))
override val staticServeDirs: Map<String, String> = mapOf(
"irsdemo" to javaClass.classLoader.getResource("irsweb").toExternalForm()

View File

@ -1,2 +0,0 @@
# Register a ServiceLoader service extending from net.corda.core.node.CordaPluginRegistry
net.corda.irs.plugin.IRSPlugin

View File

@ -0,0 +1,2 @@
# Register a ServiceLoader service extending from net.corda.webserver.services.WebServerPluginRegistry
net.corda.irs.plugin.IRSPlugin

View File

@ -15,15 +15,17 @@ import net.corda.core.serialization.SerializationCustomization
import net.corda.vega.analytics.CordaMarketData
import net.corda.vega.analytics.InitialMarginTriple
import net.corda.vega.api.PortfolioApi
import net.corda.webserver.services.WebServerPluginRegistry
import java.util.function.Function
/**
* [SimmService] is the object that makes available the flows and services for the Simm agreement / evaluation flow
* It also enables a human usable web service for demo purposes - if available.
* It is loaded via discovery - see [CordaPluginRegistry]
* [SimmService] is the object that makes available the flows and services for the Simm agreement / evaluation flow.
* It is loaded via discovery - see [CordaPluginRegistry].
* It is also the object that enables a human usable web service for demo purpose
* It is loaded via discovery see [WebServerPluginRegistry].
*/
object SimmService {
class Plugin : CordaPluginRegistry() {
class Plugin : CordaPluginRegistry(), WebServerPluginRegistry {
override val webApis = listOf(Function(::PortfolioApi))
override val staticServeDirs: Map<String, String> = mapOf("simmvaluationdemo" to javaClass.classLoader.getResource("simmvaluationweb").toExternalForm())
override fun customizeSerialization(custom: SerializationCustomization): Boolean {

View File

@ -0,0 +1,2 @@
# Register a ServiceLoader service extending from net.corda.webserver.services.WebServerPluginRegistry
net.corda.vega.services.SimmService$Plugin

View File

@ -3,10 +3,10 @@ package net.corda.webserver.internal
import com.google.common.html.HtmlEscapers.htmlEscaper
import net.corda.client.rpc.CordaRPCClient
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.node.CordaPluginRegistry
import net.corda.core.utilities.loggerFor
import net.corda.nodeapi.ArtemisMessagingComponent
import net.corda.webserver.WebServerConfig
import net.corda.webserver.services.WebServerPluginRegistry
import net.corda.webserver.servlets.*
import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
import org.eclipse.jetty.server.*
@ -203,9 +203,9 @@ class NodeWebServer(val config: WebServerConfig) {
return connection.proxy
}
/** Fetch CordaPluginRegistry classes registered in META-INF/services/net.corda.core.node.CordaPluginRegistry files that exist in the classpath */
val pluginRegistries: List<CordaPluginRegistry> by lazy {
ServiceLoader.load(CordaPluginRegistry::class.java).toList()
/** Fetch WebServerPluginRegistry classes registered in META-INF/services/net.corda.webserver.services.WebServerPluginRegistry files that exist in the classpath */
val pluginRegistries: List<WebServerPluginRegistry> by lazy {
ServiceLoader.load(WebServerPluginRegistry::class.java).toList()
}
/** Used for useful info that we always want to show, even when not logging to the console */

View File

@ -0,0 +1,24 @@
package net.corda.webserver.services
import net.corda.core.messaging.CordaRPCOps
import java.util.function.Function
/**
* Implement this interface on a class advertised in a META-INF/services/net.corda.webserver.services.WebServerPluginRegistry file
* to create web API to connect to Corda node via RPC.
*/
interface WebServerPluginRegistry {
/**
* List of lambdas returning JAX-RS objects. They may only depend on the RPC interface, as the webserver lives
* in a process separate from the node itself.
*/
val webApis: List<Function<CordaRPCOps, out Any>> get() = emptyList()
/**
* Map of static serving endpoints to the matching resource directory. All endpoints will be prefixed with "/web" and postfixed with "\*.
* Resource directories can be either on disk directories (especially when debugging) in the form "a/b/c". Serving from a JAR can
* be specified with: javaClass.getResource("<folder-in-jar>").toExternalForm()
*/
val staticServeDirs: Map<String, String> get() = emptyMap()
}

View File

@ -3,7 +3,7 @@ package net.corda.webserver.servlets
import kotlinx.html.*
import kotlinx.html.stream.appendHTML
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.node.CordaPluginRegistry
import net.corda.webserver.services.WebServerPluginRegistry
import org.glassfish.jersey.server.model.Resource
import org.glassfish.jersey.server.model.ResourceMethod
import java.io.IOException
@ -15,7 +15,7 @@ import javax.servlet.http.HttpServletResponse
* Dumps some data about the installed CorDapps.
* TODO: Add registered flow initiators.
*/
class CorDappInfoServlet(val plugins: List<CordaPluginRegistry>, val rpc: CordaRPCOps): HttpServlet() {
class CorDappInfoServlet(val plugins: List<WebServerPluginRegistry>, val rpc: CordaRPCOps): HttpServlet() {
@Throws(IOException::class)
override fun doGet(req: HttpServletRequest, resp: HttpServletResponse) {