mirror of
https://github.com/corda/corda.git
synced 2025-06-22 17:09:00 +00:00
DemoBench: open web page automatically once web server has started.
This commit is contained in:
@ -1,6 +1,5 @@
|
|||||||
package net.corda.demobench.views
|
package net.corda.demobench.views
|
||||||
|
|
||||||
import com.google.common.util.concurrent.RateLimiter
|
|
||||||
import com.jediterm.terminal.TerminalColor
|
import com.jediterm.terminal.TerminalColor
|
||||||
import com.jediterm.terminal.TextStyle
|
import com.jediterm.terminal.TextStyle
|
||||||
import com.jediterm.terminal.ui.settings.DefaultSettingsProvider
|
import com.jediterm.terminal.ui.settings.DefaultSettingsProvider
|
||||||
@ -13,6 +12,8 @@ import javafx.scene.layout.StackPane
|
|||||||
import javafx.scene.layout.VBox
|
import javafx.scene.layout.VBox
|
||||||
import javafx.util.Duration
|
import javafx.util.Duration
|
||||||
import net.corda.client.rpc.notUsed
|
import net.corda.client.rpc.notUsed
|
||||||
|
import net.corda.core.success
|
||||||
|
import net.corda.core.then
|
||||||
import net.corda.demobench.explorer.ExplorerController
|
import net.corda.demobench.explorer.ExplorerController
|
||||||
import net.corda.demobench.model.NodeConfig
|
import net.corda.demobench.model.NodeConfig
|
||||||
import net.corda.demobench.model.NodeController
|
import net.corda.demobench.model.NodeController
|
||||||
@ -24,12 +25,9 @@ import net.corda.demobench.web.DBViewer
|
|||||||
import net.corda.demobench.web.WebServerController
|
import net.corda.demobench.web.WebServerController
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
import java.awt.Dimension
|
import java.awt.Dimension
|
||||||
import java.io.IOException
|
import java.net.URI
|
||||||
import java.net.SocketException
|
|
||||||
import java.net.URL
|
|
||||||
import java.util.logging.Level
|
import java.util.logging.Level
|
||||||
import javax.swing.SwingUtilities
|
import javax.swing.SwingUtilities
|
||||||
import kotlin.concurrent.thread
|
|
||||||
|
|
||||||
class NodeTerminalView : Fragment() {
|
class NodeTerminalView : Fragment() {
|
||||||
override val root by fxml<VBox>()
|
override val root by fxml<VBox>()
|
||||||
@ -131,6 +129,8 @@ class NodeTerminalView : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var webURL: URI? = null
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We only want to run one web server for each node.
|
* We only want to run one web server for each node.
|
||||||
* So disable the "launch" button when we have
|
* So disable the "launch" button when we have
|
||||||
@ -139,32 +139,20 @@ class NodeTerminalView : Fragment() {
|
|||||||
*/
|
*/
|
||||||
fun configureWebButton(config: NodeConfig) {
|
fun configureWebButton(config: NodeConfig) {
|
||||||
launchWebButton.setOnAction {
|
launchWebButton.setOnAction {
|
||||||
|
if (webURL != null) {
|
||||||
|
app.hostServices.showDocument(webURL.toString())
|
||||||
|
return@setOnAction
|
||||||
|
}
|
||||||
launchWebButton.isDisable = true
|
launchWebButton.isDisable = true
|
||||||
|
|
||||||
webServer.open(config, onExit = {
|
log.info("Starting web server for ${config.legalName}")
|
||||||
launchWebButton.isDisable = false
|
webServer.open(config) then {
|
||||||
})
|
Platform.runLater { launchWebButton.isDisable = false }
|
||||||
|
} success {
|
||||||
openBrowserWhenWebServerHasStarted(config)
|
log.info("Web server for ${config.legalName} started on $it")
|
||||||
}
|
Platform.runLater {
|
||||||
}
|
webURL = it
|
||||||
|
app.hostServices.showDocument(it.toString())
|
||||||
private fun openBrowserWhenWebServerHasStarted(config: NodeConfig) {
|
|
||||||
thread {
|
|
||||||
log.info("Waiting for web server to start ...")
|
|
||||||
val url = URL("http://localhost:${config.webPort}/")
|
|
||||||
val rateLimiter = RateLimiter.create(1.0)
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
rateLimiter.acquire()
|
|
||||||
val conn = url.openConnection()
|
|
||||||
conn.connectTimeout = 1000 // msec
|
|
||||||
conn.connect()
|
|
||||||
log.info("Web server started")
|
|
||||||
app.hostServices.showDocument(url.toString())
|
|
||||||
break
|
|
||||||
} catch(e: SocketException) {
|
|
||||||
} catch(e: IOException) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,21 @@
|
|||||||
package net.corda.demobench.web
|
package net.corda.demobench.web
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
|
import com.google.common.util.concurrent.RateLimiter
|
||||||
|
import com.google.common.util.concurrent.SettableFuture
|
||||||
|
import net.corda.core.catch
|
||||||
|
import net.corda.core.minutes
|
||||||
|
import net.corda.core.until
|
||||||
import net.corda.core.utilities.loggerFor
|
import net.corda.core.utilities.loggerFor
|
||||||
import net.corda.demobench.model.NodeConfig
|
import net.corda.demobench.model.NodeConfig
|
||||||
import net.corda.demobench.readErrorLines
|
import net.corda.demobench.readErrorLines
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
import java.net.URI
|
||||||
|
import java.time.Instant
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
import java.util.concurrent.TimeoutException
|
||||||
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
class WebServer internal constructor(private val webServerController: WebServerController) : AutoCloseable {
|
class WebServer internal constructor(private val webServerController: WebServerController) : AutoCloseable {
|
||||||
private companion object {
|
private companion object {
|
||||||
@ -15,13 +26,12 @@ class WebServer internal constructor(private val webServerController: WebServerC
|
|||||||
private var process: Process? = null
|
private var process: Process? = null
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun open(config: NodeConfig, onExit: (NodeConfig) -> Unit) {
|
fun open(config: NodeConfig): ListenableFuture<URI> {
|
||||||
val nodeDir = config.nodeDir.toFile()
|
val nodeDir = config.nodeDir.toFile()
|
||||||
|
|
||||||
if (!nodeDir.isDirectory) {
|
if (!nodeDir.isDirectory) {
|
||||||
log.warn("Working directory '{}' does not exist.", nodeDir.absolutePath)
|
log.warn("Working directory '{}' does not exist.", nodeDir.absolutePath)
|
||||||
onExit(config)
|
return SettableFuture.create()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -46,12 +56,18 @@ class WebServer internal constructor(private val webServerController: WebServerC
|
|||||||
} else {
|
} else {
|
||||||
log.error("Web Server for '{}' has exited (value={}, {})", config.legalName, exitValue, errors)
|
log.error("Web Server for '{}' has exited (value={}, {})", config.legalName, exitValue, errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
onExit(config)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val future = SettableFuture.create<URI>()
|
||||||
|
thread {
|
||||||
|
future.catch {
|
||||||
|
log.info("Waiting for web server for ${config.legalName} to start ...")
|
||||||
|
waitForStart(config.webPort)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return future
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
log.error("Failed to launch Web Server for '{}': {}", config.legalName, e.message)
|
log.error("Failed to launch Web Server for '{}': {}", config.legalName, e.message)
|
||||||
onExit(config)
|
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,4 +84,24 @@ class WebServer internal constructor(private val webServerController: WebServerC
|
|||||||
log.error("Failed to close stream: '{}'", e.message)
|
log.error("Failed to close stream: '{}'", e.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun waitForStart(port: Int): URI {
|
||||||
|
val url = URI("http://localhost:$port/")
|
||||||
|
val rateLimiter = RateLimiter.create(2.0)
|
||||||
|
val start = Instant.now()
|
||||||
|
val timeout = 1.minutes
|
||||||
|
while ((start until Instant.now()) < timeout) {
|
||||||
|
try {
|
||||||
|
rateLimiter.acquire()
|
||||||
|
val conn = url.toURL().openConnection() as HttpURLConnection
|
||||||
|
conn.connectTimeout = 500 // msec
|
||||||
|
conn.requestMethod = "HEAD"
|
||||||
|
conn.connect()
|
||||||
|
conn.disconnect()
|
||||||
|
return url
|
||||||
|
} catch(e: IOException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw TimeoutException("Web server did not start within ${timeout.seconds} seconds")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user