This is an automated email from the ASF dual-hosted git repository.
toulmean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-tuweni.git
The following commit(s) were added to refs/heads/main by this push:
new dc0bd010 simplify the UI by using webjars - still WIP, and simpler
spring app
new decdd55c Merge pull request #453 from
atoulme/move_to_use_templates_for_ui
dc0bd010 is described below
commit dc0bd010baaedc02b762eaa14ada48a23d415e4d
Author: Antoine Toulme <[email protected]>
AuthorDate: Mon Dec 12 00:59:37 2022 -0800
simplify the UI by using webjars - still WIP, and simpler spring app
---
dependency-versions.gradle | 17 ++---
eth-client-app/build.gradle | 2 +
.../apache/tuweni/ethclient/EthereumClientApp.kt | 9 +--
eth-client-ui/build.gradle | 18 ++---
.../apache/tuweni/ethclientui/UIIntegrationTest.kt | 25 +++---
.../tuweni/ethclientui/ClientUIApplication.kt | 84 +++++++++++++++++++++
.../org/apache/tuweni/ethclientui/JSONProvider.kt | 56 --------------
.../kotlin/org/apache/tuweni/ethclientui/UI.kt | 68 -----------------
.../{ => controller}/ConfigurationService.kt | 26 +++----
.../Controller.kt} | 34 ++++-----
.../ethclientui/{ => controller}/StateService.kt | 29 ++++---
eth-client-ui/src/main/resources/application.yml | 36 +++++++++
.../resources/{webapp => templates}/config.html | 0
.../main/resources/{webapp => templates}/config.js | 0
.../resources/{webapp => templates}/favicon.ico | Bin
.../resources/{webapp => templates}/img/tuweni.svg | 0
.../resources/{webapp => templates}/index.html | 8 +-
.../resources/{webapp => templates}/state.html | 0
.../main/resources/{webapp => templates}/state.js | 0
eth-faucet/build.gradle | 2 +-
20 files changed, 202 insertions(+), 212 deletions(-)
diff --git a/dependency-versions.gradle b/dependency-versions.gradle
index ecda0b52..355adaa6 100644
--- a/dependency-versions.gradle
+++ b/dependency-versions.gradle
@@ -33,19 +33,18 @@ dependencyManagement {
dependency('com.zaxxer:HikariCP:4.0.3')
dependency('info.picocli:picocli:4.0.0-alpha-2')
dependency('io.grpc:grpc-netty-shaded:1.38.0')
- dependency('io.ktor:ktor-client-core:1.4.2')
- dependency('io.ktor:ktor-client-json:1.4.2')
- dependency('io.ktor:ktor-client-serialization:1.4.2')
- dependency('io.ktor:ktor-client-cio:1.4.2')
dependency('net.java.dev.jna:jna:5.11.0')
dependency('org.hyperledger.besu:bls12-381:0.4.3')
dependency('org.hyperledger.besu:altbn128:0.4.3')
dependency('org.hyperledger.besu:secp256k1:0.4.3')
- dependency('io.ktor:ktor-network:1.4.2')
- dependency('io.ktor:ktor-server-core:1.4.2')
- dependency('io.ktor:ktor-server-netty:1.4.2')
- dependency('org.springframework.boot:spring-boot-starter-thymeleaf:2.4.1')
+ dependency('org.springframework:spring-context:5.3.24')
+ dependency('org.springframework.boot:spring-boot:2.7.6')
+ dependency('org.springframework.boot:spring-boot-starter:2.7.6')
+ dependency('org.springframework.boot:spring-boot-starter-thymeleaf:2.7.6')
+ dependency('org.springframework.boot:spring-boot-starter-web:2.7.6')
+ dependency('org.springframework.boot:spring-boot-starter-webflux:2.7.6')
+ dependency('org.springframework.boot:spring-boot-starter-tomcat:2.7.6')
dependency('io.opentelemetry:opentelemetry-api:1.2.0')
dependency('io.opentelemetry:opentelemetry-api-metrics:1.2.0-alpha')
@@ -139,7 +138,7 @@ dependencyManagement {
dependency('org.connid:framework:1.3.2')
dependency('org.connid:framework-internal:1.3.2')
- dependency('org.webjars:bootstrap:4.1.3')
+ dependency('org.webjars:bootstrap:4.5.3')
dependency('org.webjars:webjars-locator:0.40')
dependency('org.xerial.snappy:snappy-java:1.1.8.4')
diff --git a/eth-client-app/build.gradle b/eth-client-app/build.gradle
index 1c315293..5a20d0a8 100644
--- a/eth-client-app/build.gradle
+++ b/eth-client-app/build.gradle
@@ -19,6 +19,8 @@ dependencies {
implementation 'io.vertx:vertx-core'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core'
implementation 'org.bouncycastle:bcprov-jdk15on'
+ implementation 'org.springframework:spring-context'
+
implementation project(':app-commons')
implementation project(':crypto')
diff --git
a/eth-client-app/src/main/kotlin/org/apache/tuweni/ethclient/EthereumClientApp.kt
b/eth-client-app/src/main/kotlin/org/apache/tuweni/ethclient/EthereumClientApp.kt
index c0640af9..7052d329 100644
---
a/eth-client-app/src/main/kotlin/org/apache/tuweni/ethclient/EthereumClientApp.kt
+++
b/eth-client-app/src/main/kotlin/org/apache/tuweni/ethclient/EthereumClientApp.kt
@@ -20,14 +20,14 @@ import io.vertx.core.Vertx
import kotlinx.coroutines.runBlocking
import org.apache.tuweni.app.commons.ApplicationUtils
import org.apache.tuweni.crypto.blake2bf.TuweniProvider
-import org.apache.tuweni.ethclientui.UI
+import org.apache.tuweni.ethclientui.ClientUIApplication
import org.bouncycastle.jce.provider.BouncyCastleProvider
import picocli.CommandLine
import java.nio.file.Path
import java.security.Security
import kotlin.system.exitProcess
-fun main(args: Array<String>) = runBlocking {
+fun main(args: Array<String>): Unit = runBlocking {
ApplicationUtils.renderBanner("Apache Tuweni client loading")
Security.addProvider(BouncyCastleProvider())
Security.addProvider(TuweniProvider())
@@ -47,9 +47,8 @@ fun main(args: Array<String>) = runBlocking {
Runtime.getRuntime().addShutdownHook(Thread(Runnable { ethClient.stop() }))
ethClient.start()
val (host, port) = opts.web!!.split(":")
- val ui = UI(networkInterface = host, port = port.toInt(), client = ethClient)
- Runtime.getRuntime().addShutdownHook(Thread(Runnable { ui.stop() }))
- ui.start()
+
+ ClientUIApplication.start(networkInterface = host, port = port.toInt(),
client = ethClient)
}
class AppOptions {
diff --git a/eth-client-ui/build.gradle b/eth-client-ui/build.gradle
index 64a0bea6..9ee339ea 100644
--- a/eth-client-ui/build.gradle
+++ b/eth-client-ui/build.gradle
@@ -15,16 +15,16 @@ description = 'Ethereum client UI'
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core'
- implementation 'org.eclipse.jetty:jetty-server'
- implementation 'org.eclipse.jetty:jetty-servlet'
- implementation 'org.eclipse.jetty:jetty-util'
- implementation 'org.glassfish.jersey.core:jersey-server'
- implementation 'org.glassfish.jersey.containers:jersey-container-servlet'
- implementation 'org.glassfish.jersey.media:jersey-media-json-jackson'
- implementation 'org.glassfish.jersey.inject:jersey-hk2'
- implementation 'javax.xml.bind:jaxb-api'
- implementation 'javax.servlet:javax.servlet-api'
+ implementation 'org.springframework.boot:spring-boot'
+ implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
+ implementation 'org.springframework.boot:spring-boot-starter'
+ implementation 'org.springframework.boot:spring-boot-starter-web'
+ implementation 'org.springframework.boot:spring-boot-starter-webflux'
+ implementation 'org.springframework.boot:spring-boot-starter-hateoas:2.7.6'
implementation 'javax.ws.rs:javax.ws.rs-api'
+ implementation 'org.webjars:bootstrap'
+ implementation 'org.webjars:webjars-locator'
+ implementation 'jakarta.annotation:jakarta.annotation-api:1.3.5'
implementation project(':bytes')
implementation project(':concurrent')
diff --git
a/eth-client-ui/src/integrationTest/kotlin/org/apache/tuweni/ethclientui/UIIntegrationTest.kt
b/eth-client-ui/src/integrationTest/kotlin/org/apache/tuweni/ethclientui/UIIntegrationTest.kt
index 19f0e0ba..a2377729 100644
---
a/eth-client-ui/src/integrationTest/kotlin/org/apache/tuweni/ethclientui/UIIntegrationTest.kt
+++
b/eth-client-ui/src/integrationTest/kotlin/org/apache/tuweni/ethclientui/UIIntegrationTest.kt
@@ -38,39 +38,42 @@ class UIIntegrationTest {
@Test
fun testServerComesUp(@VertxInstance vertx: Vertx, @TempDirectory tempDir:
Path) = runBlocking {
- val ui = UI(
- client = EthereumClient(
- vertx,
- EthereumClientConfig.fromString(
- """[storage.default]
+ val client = EthereumClient(
+ vertx,
+ EthereumClientConfig.fromString(
+ """[storage.default]
path="${tempDir.toAbsolutePath()}"
genesis="default"
[genesis.default]
path="classpath:/genesis/dev.json"
[peerRepository.default]
type="memory""""
- )
)
)
- ui.client.start()
+ val ui = ClientUIApplication.start(client = client, port = 9000)
+ client.start()
ui.start()
- val url = URL("http://localhost:" + ui.actualPort)
+ val app = ui.getBean(ClientUIApplication::class.java)
+ val url = URL("http://localhost:" + app.config.port)
val con = url.openConnection() as HttpURLConnection
con.requestMethod = "GET"
val response = con.inputStream.readAllBytes()
assertTrue(response.isNotEmpty())
- val url2 = URL("http://localhost:" + ui.actualPort + "/rest/config")
+ val url2 = URL("http://localhost:" + app.config.port + "/rest/config")
val con2 = url2.openConnection() as HttpURLConnection
con2.requestMethod = "GET"
val response2 = con2.inputStream.readAllBytes()
assertTrue(response2.isNotEmpty())
- val url3 = URL("http://localhost:" + ui.actualPort + "/rest/state")
+ val url3 = URL("http://localhost:" + app.config.port + "/rest/state")
val con3 = url3.openConnection() as HttpURLConnection
con3.requestMethod = "GET"
val response3 = con3.inputStream.readAllBytes()
assertTrue(response3.isNotEmpty())
-
assertEquals("""{"peerCounts":{"default":0},"bestBlocks":{"default":{"hash":"0xa08d1edb37ba1c62db764ef7c2566cbe368b850f5b3762c6c24114a3fd97b87f","number":"0x0000000000000000000000000000000000000000000000000000000000000000"}}}""",
String(response3))
+ assertEquals(
+
"""{"peerCounts":{"default":0},"bestBlocks":{"default":{"hash":"0xa08d1edb37ba1c62db764ef7c2566cbe368b850f5b3762c6c24114a3fd97b87f","number":"0x0000000000000000000000000000000000000000000000000000000000000000"}}}""",
+ String(response3)
+ )
ui.stop()
}
}
diff --git
a/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/ClientUIApplication.kt
b/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/ClientUIApplication.kt
new file mode 100644
index 00000000..0bb0a213
--- /dev/null
+++
b/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/ClientUIApplication.kt
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuweni.ethclientui
+
+import org.apache.tuweni.eth.EthJsonModule
+import org.apache.tuweni.ethclient.EthereumClient
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.WebApplicationType
+import org.springframework.boot.autoconfigure.SpringBootApplication
+import
org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer
+import org.springframework.boot.builder.SpringApplicationBuilder
+import
org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
+import org.springframework.boot.web.server.WebServerFactoryCustomizer
+import
org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory
+import org.springframework.boot.web.servlet.server.ServletWebServerFactory
+import org.springframework.context.ConfigurableApplicationContext
+import org.springframework.context.annotation.Bean
+import org.springframework.context.support.GenericApplicationContext
+import java.net.InetAddress
+
+@SpringBootApplication
+open class ClientUIApplication(@Autowired val config: Config) {
+
+ companion object {
+ fun start(
+ client: EthereumClient,
+ port: Int = 0,
+ networkInterface: String = "127.0.0.1",
+ contextPath: String = ""
+ ): ConfigurableApplicationContext {
+ val parentContext = GenericApplicationContext()
+ parentContext.beanFactory.registerSingleton("ethereumClient", client)
+ parentContext.beanFactory.registerSingleton("config", Config(port,
networkInterface, contextPath))
+
+ val springApp =
+ SpringApplicationBuilder(ClientUIApplication::class.java)
+ .web(WebApplicationType.SERVLET)
+ .parent(parentContext)
+ .build()
+ springApp.setRegisterShutdownHook(true)
+ parentContext.refresh()
+ return springApp.run()
+ }
+ }
+
+ @Bean
+ open fun jsonCustomizer(): Jackson2ObjectMapperBuilderCustomizer? {
+ return Jackson2ObjectMapperBuilderCustomizer { builder ->
+ builder.modules(EthJsonModule())
+ }
+ }
+
+ @Bean
+ open fun servletWebServerFactory(): ServletWebServerFactory {
+ return TomcatServletWebServerFactory()
+ }
+
+ @Bean
+ open fun webServerFactoryCustomizer():
WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
+ return WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
factory ->
+ run {
+ factory.setContextPath(config.contextPath)
+ factory.setPort(config.port)
+ factory.setAddress(InetAddress.getByName(config.networkInterface))
+ }
+ }
+ }
+}
+
+data class Config(val port: Int, val networkInterface: String, val
contextPath: String)
diff --git
a/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/JSONProvider.kt
b/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/JSONProvider.kt
deleted file mode 100644
index 365beb51..00000000
---
a/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/JSONProvider.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tuweni.ethclientui
-
-import com.fasterxml.jackson.databind.ObjectMapper
-import jakarta.ws.rs.Produces
-import jakarta.ws.rs.core.Feature
-import jakarta.ws.rs.core.FeatureContext
-import jakarta.ws.rs.core.MediaType
-import jakarta.ws.rs.ext.MessageBodyReader
-import jakarta.ws.rs.ext.MessageBodyWriter
-import jakarta.ws.rs.ext.Provider
-import org.apache.tuweni.eth.EthJsonModule
-import org.glassfish.jersey.jackson.internal.jackson.jaxrs.cfg.Annotations
-import
org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider
-
-@Provider
-@Produces(MediaType.APPLICATION_JSON)
-class JSONProvider : JacksonJaxbJsonProvider {
-
- constructor() : super()
- constructor(vararg annotationsToUse: Annotations?) : super(mapper,
annotationsToUse)
-
- companion object {
- val mapper = ObjectMapper()
-
- init {
- mapper.registerModule(EthJsonModule())
- }
- }
-
- init {
- setMapper(mapper)
- }
-}
-
-class MarshallingFeature : Feature {
- override fun configure(context: FeatureContext): Boolean {
- context.register(JSONProvider::class.java, MessageBodyReader::class.java,
MessageBodyWriter::class.java)
- return true
- }
-}
diff --git a/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/UI.kt
b/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/UI.kt
deleted file mode 100644
index 7f7e7716..00000000
--- a/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/UI.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.tuweni.ethclientui
-
-import org.apache.tuweni.ethclient.EthereumClient
-import org.eclipse.jetty.server.Server
-import org.eclipse.jetty.servlet.DefaultServlet
-import org.eclipse.jetty.servlet.ServletContextHandler
-import org.eclipse.jetty.servlet.ServletHolder
-import org.eclipse.jetty.util.resource.Resource
-import org.glassfish.jersey.server.ResourceConfig
-import org.glassfish.jersey.servlet.ServletContainer
-import java.net.InetSocketAddress
-
-class UI(
- val port: Int = 0,
- val networkInterface: String = "127.0.0.1",
- val path: String = "/",
- val client: EthereumClient
-) {
-
- private var server: Server? = null
-
- var actualPort: Int? = null
-
- fun start() {
- val newServer = Server(InetSocketAddress(networkInterface, port))
-
- val ctx = ServletContextHandler(ServletContextHandler.NO_SESSIONS)
-
- ctx.contextPath = path
- newServer.handler = ctx
-
- val config = ResourceConfig().packages(true,
"org.apache.tuweni.ethclientui").register(MarshallingFeature::class.java)
- val holder = ServletHolder(ServletContainer(config))
- holder.initOrder = 1
- ctx.addServlet(holder, "/rest/*")
-
-
ctx.setBaseResource(Resource.newResource(UI::class.java.getResource("/webapp")))
- val staticContent = ctx.addServlet(DefaultServlet::class.java, "/*")
- ctx.setWelcomeFiles(arrayOf("index.html"))
- staticContent.initOrder = 10
-
- newServer.stopAtShutdown = true
- newServer.start()
- holder.servlet.servletConfig.servletContext.setAttribute("ethclient",
client)
- server = newServer
- actualPort = newServer.uri.port
- }
-
- fun stop() {
- server?.stop()
- }
-}
diff --git
a/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/ConfigurationService.kt
b/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/controller/ConfigurationService.kt
similarity index 62%
copy from
eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/ConfigurationService.kt
copy to
eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/controller/ConfigurationService.kt
index 900005f7..f28687fd 100644
---
a/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/ConfigurationService.kt
+++
b/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/controller/ConfigurationService.kt
@@ -14,26 +14,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.tuweni.ethclientui
+package org.apache.tuweni.ethclientui.controller
-import jakarta.servlet.ServletContext
-import jakarta.ws.rs.GET
-import jakarta.ws.rs.Path
-import jakarta.ws.rs.Produces
-import jakarta.ws.rs.core.Context
-import jakarta.ws.rs.core.MediaType
import org.apache.tuweni.ethclient.EthereumClient
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.http.MediaType
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
-@Path("config")
+@RestController
+@RequestMapping("/rest/config")
class ConfigurationService {
- @Context
- var context: ServletContext? = null
+ @Autowired
+ var client: EthereumClient? = null
- @GET
- @Produces(MediaType.TEXT_PLAIN)
+ @GetMapping(value = [""], produces = [MediaType.TEXT_PLAIN_VALUE])
fun get(): String {
- val client = context!!.getAttribute("ethclient") as EthereumClient
- return client.config.toToml()
+ return client?.config?.toToml() ?: ""
}
}
diff --git
a/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/ConfigurationService.kt
b/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/controller/Controller.kt
similarity index 60%
rename from
eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/ConfigurationService.kt
rename to
eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/controller/Controller.kt
index 900005f7..e1906383 100644
---
a/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/ConfigurationService.kt
+++
b/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/controller/Controller.kt
@@ -14,26 +14,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.tuweni.ethclientui
+package org.apache.tuweni.ethclientui.controller
-import jakarta.servlet.ServletContext
-import jakarta.ws.rs.GET
-import jakarta.ws.rs.Path
-import jakarta.ws.rs.Produces
-import jakarta.ws.rs.core.Context
-import jakarta.ws.rs.core.MediaType
-import org.apache.tuweni.ethclient.EthereumClient
+import org.springframework.stereotype.Controller
+import org.springframework.web.bind.annotation.GetMapping
-@Path("config")
-class ConfigurationService {
+@Controller
+class Controller {
- @Context
- var context: ServletContext? = null
+ @GetMapping("/")
+ fun index(): String {
+ return "index"
+ }
+
+ @GetMapping("/config")
+ fun config(): String {
+ return "config"
+ }
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- fun get(): String {
- val client = context!!.getAttribute("ethclient") as EthereumClient
- return client.config.toToml()
+ @GetMapping("/state")
+ fun state(): String {
+ return "state"
}
}
diff --git
a/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/StateService.kt
b/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/controller/StateService.kt
similarity index 70%
rename from
eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/StateService.kt
rename to
eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/controller/StateService.kt
index e53157f6..0a6e99c2 100644
---
a/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/StateService.kt
+++
b/eth-client-ui/src/main/kotlin/org/apache/tuweni/ethclientui/controller/StateService.kt
@@ -14,38 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.tuweni.ethclientui
+package org.apache.tuweni.ethclientui.controller
-import jakarta.servlet.ServletContext
-import jakarta.ws.rs.GET
-import jakarta.ws.rs.Path
-import jakarta.ws.rs.Produces
-import jakarta.ws.rs.core.Context
-import jakarta.ws.rs.core.MediaType
import kotlinx.coroutines.runBlocking
import org.apache.tuweni.bytes.Bytes32
import org.apache.tuweni.ethclient.EthereumClient
import org.apache.tuweni.units.bigints.UInt256
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.http.MediaType
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
data class BlockHashAndNumber(val hash: Bytes32, val number: UInt256)
data class State(val peerCounts: Map<String, Long>, val bestBlocks:
Map<String, BlockHashAndNumber>)
-@Path("state")
+@RestController
+@RequestMapping("/rest/state")
class StateService {
- @Context
- var context: ServletContext? = null
+ @Autowired
+ var client: EthereumClient? = null
- @GET
- @Produces(MediaType.APPLICATION_JSON)
+ @GetMapping(value = [""], produces = [MediaType.APPLICATION_JSON_VALUE])
fun get(): State {
- val client = context!!.getAttribute("ethclient") as EthereumClient
-
- val peerCounts = client.peerRepositories.entries.map {
+ val peerCounts = client!!.peerRepositories.entries.map {
Pair(it.key, it.value.activeConnections().count())
}
- val bestBlocks = client.storageRepositories.entries.map {
+ val bestBlocks = client!!.storageRepositories.entries.map {
runBlocking {
val bestBlock = it.value.retrieveChainHeadHeader()
Pair(it.key, BlockHashAndNumber(bestBlock.hash, bestBlock.number))
diff --git a/eth-client-ui/src/main/resources/application.yml
b/eth-client-ui/src/main/resources/application.yml
new file mode 100644
index 00000000..8f7511a3
--- /dev/null
+++ b/eth-client-ui/src/main/resources/application.yml
@@ -0,0 +1,36 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+spring:
+ main:
+ banner-mode: "off"
+
+banner: >
+ Apache Tuweni Client UI.
+
+ `:oyhdhhhhhhyo-`
+ :yds/. ./sdy:
+ :mh: :hm:
+ `ym: :my`
+ hm` `mh
+ +N. .N+
+ my :ydh/ /hdy- ym
+ Mo`MMMMM` .MMMMN oM
+ my /hdh/ +hdh: ym
+ +N. .N+
+ hm` `m: `mh
+ `ym: `sssssssssN: :my`
+ :dh: `````````` :hd:
+ :yds/. ./sdy:
+ `-oyhdhhhhdhyo-`
\ No newline at end of file
diff --git a/eth-client-ui/src/main/resources/webapp/config.html
b/eth-client-ui/src/main/resources/templates/config.html
similarity index 100%
rename from eth-client-ui/src/main/resources/webapp/config.html
rename to eth-client-ui/src/main/resources/templates/config.html
diff --git a/eth-client-ui/src/main/resources/webapp/config.js
b/eth-client-ui/src/main/resources/templates/config.js
similarity index 100%
rename from eth-client-ui/src/main/resources/webapp/config.js
rename to eth-client-ui/src/main/resources/templates/config.js
diff --git a/eth-client-ui/src/main/resources/webapp/favicon.ico
b/eth-client-ui/src/main/resources/templates/favicon.ico
similarity index 100%
rename from eth-client-ui/src/main/resources/webapp/favicon.ico
rename to eth-client-ui/src/main/resources/templates/favicon.ico
diff --git a/eth-client-ui/src/main/resources/webapp/img/tuweni.svg
b/eth-client-ui/src/main/resources/templates/img/tuweni.svg
similarity index 100%
rename from eth-client-ui/src/main/resources/webapp/img/tuweni.svg
rename to eth-client-ui/src/main/resources/templates/img/tuweni.svg
diff --git a/eth-client-ui/src/main/resources/webapp/index.html
b/eth-client-ui/src/main/resources/templates/index.html
similarity index 93%
rename from eth-client-ui/src/main/resources/webapp/index.html
rename to eth-client-ui/src/main/resources/templates/index.html
index 3033e372..20da2209 100644
--- a/eth-client-ui/src/main/resources/webapp/index.html
+++ b/eth-client-ui/src/main/resources/templates/index.html
@@ -21,9 +21,7 @@ specific language governing permissions and limitations under
the License.
href="/favicon.ico">
<!-- Bootstrap CSS -->
- <link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
-
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
crossorigin="anonymous">
-
+ <link rel="stylesheet"
th:href="@{/webjars/bootstrap/css/bootstrap.min.css} "/>
<title>Apache Tuweni Console</title>
</head>
<body>
@@ -116,9 +114,7 @@ specific language governing permissions and limitations
under the License.
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"></script>
-<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"
-
integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI"
- crossorigin="anonymous"></script>
+<link rel="stylesheet" th:href="@{/webjars/bootstrap/js/bootstrap.min.js} "/>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
</body>
diff --git a/eth-client-ui/src/main/resources/webapp/state.html
b/eth-client-ui/src/main/resources/templates/state.html
similarity index 100%
rename from eth-client-ui/src/main/resources/webapp/state.html
rename to eth-client-ui/src/main/resources/templates/state.html
diff --git a/eth-client-ui/src/main/resources/webapp/state.js
b/eth-client-ui/src/main/resources/templates/state.js
similarity index 100%
rename from eth-client-ui/src/main/resources/webapp/state.js
rename to eth-client-ui/src/main/resources/templates/state.js
diff --git a/eth-faucet/build.gradle b/eth-faucet/build.gradle
index 9915915a..443c0545 100644
--- a/eth-faucet/build.gradle
+++ b/eth-faucet/build.gradle
@@ -33,7 +33,6 @@ dependencies {
implementation 'io.vertx:vertx-lang-kotlin'
implementation 'io.vertx:vertx-lang-kotlin-coroutines'
implementation 'org.bouncycastle:bcprov-jdk15on'
- implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core'
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
@@ -41,6 +40,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-web")
+ implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation 'org.webjars:bootstrap'
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]