Skip to content

Commit

Permalink
fix: Docker manager and settings
Browse files Browse the repository at this point in the history
  • Loading branch information
utfunderscore committed Aug 20, 2024
1 parent 2961d48 commit f802bd0
Show file tree
Hide file tree
Showing 15 changed files with 198 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package org.readutf.orchestrator.wrapper

import kotlinx.coroutines.runBlocking
import org.jetbrains.annotations.Blocking
import org.readutf.orchestrator.wrapper.services.DockerService
import org.readutf.orchestrator.wrapper.services.ServerService
import retrofit2.Retrofit
import retrofit2.converter.fastjson.FastJsonConverterFactory

Expand All @@ -17,9 +21,17 @@ class OrchestratorApi(
.build()

val serverService by lazy { retrofit.create(ServerService::class.java) }
val dockerService by lazy { retrofit.create(DockerService::class.java) }

@Blocking
fun requestGame(
gameType: String,
timeout: Long = 5000,
) = requestClient.requestGame(gameType, timeout)

@Blocking
fun getPort(shortId: String) =
runBlocking {
dockerService.getPort(shortId)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.readutf.orchestrator.wrapper.services

import org.readutf.orchestrator.shared.utils.ApiResponse
import org.readutf.orchestrator.wrapper.types.ContainerPort
import retrofit2.http.GET
import retrofit2.http.Query

interface DockerService {
@GET("/docker/port")
suspend fun getPort(
@Query("shortId") shortId: String,
): ApiResponse<List<ContainerPort>>
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.readutf.orchestrator.wrapper
package org.readutf.orchestrator.wrapper.services

import org.readutf.orchestrator.shared.server.Server
import org.readutf.orchestrator.shared.utils.ApiResponse
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.readutf.orchestrator.wrapper.types

data class ContainerPort(
val ip: String,
val privatePort: Int,
val publicPort: Int,
val type: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test
* The server needs to be running before
* game request tests are executed
*/
class GameRequestTest {
class ApiTests {
val orchestratorApi = OrchestratorApi("localhost", 9393)

@Test
Expand Down
36 changes: 30 additions & 6 deletions Client/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
plugins {
id("java-library")
kotlin("jvm") version "2.0.0"
id("maven-publish")
}

group = "org.readutf.orchestrator"
Expand All @@ -13,24 +15,46 @@ dependencies {
testImplementation(kotlin("test"))

val hermesVersion: String by rootProject.extra
implementation("org.readutf.hermes:core:$hermesVersion")
implementation("org.readutf.hermes:netty:$hermesVersion")
implementation("org.readutf.hermes:kryo:$hermesVersion")
api("org.readutf.hermes:core:$hermesVersion")
api("org.readutf.hermes:netty:$hermesVersion")
api("org.readutf.hermes:kryo:$hermesVersion")

val nettyVersion: String by rootProject.extra
implementation("io.netty:netty-all:$nettyVersion")
api("io.netty:netty-all:$nettyVersion")

// Logging
val log4jVersion: String by rootProject.extra
implementation("org.apache.logging.log4j:log4j-api:$log4jVersion")
implementation("org.apache.logging.log4j:log4j-slf4j2-impl:$log4jVersion")

// FastJSON2
implementation("com.alibaba:fastjson:+")
api("com.alibaba:fastjson:2.0.52")

implementation(project(":Shared"))
api(project(":Shared"))
}

publishing {
repositories {
maven {
name = "utfunderscore"
url = uri("https://reposilite.readutf.org/releases")
credentials(PasswordCredentials::class)
authentication {
create<BasicAuthentication>("basic")
}
}
}

publications {
create<MavenPublication>("maven") {
groupId = "org.readutf.orchestrator"
artifactId = "client"
version = rootProject.version.toString()

from(components["java"])
}
}
}
tasks.test {
useJUnitPlatform()
}
Expand Down
4 changes: 4 additions & 0 deletions Server/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ dependencies {
implementation("org.jetbrains.exposed:exposed-jdbc:$exposed")
implementation("org.jetbrains.exposed:exposed-java-time:$exposed")

// Docker
implementation("com.github.docker-java:docker-java-core:3.4.0")
implementation("com.github.docker-java:docker-java-transport-zerodep:3.4.0")

// Hoplite
implementation("com.sksamuel.hoplite:hoplite-core:2.8.0.RC3")
runtimeOnly("com.sksamuel.hoplite:hoplite-yaml:2.8.0.RC3")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class Orchestrator(
val gameManager = GameManager(InMemoryGameStore(serverStore))
val endpointManager =
EndpointManager(
apiSettings = settings.apiSettings,
settings = settings.apiSettings,
serverManager = serverManager,
gameManager = gameManager,
)
Expand All @@ -49,7 +49,6 @@ class Orchestrator(
}, "Command Thread").start()

// shutdown hook

Runtime.getRuntime().addShutdownHook(
Thread {
logger.info { "Shutting down Orchestrator" }
Expand All @@ -65,8 +64,8 @@ class Orchestrator(
): PacketManager<*> =
PacketManager
.nettyServer(
hostName = settings.serversettings.host,
port = settings.serversettings.port,
hostName = settings.serverSettings.host,
port = settings.serverSettings.port,
serializer = KryoPacketSerializer(kryo),
).editListeners { listeners ->
listeners.registerListener(ChannelCloseListener(serverManager))
Expand Down
31 changes: 29 additions & 2 deletions Server/src/main/kotlin/org/readutf/orchestrator/server/Test.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
package org.readutf.orchestrator.server

class Test {
}
import org.readutf.orchestrator.server.settings.ApiSettings
import org.readutf.orchestrator.server.settings.DockerSettings
import org.readutf.orchestrator.server.settings.ServerSettings
import org.readutf.orchestrator.server.settings.Settings
import java.net.URI

fun main() {
val settings =
Settings(
apiSettings =
ApiSettings(
host = "localhost",
port = 9393,
virtualThreads = true,
),
dockerSettings =
DockerSettings(
uri = URI("http://localhost:2375"),
maxConnections = 100,
responseTimeout = java.time.Duration.ofSeconds(10),
connectionTimeout = java.time.Duration.ofSeconds(10),
),
serverSettings =
ServerSettings(
"localhost",
port = 2980,
),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ package org.readutf.orchestrator.server.api

import io.javalin.Javalin
import io.javalin.community.routing.annotations.AnnotatedRouting.Annotated
import org.readutf.orchestrator.server.api.endpoint.DockerEndpoint
import org.readutf.orchestrator.server.api.endpoint.GameRequestSocket
import org.readutf.orchestrator.server.api.endpoint.ServerEndpoint
import org.readutf.orchestrator.server.docker.DockerManager
import org.readutf.orchestrator.server.game.GameManager
import org.readutf.orchestrator.server.server.ServerManager
import org.readutf.orchestrator.server.settings.ApiSettings
import org.readutf.orchestrator.server.settings.Settings
import org.readutf.orchestrator.server.utils.FastJsonMapper

class EndpointManager(
val apiSettings: ApiSettings,
val settings: Settings,
val serverManager: ServerManager,
val gameManager: GameManager,
) {
Expand All @@ -19,7 +21,6 @@ class EndpointManager(
// private val logger = KotlinLogging.logger { }

init {

javalin.ws(
"/game/request",
GameRequestSocket(
Expand All @@ -35,16 +36,17 @@ class EndpointManager(

private fun setupJavalin() =
Javalin.createAndStart { config ->
config.jetty.defaultHost = apiSettings.host
config.jetty.defaultPort = apiSettings.port
config.jetty.defaultHost = settings.apiSettings.host
config.jetty.defaultPort = settings.apiSettings.port
config.jsonMapper(FastJsonMapper)
config.useVirtualThreads = apiSettings.virtualThreads
config.useVirtualThreads = settings.apiSettings.virtualThreads
config.showJavalinBanner = false
config.bundledPlugins.enableDevLogging()

// register endpoints
config.router.mount(Annotated) { routing ->
routing.registerEndpoints(ServerEndpoint(serverManager))
routing.registerEndpoints(DockerEndpoint(DockerManager(settings.dockerSettings)))
}

config.pvt.internalRouter.allHttpHandlers().forEach { parsedEndpoint ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.readutf.orchestrator.server.api.endpoint

import io.javalin.community.routing.annotations.Endpoints
import io.javalin.community.routing.annotations.Get
import io.javalin.http.Context
import org.readutf.orchestrator.server.docker.DockerManager
import org.readutf.orchestrator.shared.utils.ApiResponse

@Endpoints("/docker")
class DockerEndpoint(
val dockerManager: DockerManager,
) {
@Get("port")
fun getPort(
context: Context,
shortId: String,
) {
val containerByShortId = dockerManager.getContainerByShortId(shortId)

if (containerByShortId.isError()) {
context.json(ApiResponse.failure<String>(containerByShortId.getError()))
}

context.json(ApiResponse.success(containerByShortId.get().getPorts()))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.readutf.orchestrator.server.docker

import com.github.dockerjava.api.model.Container
import com.github.dockerjava.core.DefaultDockerClientConfig
import com.github.dockerjava.core.DockerClientConfig
import com.github.dockerjava.core.DockerClientImpl
import com.github.dockerjava.zerodep.ZerodepDockerHttpClient
import io.github.oshai.kotlinlogging.KotlinLogging
import org.readutf.orchestrator.server.settings.DockerSettings
import org.readutf.orchestrator.shared.utils.Result
import java.net.URI
import java.time.Duration

class DockerManager(
dockerSettings: DockerSettings,
) {
private val logger = KotlinLogging.logger { }

private var config: DockerClientConfig =
DefaultDockerClientConfig
.createDefaultConfigBuilder()
.build()

private val httpClient =
ZerodepDockerHttpClient
.Builder()
.dockerHost(URI(dockerSettings.uri))
.maxConnections(dockerSettings.maxConnections)
.connectionTimeout(Duration.ofSeconds(dockerSettings.connectionTimeout))
.responseTimeout(Duration.ofSeconds(dockerSettings.responseTimeout))
.build()

private val dockerClient = DockerClientImpl.getInstance(config, httpClient)

fun getContainerByShortId(shortId: String): Result<Container> {
val containers = dockerClient.listContainersCmd().exec()

val found = containers.filter { container -> container.id.startsWith(shortId) }

if (found.isEmpty()) {
return Result.error("Could not find container with id $shortId")
}

return Result.ok(found.first())
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package org.readutf.orchestrator.server.settings

import java.net.URI
import java.time.Duration

object Docker {
val URI = URI("tcp://localhost:2375")
val maxConnections = 100
val responseTimeout: Duration = Duration.ofSeconds(15)
val connectionTimeout: Duration = Duration.ofSeconds(15)
}
data class DockerSettings(
val uri: String,
val maxConnections: Int,
val responseTimeout: Long,
val connectionTimeout: Long,
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.readutf.orchestrator.server.settings
import com.sksamuel.hoplite.ConfigAlias

data class Settings(
@ConfigAlias("api-settings") val apiSettings: ApiSettings,
@ConfigAlias("server-settings") val serversettings: ServerSettings,
@ConfigAlias("api") val apiSettings: ApiSettings,
@ConfigAlias("server") val serverSettings: ServerSettings,
@ConfigAlias("docker") val dockerSettings: DockerSettings,
)
11 changes: 8 additions & 3 deletions Server/src/main/resources/settings.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
api-settings:
api:
host: localhost
port: 9393
virtual-threads: false
server-settings:
server:
host: localhost
port: 2980
port: 2980
docker:
uri: "tcp://localhost:2375"
maxConnections: 100
responseTimeout: 30
connectionTimeout: 30

0 comments on commit f802bd0

Please sign in to comment.