diff --git a/src/main/kotlin/mdnet/base/Main.kt b/src/main/kotlin/mdnet/base/Main.kt
index 5d9584a..229730b 100644
--- a/src/main/kotlin/mdnet/base/Main.kt
+++ b/src/main/kotlin/mdnet/base/Main.kt
@@ -56,7 +56,10 @@ object Main {
}
val client = MangaDexClient(file)
- Runtime.getRuntime().addShutdownHook(Thread { client.shutdown() })
+ Runtime.getRuntime().addShutdownHook(Thread {
+ client.shutdown()
+ (LoggerFactory.getILoggerFactory() as LoggerContext).stop()
+ })
client.runLoop()
}
diff --git a/src/main/kotlin/mdnet/base/MangaDexClient.kt b/src/main/kotlin/mdnet/base/MangaDexClient.kt
index 2e806b8..577630d 100644
--- a/src/main/kotlin/mdnet/base/MangaDexClient.kt
+++ b/src/main/kotlin/mdnet/base/MangaDexClient.kt
@@ -19,7 +19,7 @@ along with this MangaDex@Home. If not, see .
/* ktlint-disable no-wildcard-imports */
package mdnet.base
-import ch.qos.logback.classic.LoggerContext
+import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException
@@ -27,349 +27,106 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import java.io.File
import java.io.FileReader
-import java.io.FileWriter
import java.io.IOException
-import java.time.Instant
-import java.util.*
-import java.util.concurrent.CountDownLatch
+import java.lang.AssertionError
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
-import java.util.concurrent.atomic.AtomicBoolean
-import java.util.concurrent.atomic.AtomicReference
import java.util.regex.Pattern
import mdnet.base.Main.dieWithError
-import mdnet.base.data.Statistics
-import mdnet.base.server.getServer
import mdnet.base.server.getUiServer
-import mdnet.base.settings.ClientSettings
-import mdnet.base.settings.ServerSettings
+import mdnet.base.settings.*
import mdnet.cache.DiskLruCache
import mdnet.cache.HeaderMismatchException
import org.http4k.server.Http4kServer
import org.slf4j.LoggerFactory
-private const val CLIENT_KEY_LENGTH = 52
-
// Exception class to handle when Client Settings have invalid values
class ClientSettingsException(message: String) : Exception(message)
-sealed class State
-// server is not running
-data class Uninitialized(val clientSettings: ClientSettings) : State()
-// server has shut down
-object Shutdown : State()
-// server is in the process of shutting down
-data class GracefulShutdown(val lastRunning: Running, val counts: Int = 0, val nextState: State = Uninitialized(lastRunning.clientSettings), val action: () -> Unit = {}) : State()
-// server is currently running
-data class Running(val server: Http4kServer, val settings: ServerSettings, val clientSettings: ClientSettings) : State()
-
class MangaDexClient(private val clientSettingsFile: String) {
- // this must remain singlethreaded because of how the state mechanism works
- private val executorService = Executors.newSingleThreadScheduledExecutor()
- // state must only be accessed from the thread on the executorService
- private var state: State
-
- private var serverHandler: ServerHandler
- private val statsMap: MutableMap = Collections
- .synchronizedMap(object : LinkedHashMap(240) {
- override fun removeEldestEntry(eldest: Map.Entry): Boolean {
- return this.size > 240
- }
- })
- private val statistics: AtomicReference = AtomicReference(
- Statistics()
- )
- private val isHandled: AtomicBoolean = AtomicBoolean(false)
- private var webUi: Http4kServer? = null
+ // just for scheduling one task, so single-threaded
+ private val executor = Executors.newSingleThreadScheduledExecutor()
private val cache: DiskLruCache
+ private var settings: ClientSettings
+
+ private var imageServer: ServerManager? = null
+ private var webUi: Http4kServer? = null
init {
- // Read ClientSettings
- val clientSettings = try {
+ settings = try {
readClientSettings()
} catch (e: UnrecognizedPropertyException) {
dieWithError("'${e.propertyName}' is not a valid setting")
} catch (e: JsonProcessingException) {
dieWithError(e)
- } catch (ignored: IOException) {
- ClientSettings().also {
- LOGGER.warn { "Settings file $clientSettingsFile not found, generating file" }
- try {
- FileWriter(clientSettingsFile).use { writer -> JACKSON.writeValue(writer, it) }
- } catch (e: IOException) {
- dieWithError(e)
- }
- }
} catch (e: ClientSettingsException) {
dieWithError(e)
+ } catch (e: IOException) {
+ dieWithError(e)
}
- // Initialize things that depend on Client Settings
- LOGGER.info { "Client settings loaded: $clientSettings" }
- state = Uninitialized(clientSettings)
- serverHandler = ServerHandler(clientSettings)
-
- // Initialize everything else
try {
cache = DiskLruCache.open(
File("cache"), 1, 1,
- (clientSettings.maxCacheSizeInMebibytes * 1024 * 1024 * 0.8).toLong() /* MiB to bytes */
+ (settings.maxCacheSizeInMebibytes * 1024 * 1024 * 0.8).toLong() /* MiB to bytes */
)
- cache.get("statistics")?.use {
- try {
- statistics.set(JACKSON.readValue(it.getInputStream(0)))
- } catch (_: JsonProcessingException) {
- cache.remove("statistics")
- }
- }
} catch (e: HeaderMismatchException) {
LOGGER.warn { "Cache version may be outdated - remove if necessary" }
dieWithError(e)
} catch (e: IOException) {
- LOGGER.warn { "Cache may be corrupt - remove if necessary" }
dieWithError(e)
}
}
fun runLoop() {
- loginAndStartServer()
- statsMap[Instant.now()] = statistics.get()
- startWebUi()
- LOGGER.info { "Mangadex@Home Client initialized. Starting normal operation." }
+ LOGGER.info { "Mangadex@Home Client initialized - starting normal operation." }
- executorService.scheduleAtFixedRate({
+ executor.scheduleWithFixedDelay({
try {
- if (state is Running || state is GracefulShutdown || state is Uninitialized) {
- statistics.updateAndGet {
- it.copy(bytesOnDisk = cache.size())
- }
- statsMap[Instant.now()] = statistics.get()
- val editor = cache.edit("statistics")
- if (editor != null) {
- JACKSON.writeValue(editor.newOutputStream(0), statistics.get())
- editor.commit()
- }
- }
- } catch (e: Exception) {
- LOGGER.warn(e) { "Statistics update failed" }
- }
- }, 15, 15, TimeUnit.SECONDS)
-
- var lastBytesSent = statistics.get().bytesSent
- executorService.scheduleAtFixedRate({
- try {
- lastBytesSent = statistics.get().bytesSent
-
- val state = this.state
- if (state is GracefulShutdown) {
- LOGGER.info { "Aborting graceful shutdown started due to hourly bandwidth limit" }
-
- this.state = state.lastRunning
- }
- if (state is Uninitialized) {
- LOGGER.info { "Restarting server stopped due to hourly bandwidth limit" }
-
- loginAndStartServer()
- }
- } catch (e: Exception) {
- LOGGER.warn(e) { "Hourly bandwidth check failed" }
- }
- }, 1, 1, TimeUnit.HOURS)
-
- executorService.scheduleAtFixedRate({
- try {
- val state = this.state
- if (state is GracefulShutdown) {
- val timesToWait = state.lastRunning.clientSettings.gracefulShutdownWaitSeconds / 15
- when {
- state.counts == 0 -> {
- LOGGER.info { "Starting graceful shutdown" }
-
- logout()
- isHandled.set(false)
- this.state = state.copy(counts = state.counts + 1)
- }
- state.counts == timesToWait || !isHandled.get() -> {
- if (!isHandled.get()) {
- LOGGER.info { "No requests received, shutting down" }
- } else {
- LOGGER.info { "Max tries attempted (${state.counts} out of $timesToWait), shutting down" }
- }
-
- stopServer(state.nextState)
- state.action()
- }
- else -> {
- LOGGER.info {
- "Waiting another 15 seconds for graceful shutdown (${state.counts} out of $timesToWait)"
- }
-
- isHandled.set(false)
- this.state = state.copy(counts = state.counts + 1)
- }
- }
- }
- } catch (e: Exception) {
- LOGGER.warn(e) { "Main loop failed" }
- }
- }, 15, 15, TimeUnit.SECONDS)
-
- executorService.scheduleWithFixedDelay({
- try {
- val state = this.state
- if (state is Running) {
- val currentBytesSent = statistics.get().bytesSent - lastBytesSent
- if (state.clientSettings.maxMebibytesPerHour != 0L && state.clientSettings.maxMebibytesPerHour * 1024 * 1024 /* MiB to bytes */ < currentBytesSent) {
- LOGGER.info { "Shutting down server as hourly bandwidth limit reached" }
-
- this.state = GracefulShutdown(lastRunning = state)
- } else {
- pingControl()
- }
- }
- } catch (e: Exception) {
- LOGGER.warn(e) { "Graceful shutdown checker failed" }
- }
- }, 45, 45, TimeUnit.SECONDS)
-
- // Check every minute to see if client settings have changed
- executorService.scheduleWithFixedDelay({
- try {
- val state = this.state
- if (state is Running) {
- reloadClientSettings()
- }
+ reloadClientSettings()
} catch (e: Exception) {
LOGGER.warn(e) { "Reload of ClientSettings failed" }
}
- }, 60, 60, TimeUnit.SECONDS)
+ }, 1, 1, TimeUnit.MINUTES)
}
- private fun pingControl() {
- val state = this.state as Running
-
- val newSettings = serverHandler.pingControl(state.settings)
- if (newSettings != null) {
- LOGGER.info { "Server settings received: $newSettings" }
-
- if (newSettings.latestBuild > Constants.CLIENT_BUILD) {
- LOGGER.warn {
- "Outdated build detected! Latest: ${newSettings.latestBuild}, Current: ${Constants.CLIENT_BUILD}"
- }
- }
- if (newSettings.tls != null || newSettings.imageServer != state.settings.imageServer) {
- // certificates or upstream url must have changed, restart webserver
- LOGGER.info { "Doing internal restart of HTTP server to refresh certs/upstream URL" }
-
- this.state = GracefulShutdown(lastRunning = state) {
- loginAndStartServer()
- }
- }
- } else {
- LOGGER.info { "Server ping failed - ignoring" }
- }
- }
-
- private fun loginAndStartServer() {
- val state = this.state as Uninitialized
-
- val serverSettings = serverHandler.loginToControl()
- ?: dieWithError("Failed to get a login response from server - check API secret for validity")
- val server = getServer(cache, serverSettings, state.clientSettings, statistics, isHandled).start()
-
- if (serverSettings.latestBuild > Constants.CLIENT_BUILD) {
- LOGGER.warn {
- "Outdated build detected! Latest: ${serverSettings.latestBuild}, Current: ${Constants.CLIENT_BUILD}"
- }
- }
-
- this.state = Running(server, serverSettings, state.clientSettings)
- LOGGER.info { "Internal HTTP server was successfully started" }
- }
-
- private fun logout() {
- serverHandler.logoutFromControl()
- }
-
- private fun stopServer(nextState: State) {
- val state = this.state.let {
- when (it) {
- is Running ->
- it
- is GracefulShutdown ->
- it.lastRunning
- else ->
- throw AssertionError()
- }
- }
-
- LOGGER.info { "Shutting down HTTP server" }
- state.server.stop()
- LOGGER.info { "Internal HTTP server has shut down" }
-
- this.state = nextState
- }
-
- /**
- * Starts the WebUI if the ClientSettings demand it.
- * This method checks if the WebUI is needed,
- */
+ // Precondition: settings must be filled with up-to-date settings and `imageServer` must not be null
private fun startWebUi() {
- val state = this.state
- // Grab the client settings if available
- val clientSettings = state.let {
- when (it) {
- is Running ->
- it.clientSettings
- is Uninitialized ->
- it.clientSettings
- else ->
- null
- }
- }
+ settings.webSettings?.let { webSettings ->
+ val imageServer = requireNotNull(imageServer)
- // Only start the Web UI if the settings demand it
- if (clientSettings?.webSettings != null) {
- webUi = getUiServer(clientSettings.webSettings, statistics, statsMap)
- webUi!!.start()
+ if (webUi != null) throw AssertionError()
+ webUi = getUiServer(webSettings, imageServer.statistics, imageServer.statsMap).also {
+ it.start()
+ }
+ LOGGER.info { "WebUI was successfully started" }
}
}
- /**
- * Shutdowns the MangaDexClient
- */
- fun shutdown() {
- LOGGER.info { "Mangadex@Home Client stopping" }
-
- val latch = CountDownLatch(1)
- executorService.schedule({
- val state = this.state
- if (state is Running) {
- this.state = GracefulShutdown(state, nextState = Shutdown) {
- latch.countDown()
- }
- } else if (state is GracefulShutdown) {
- this.state = state.copy(nextState = Shutdown) {
- latch.countDown()
- }
- } else if (state is Uninitialized || state is Shutdown) {
- this.state = Shutdown
- latch.countDown()
- }
- }, 0, TimeUnit.SECONDS)
- latch.await()
-
- webUi?.close()
- try {
- cache.close()
- } catch (e: IOException) {
- LOGGER.error(e) { "Cache failed to close" }
+ // Precondition: settings must be filled with up-to-date settings
+ private fun startImageServer() {
+ if (imageServer != null) throw AssertionError()
+ imageServer = ServerManager(settings.serverSettings, settings.devSettings, settings.maxCacheSizeInMebibytes, cache).also {
+ it.start()
}
+ LOGGER.info { "Server manager was successfully started" }
+ }
- executorService.shutdown()
- LOGGER.info { "Mangadex@Home Client stopped" }
+ private fun stopImageServer() {
+ requireNotNull(imageServer).shutdown()
+ LOGGER.info { "Server manager was successfully stopped" }
+ }
- (LoggerFactory.getILoggerFactory() as LoggerContext).stop()
+ private fun stopWebUi() {
+ requireNotNull(webUi).stop()
+ LOGGER.info { "Server manager was successfully stopped" }
+ }
+
+ fun shutdown() {
+ LOGGER.info { "Mangadex@Home Client shutting down" }
+ stopWebUi()
+ stopImageServer()
+ LOGGER.info { "Mangadex@Home Client has shut down" }
}
/**
@@ -377,102 +134,81 @@ class MangaDexClient(private val clientSettingsFile: String) {
* Web UI and/or the server if needed
*/
private fun reloadClientSettings() {
- val state = this.state as Running
- LOGGER.info { "Reloading client settings" }
+ LOGGER.info { "Checking client settings" }
try {
val newSettings = readClientSettings()
- if (newSettings == state.clientSettings) {
- LOGGER.info { "Client Settings have not changed" }
+ if (newSettings == settings) {
+ LOGGER.info { "Client settings unchanged" }
return
}
cache.maxSize = (newSettings.maxCacheSizeInMebibytes * 1024 * 1024 * 0.8).toLong()
- // Setting loaded without issue. Figure out
- // if there are changes that require a restart
- val restartServer = newSettings.clientSecret != state.clientSettings.clientSecret ||
- newSettings.clientHostname != state.clientSettings.clientHostname ||
- newSettings.clientPort != state.clientSettings.clientPort ||
- newSettings.clientExternalPort != state.clientSettings.clientExternalPort ||
- newSettings.threads != state.clientSettings.threads ||
- newSettings.devSettings?.isDev != state.clientSettings.devSettings?.isDev
- val stopWebUi = newSettings.webSettings != state.clientSettings.webSettings ||
- newSettings.webSettings?.uiPort != state.clientSettings.webSettings?.uiPort ||
- newSettings.webSettings?.uiHostname != state.clientSettings.webSettings?.uiHostname
- val startWebUi = (stopWebUi && newSettings.webSettings != null)
+ val restartServer = newSettings.serverSettings != settings.serverSettings ||
+ newSettings.devSettings != settings.devSettings
+
+ val stopWebUi = restartServer || newSettings.webSettings != settings.webSettings
+ val startWebUi = stopWebUi && newSettings.webSettings != null
- // Stop the the WebUI if needed
if (stopWebUi) {
LOGGER.info { "Stopping WebUI to reload ClientSettings" }
- webUi?.close()
- webUi = null
+ stopWebUi()
}
if (restartServer) {
- // If we are restarting the server
- // We must do it gracefully and set
- // the new settings later
- LOGGER.info { "Stopping Server to reload ClientSettings" }
-
- this.state = GracefulShutdown(state, nextState = Uninitialized(clientSettings = newSettings), action = {
- serverHandler = ServerHandler(newSettings)
- LOGGER.info { "Reloaded ClientSettings: $newSettings" }
-
- LOGGER.info { "Starting Server after reloading ClientSettings" }
- loginAndStartServer()
- })
- } else {
- // If we aren't restarting the server
- // We can update the settings now
- this.state = state.copy(clientSettings = newSettings)
- serverHandler.settings = newSettings
- LOGGER.info { "Reloaded ClientSettings: $newSettings" }
+ stopImageServer()
+ startImageServer()
}
- // Start the WebUI if we had to stop it
- // and still want it
if (startWebUi) {
- LOGGER.info { "Starting WebUI after reloading ClientSettings" }
startWebUi()
- LOGGER.info { "Started WebUI after reloading ClientSettings" }
}
} catch (e: UnrecognizedPropertyException) {
LOGGER.warn { "Settings file is invalid: '$e.propertyName' is not a valid setting" }
} catch (e: JsonProcessingException) {
LOGGER.warn { "Settings file is invalid: $e.message" }
- } catch (e: IOException) {
- LOGGER.warn { "Settings file is could not be found: $e.message" }
} catch (e: ClientSettingsException) {
- LOGGER.warn { "Can't reload client settings: $e.message" }
+ LOGGER.warn { "Settings file is invalid: $e.message" }
+ } catch (e: IOException) {
+ LOGGER.warn { "Error loading settings file: $e.message" }
}
}
private fun validateSettings(settings: ClientSettings) {
- if (!isSecretValid(settings.clientSecret)) throw ClientSettingsException("Config Error: API Secret is invalid, must be 52 alphanumeric characters")
- if (settings.clientPort == 0) {
- throw ClientSettingsException("Config Error: Invalid port number")
- }
- if (settings.clientPort in Constants.RESTRICTED_PORTS) {
- throw ClientSettingsException("Config Error: Unsafe port number")
- }
if (settings.maxCacheSizeInMebibytes < 1024) {
throw ClientSettingsException("Config Error: Invalid max cache size, must be >= 1024 MiB (1GiB)")
}
- if (settings.threads < 4) {
- throw ClientSettingsException("Config Error: Invalid number of threads, must be >= 4")
+
+ fun isSecretValid(clientSecret: String): Boolean {
+ return Pattern.matches("^[a-zA-Z0-9]{$CLIENT_KEY_LENGTH}$", clientSecret)
}
- if (settings.maxMebibytesPerHour < 0) {
- throw ClientSettingsException("Config Error: Max bandwidth must be >= 0")
+
+ settings.serverSettings.let {
+ if (!isSecretValid(it.clientSecret)) {
+ throw ClientSettingsException("Config Error: API Secret is invalid, must be 52 alphanumeric characters")
+ }
+ if (it.clientPort == 0) {
+ throw ClientSettingsException("Config Error: Invalid port number")
+ }
+ if (it.clientPort in Constants.RESTRICTED_PORTS) {
+ throw ClientSettingsException("Config Error: Unsafe port number")
+ }
+ if (it.threads < 4) {
+ throw ClientSettingsException("Config Error: Invalid number of threads, must be >= 4")
+ }
+ if (it.maxMebibytesPerHour < 0) {
+ throw ClientSettingsException("Config Error: Max bandwidth must be >= 0")
+ }
+ if (it.maxKilobitsPerSecond < 0) {
+ throw ClientSettingsException("Config Error: Max burst rate must be >= 0")
+ }
+ if (it.gracefulShutdownWaitSeconds < 15) {
+ throw ClientSettingsException("Config Error: Graceful shutdown wait must be >= 15")
+ }
}
- if (settings.maxKilobitsPerSecond < 0) {
- throw ClientSettingsException("Config Error: Max burst rate must be >= 0")
- }
- if (settings.gracefulShutdownWaitSeconds < 15) {
- throw ClientSettingsException("Config Error: Graceful shutdown wait must be >= 15")
- }
- if (settings.webSettings != null) {
- if (settings.webSettings.uiPort == 0) {
+ settings.webSettings?.let {
+ if (it.uiPort == 0) {
throw ClientSettingsException("Config Error: Invalid UI port number")
}
}
@@ -482,12 +218,9 @@ class MangaDexClient(private val clientSettingsFile: String) {
return JACKSON.readValue(FileReader(clientSettingsFile)).apply(::validateSettings)
}
- private fun isSecretValid(clientSecret: String): Boolean {
- return Pattern.matches("^[a-zA-Z0-9]*$CLIENT_KEY_LENGTH}$", clientSecret)
- }
-
companion object {
+ private const val CLIENT_KEY_LENGTH = 52
private val LOGGER = LoggerFactory.getLogger(MangaDexClient::class.java)
- private val JACKSON: ObjectMapper = jacksonObjectMapper()
+ private val JACKSON: ObjectMapper = jacksonObjectMapper().configure(JsonParser.Feature.ALLOW_COMMENTS, true)
}
}
diff --git a/src/main/kotlin/mdnet/base/ServerHandler.kt b/src/main/kotlin/mdnet/base/ServerHandler.kt
index 4c74105..acca135 100644
--- a/src/main/kotlin/mdnet/base/ServerHandler.kt
+++ b/src/main/kotlin/mdnet/base/ServerHandler.kt
@@ -22,7 +22,8 @@ import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.module.kotlin.KotlinModule
import java.net.InetAddress
import mdnet.base.ServerHandlerJackson.auto
-import mdnet.base.settings.ClientSettings
+import mdnet.base.settings.DevSettings
+import mdnet.base.settings.RemoteSettings
import mdnet.base.settings.ServerSettings
import org.apache.http.client.config.RequestConfig
import org.apache.http.impl.client.HttpClients
@@ -43,13 +44,13 @@ object ServerHandlerJackson : ConfigurableJackson(
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
)
-class ServerHandler(var settings: ClientSettings) {
+class ServerHandler(private val serverSettings: ServerSettings, private val devSettings: DevSettings, private val maxCacheSizeInMebibytes: Long) {
private val client = ApacheClient(client = HttpClients.custom()
.setDefaultRequestConfig(
RequestConfig.custom()
.apply {
- if (settings.clientHostname != "0.0.0.0") {
- setLocalAddress(InetAddress.getByName(settings.clientHostname))
+ if (serverSettings.clientHostname != "0.0.0.0") {
+ setLocalAddress(InetAddress.getByName(serverSettings.clientHostname))
}
}
.build())
@@ -58,7 +59,7 @@ class ServerHandler(var settings: ClientSettings) {
fun logoutFromControl(): Boolean {
LOGGER.info { "Disconnecting from the control server" }
val params = mapOf(
- "secret" to settings.clientSecret
+ "secret" to serverSettings.clientSecret
)
val request = STRING_ANY_MAP_LENS(params, Request(Method.POST, getServerAddress() + "stop"))
@@ -69,16 +70,16 @@ class ServerHandler(var settings: ClientSettings) {
private fun getPingParams(tlsCreatedAt: String? = null): Map =
mapOf(
- "secret" to settings.clientSecret,
+ "secret" to serverSettings.clientSecret,
"port" to let {
- if (settings.clientExternalPort != 0) {
- settings.clientExternalPort
+ if (serverSettings.clientExternalPort != 0) {
+ serverSettings.clientExternalPort
} else {
- settings.clientPort
+ serverSettings.clientPort
}
},
- "disk_space" to settings.maxCacheSizeInMebibytes * 1024 * 1024,
- "network_speed" to settings.maxKilobitsPerSecond * 1000 / 8,
+ "disk_space" to maxCacheSizeInMebibytes * 1024 * 1024,
+ "network_speed" to serverSettings.maxKilobitsPerSecond * 1000 / 8,
"build_version" to Constants.CLIENT_BUILD
).let {
if (tlsCreatedAt != null) {
@@ -88,7 +89,7 @@ class ServerHandler(var settings: ClientSettings) {
}
}
- fun loginToControl(): ServerSettings? {
+ fun loginToControl(): RemoteSettings? {
LOGGER.info { "Connecting to the control server" }
val request = STRING_ANY_MAP_LENS(getPingParams(), Request(Method.POST, getServerAddress() + "ping"))
@@ -101,7 +102,7 @@ class ServerHandler(var settings: ClientSettings) {
}
}
- fun pingControl(old: ServerSettings): ServerSettings? {
+ fun pingControl(old: RemoteSettings): RemoteSettings? {
LOGGER.info { "Pinging the control server" }
val request = STRING_ANY_MAP_LENS(getPingParams(old.tls!!.createdAt), Request(Method.POST, getServerAddress() + "ping"))
@@ -115,7 +116,7 @@ class ServerHandler(var settings: ClientSettings) {
}
private fun getServerAddress(): String {
- return if (settings.devSettings?.isDev != true)
+ return if (!devSettings.isDev)
SERVER_ADDRESS
else
SERVER_ADDRESS_DEV
@@ -124,7 +125,7 @@ class ServerHandler(var settings: ClientSettings) {
companion object {
private val LOGGER = LoggerFactory.getLogger(ServerHandler::class.java)
private val STRING_ANY_MAP_LENS = Body.auto