mirror of
https://github.com/corda/corda.git
synced 2024-12-19 13:08:04 +00:00
Merge pull request #589 from corda/rog-webserver-index
Rog webserver index
This commit is contained in:
commit
93311308a6
@ -54,6 +54,9 @@ dependencies {
|
|||||||
compile "org.glassfish.jersey.containers:jersey-container-jetty-http:$jersey_version"
|
compile "org.glassfish.jersey.containers:jersey-container-jetty-http:$jersey_version"
|
||||||
compile "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version"
|
compile "org.glassfish.jersey.media:jersey-media-json-jackson:$jersey_version"
|
||||||
|
|
||||||
|
// For rendering the index page.
|
||||||
|
compile "org.jetbrains.kotlinx:kotlinx-html-jvm:0.6.3"
|
||||||
|
|
||||||
testCompile "junit:junit:$junit_version"
|
testCompile "junit:junit:$junit_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,10 +7,7 @@ import net.corda.core.node.CordaPluginRegistry
|
|||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.nodeapi.ArtemisMessagingComponent
|
import net.corda.nodeapi.ArtemisMessagingComponent
|
||||||
import net.corda.webserver.WebServerConfig
|
import net.corda.webserver.WebServerConfig
|
||||||
import net.corda.webserver.servlets.AttachmentDownloadServlet
|
import net.corda.webserver.servlets.*
|
||||||
import net.corda.webserver.servlets.DataUploadServlet
|
|
||||||
import net.corda.webserver.servlets.ObjectMapperConfig
|
|
||||||
import net.corda.webserver.servlets.ResponseFilter
|
|
||||||
import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
|
import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException
|
||||||
import org.eclipse.jetty.server.*
|
import org.eclipse.jetty.server.*
|
||||||
import org.eclipse.jetty.server.handler.ErrorHandler
|
import org.eclipse.jetty.server.handler.ErrorHandler
|
||||||
@ -159,13 +156,13 @@ class NodeWebServer(val config: WebServerConfig) {
|
|||||||
addServlet(staticDir, "/web/${it.first}/*")
|
addServlet(staticDir, "/web/${it.first}/*")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have at least one static web data directory, redirect / to the right URL.
|
|
||||||
staticDirs.firstOrNull()?.let { addServlet(ServletHolder(IndexRedirectServlet("/web/${it.first}")), "/") }
|
|
||||||
|
|
||||||
// Give the app a slightly better name in JMX rather than a randomly generated one and enable JMX
|
// 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",
|
resourceConfig.addProperties(mapOf(ServerProperties.APPLICATION_NAME to "node.api",
|
||||||
ServerProperties.MONITORING_STATISTICS_MBEANS_ENABLED to "true"))
|
ServerProperties.MONITORING_STATISTICS_MBEANS_ENABLED to "true"))
|
||||||
|
|
||||||
|
val infoServlet = ServletHolder(CorDappInfoServlet(pluginRegistries, localRpc))
|
||||||
|
addServlet(infoServlet, "")
|
||||||
|
|
||||||
val container = ServletContainer(resourceConfig)
|
val container = ServletContainer(resourceConfig)
|
||||||
val jerseyServlet = ServletHolder(container)
|
val jerseyServlet = ServletHolder(container)
|
||||||
addServlet(jerseyServlet, "/api/*")
|
addServlet(jerseyServlet, "/api/*")
|
||||||
@ -173,12 +170,6 @@ class NodeWebServer(val config: WebServerConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class IndexRedirectServlet(private val redirectTo: String) : HttpServlet() {
|
|
||||||
override fun doGet(req: HttpServletRequest, resp: HttpServletResponse) {
|
|
||||||
resp.sendRedirect(resp.encodeRedirectURL(redirectTo))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun retryConnectLocalRpc(): CordaRPCOps {
|
private fun retryConnectLocalRpc(): CordaRPCOps {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
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 org.glassfish.jersey.server.model.Resource
|
||||||
|
import org.glassfish.jersey.server.model.ResourceMethod
|
||||||
|
import javax.servlet.http.HttpServlet
|
||||||
|
import javax.servlet.http.HttpServletRequest
|
||||||
|
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() {
|
||||||
|
|
||||||
|
override fun doGet(req: HttpServletRequest, resp: HttpServletResponse) {
|
||||||
|
resp.writer.appendHTML().html {
|
||||||
|
head {
|
||||||
|
title { +"Installed CorDapps" }
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
h2 { +"Installed CorDapps" }
|
||||||
|
plugins.forEach { plugin ->
|
||||||
|
h3 { +plugin::class.java.name }
|
||||||
|
if (plugin.requiredFlows.isNotEmpty()) {
|
||||||
|
div {
|
||||||
|
p { +"Whitelisted flows:" }
|
||||||
|
ul {
|
||||||
|
plugin.requiredFlows.map { it.key }.forEach { li { +it } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (plugin.webApis.isNotEmpty()) {
|
||||||
|
div {
|
||||||
|
plugin.webApis.forEach { api ->
|
||||||
|
val resource = Resource.from(api.apply(rpc)::class.java)
|
||||||
|
p { +"${resource.name}:" }
|
||||||
|
val endpoints = processEndpoints("", resource, mutableListOf<Endpoint>())
|
||||||
|
ul {
|
||||||
|
endpoints.forEach {
|
||||||
|
li { a(it.uri) { +"${it.method}\t${it.text}" } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (plugin.staticServeDirs.isNotEmpty()) {
|
||||||
|
div {
|
||||||
|
p { +"Static web content:" }
|
||||||
|
ul {
|
||||||
|
plugin.staticServeDirs.map { it.key }.forEach {
|
||||||
|
li { a("web/$it") { +it } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Endpoint(val method: String, val uri: String, val text: String)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively enumerate and record all of the end-points listed in the API implementations.
|
||||||
|
*/
|
||||||
|
private fun processEndpoints(uriPrefix: String, resource: Resource, endpoints: MutableList<Endpoint>): List<Endpoint> {
|
||||||
|
val resources = arrayListOf<Resource>()
|
||||||
|
val path = if (resource.path != null) "$uriPrefix/${resource.path}" else uriPrefix
|
||||||
|
|
||||||
|
resources.addAll(resource.childResources)
|
||||||
|
|
||||||
|
for (method in resource.allMethods) {
|
||||||
|
if (method.type == ResourceMethod.JaxrsType.SUB_RESOURCE_LOCATOR) {
|
||||||
|
resources.add( Resource.from(resource.resourceLocator.invocable.definitionMethod.returnType))
|
||||||
|
} else {
|
||||||
|
endpoints.add(Endpoint(method.httpMethod, "api$path", resource.path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resources.forEach {
|
||||||
|
processEndpoints(path, it, endpoints)
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoints
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user