mirror of
https://github.com/corda/corda.git
synced 2025-06-22 09:08:49 +00:00
Make the IRS Demo web api an api plugin (scanned from the Node classpath) and use the same permission checking entry point for web api's as the scheduler.
Fix whitespace Change ProtocolLogicRefFactory to use Map<String, Set<String>> as whitelist definition
This commit is contained in:
@ -9,6 +9,7 @@ import com.r3corda.core.crypto.Party
|
||||
import com.r3corda.core.messaging.MessagingService
|
||||
import com.r3corda.core.messaging.runOnNextMessage
|
||||
import com.r3corda.core.node.CityDatabase
|
||||
import com.r3corda.core.node.CordaPluginRegistry
|
||||
import com.r3corda.core.node.NodeInfo
|
||||
import com.r3corda.core.node.PhysicalLocation
|
||||
import com.r3corda.core.node.services.*
|
||||
@ -97,7 +98,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
|
||||
|
||||
// Internal only
|
||||
override val monitoringService: MonitoringService = MonitoringService(MetricRegistry())
|
||||
override val protocolLogicRefFactory = ProtocolLogicRefFactory()
|
||||
override val protocolLogicRefFactory: ProtocolLogicRefFactory get() = protocolLogicFactory
|
||||
|
||||
override fun <T> startProtocol(loggerName: String, logic: ProtocolLogic<T>): ListenableFuture<T> {
|
||||
return smm.add(loggerName, logic)
|
||||
@ -124,6 +125,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
|
||||
lateinit var net: MessagingService
|
||||
lateinit var api: APIServer
|
||||
lateinit var scheduler: SchedulerService
|
||||
lateinit var protocolLogicFactory: ProtocolLogicRefFactory
|
||||
var isPreviousCheckpointsPresent = false
|
||||
private set
|
||||
|
||||
@ -158,6 +160,8 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
|
||||
checkpointStorage,
|
||||
serverThread)
|
||||
|
||||
protocolLogicFactory = initialiseProtocolLogicFactory()
|
||||
|
||||
// This object doesn't need to be referenced from this class because it registers handlers on the network
|
||||
// service and so that keeps it from being collected.
|
||||
DataVendingService(net, storage, services.networkMapCache)
|
||||
@ -180,6 +184,19 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
|
||||
return this
|
||||
}
|
||||
|
||||
private fun initialiseProtocolLogicFactory(): ProtocolLogicRefFactory {
|
||||
val serviceLoader = ServiceLoader.load(CordaPluginRegistry::class.java)
|
||||
val pluginRegistries = serviceLoader.toList()
|
||||
val protocolWhitelist = HashMap<String, Set<String>>()
|
||||
for (plugin in pluginRegistries) {
|
||||
for (protocol in plugin.requiredProtocols) {
|
||||
protocolWhitelist.merge(protocol.key, protocol.value, { x, y -> x + y })
|
||||
}
|
||||
}
|
||||
|
||||
return ProtocolLogicRefFactory(protocolWhitelist)
|
||||
}
|
||||
|
||||
/**
|
||||
* Run any tasks that are needed to ensure the node is in a correct state before running start()
|
||||
*/
|
||||
|
@ -3,10 +3,11 @@ package com.r3corda.node.internal
|
||||
import com.codahale.metrics.JmxReporter
|
||||
import com.google.common.net.HostAndPort
|
||||
import com.r3corda.core.messaging.MessagingService
|
||||
import com.r3corda.core.node.CordaPluginRegistry
|
||||
import com.r3corda.core.node.NodeInfo
|
||||
import com.r3corda.core.node.ServiceHub
|
||||
import com.r3corda.core.node.services.ServiceType
|
||||
import com.r3corda.core.utilities.loggerFor
|
||||
import com.r3corda.node.api.APIServer
|
||||
import com.r3corda.node.serialization.NodeClock
|
||||
import com.r3corda.node.services.config.NodeConfiguration
|
||||
import com.r3corda.node.services.messaging.ArtemisMessagingService
|
||||
@ -27,9 +28,9 @@ import java.io.RandomAccessFile
|
||||
import java.lang.management.ManagementFactory
|
||||
import java.net.InetSocketAddress
|
||||
import java.nio.channels.FileLock
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.time.Clock
|
||||
import java.util.*
|
||||
import javax.management.ObjectName
|
||||
|
||||
class ConfigurationException(message: String) : Exception(message)
|
||||
@ -55,8 +56,7 @@ class ConfigurationException(message: String) : Exception(message)
|
||||
*/
|
||||
class Node(dir: Path, val p2pAddr: HostAndPort, val webServerAddr: HostAndPort, configuration: NodeConfiguration,
|
||||
networkMapAddress: NodeInfo?, advertisedServices: Set<ServiceType>,
|
||||
clock: Clock = NodeClock(),
|
||||
val clientAPIs: List<Class<*>> = listOf()) : AbstractNode(dir, configuration, networkMapAddress, advertisedServices, clock) {
|
||||
clock: Clock = NodeClock()) : AbstractNode(dir, configuration, networkMapAddress, advertisedServices, clock) {
|
||||
companion object {
|
||||
/** The port that is used by default if none is specified. As you know, 31337 is the most elite number. */
|
||||
val DEFAULT_PORT = 31337
|
||||
@ -109,12 +109,15 @@ class Node(dir: Path, val p2pAddr: HostAndPort, val webServerAddr: HostAndPort,
|
||||
resourceConfig.register(ResponseFilter())
|
||||
resourceConfig.register(api)
|
||||
|
||||
for(customAPIClass in clientAPIs) {
|
||||
val customAPI = customAPIClass.getConstructor(APIServer::class.java).newInstance(api)
|
||||
val serviceLoader = ServiceLoader.load(CordaPluginRegistry::class.java)
|
||||
val pluginRegistries = serviceLoader.toList()
|
||||
val webAPIsOnClasspath = pluginRegistries.flatMap { x -> x.webApis }
|
||||
for (webapi in webAPIsOnClasspath) {
|
||||
log.info("Add Plugin web API from attachment ${webapi.name}")
|
||||
val customAPI = webapi.getConstructor(ServiceHub::class.java).newInstance(services)
|
||||
resourceConfig.register(customAPI)
|
||||
}
|
||||
|
||||
|
||||
// Give the app a slightly better name in JMX rather than a randomly generated one and enable JMX
|
||||
resourceConfig.addProperties(mapOf(ServerProperties.APPLICATION_NAME to "node.api",
|
||||
ServerProperties.MONITORING_STATISTICS_MBEANS_ENABLED to "true"))
|
||||
@ -187,5 +190,5 @@ class Node(dir: Path, val p2pAddr: HostAndPort, val webServerAddr: HostAndPort,
|
||||
val ourProcessID: String = ManagementFactory.getRuntimeMXBean().name.split("@")[0]
|
||||
f.setLength(0)
|
||||
f.write(ourProcessID.toByteArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,4 +29,11 @@ abstract class ServiceHubInternal : ServiceHub {
|
||||
* itself, at which point this method would not be needed (by the scheduler)
|
||||
*/
|
||||
abstract fun <T> startProtocol(loggerName: String, logic: ProtocolLogic<T>): ListenableFuture<T>
|
||||
|
||||
override fun <T : Any> invokeProtocolAsync(logicType: Class<out ProtocolLogic<T>>, vararg args: Any?): ListenableFuture<T> {
|
||||
val logicRef = protocolLogicRefFactory.create(logicType, *args)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val logic = protocolLogicRefFactory.toProtocolLogic(logicRef) as ProtocolLogic<T>
|
||||
return startProtocol(logicType.simpleName, logic)
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import com.r3corda.core.crypto.signWithECDSA
|
||||
import com.r3corda.core.math.CubicSplineInterpolator
|
||||
import com.r3corda.core.math.Interpolator
|
||||
import com.r3corda.core.math.InterpolatorFactory
|
||||
import com.r3corda.core.node.CordaPluginRegistry
|
||||
import com.r3corda.core.node.services.ServiceType
|
||||
import com.r3corda.core.protocols.ProtocolLogic
|
||||
import com.r3corda.core.utilities.ProgressTracker
|
||||
@ -23,6 +24,7 @@ import java.io.InputStream
|
||||
import java.math.BigDecimal
|
||||
import java.security.KeyPair
|
||||
import java.time.Clock
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
import java.util.*
|
||||
@ -93,6 +95,15 @@ object NodeInterestRates {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the protocol that is used with the Fixing integration tests
|
||||
*/
|
||||
class FixingServicePlugin : CordaPluginRegistry {
|
||||
override val webApis: List<Class<*>> = emptyList()
|
||||
override val requiredProtocols: Map<String, Set<String>> = mapOf(Pair(TwoPartyDealProtocol.FixingRoleDecider::class.java.name, setOf(Duration::class.java.name, StateRef::class.java.name)))
|
||||
|
||||
}
|
||||
|
||||
// File upload support
|
||||
override val dataTypePrefix = "interest-rates"
|
||||
override val acceptableFileExtensions = listOf(".rates", ".txt")
|
||||
|
@ -43,7 +43,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
|
||||
// We have to allow Java boxed primitives but Kotlin warns we shouldn't be using them
|
||||
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||
val factory = ProtocolLogicRefFactory(setOf(TestProtocolLogic::class.java.name), setOf(NodeSchedulerServiceTest::class.java.name, Integer::class.java.name))
|
||||
val factory = ProtocolLogicRefFactory(mapOf(Pair(TestProtocolLogic::class.java.name, setOf(NodeSchedulerServiceTest::class.java.name, Integer::class.java.name))))
|
||||
|
||||
val scheduler: NodeSchedulerService
|
||||
val services: ServiceHub
|
||||
|
Reference in New Issue
Block a user