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]

Reply via email to