Skip to content
Snippets Groups Projects
Commit f2be9fb3 authored by Clément CORNU's avatar Clément CORNU
Browse files

feat: configure DB integration + koin + Readme update

parent fd246be4
No related branches found
No related tags found
No related merge requests found
# tournament-api
# Tournament API
This project was created using the [Ktor Project Generator](https://start.ktor.io).
## Initalisation
Here are some useful links to get you started:
### Pre-requisites
- [Ktor Documentation](https://ktor.io/docs/home.html)
- [Ktor GitHub page](https://github.com/ktorio/ktor)
- The [Ktor Slack chat](https://app.slack.com/client/T09229ZC6/C0A974TJ9). You'll need
to [request an invite](https://surveys.jetbrains.com/s3/kotlin-slack-sign-up) to join.
You need to have Docker and AWS CLI installed on your machine
## Features
### How to start the database
Here's a list of features included in this project:
In `docker/db` folder, run the following command:
| Name | Description |
| --------------------------------------------------------------------|------------------------------------------------------------------------------------ |
| [Routing](https://start.ktor.io/p/routing) | Provides a structured routing DSL |
| [Authentication](https://start.ktor.io/p/auth) | Provides extension point for handling the Authorization header |
| [OpenAPI](https://start.ktor.io/p/openapi) | Serves OpenAPI documentation |
| [Koin](https://start.ktor.io/p/koin) | Provides dependency injection |
| [Content Negotiation](https://start.ktor.io/p/content-negotiation) | Provides automatic content conversion according to Content-Type and Accept headers |
| [Jackson](https://start.ktor.io/p/ktor-jackson) | Handles JSON serialization using Jackson library |
```bash
docker compose up -d
```
## Building & Running
### How to start the API
To build or run the project, use one of the following tasks:
Place yourself at root and start
| Task | Description |
| -------------------------------|---------------------------------------------------------------------- |
| `./gradlew test` | Run the tests |
| `./gradlew build` | Build everything |
| `buildFatJar` | Build an executable JAR of the server with all dependencies included |
| `buildImage` | Build the docker image to use with the fat JAR |
| `publishImageToLocalRegistry` | Publish the docker image locally |
| `run` | Run the server |
| `runDocker` | Run using the local docker image |
```bash
docker compose up -d
```
If the server starts successfully, you'll see the following output:
## Available endpoints
```
2024-12-04 14:32:45.584 [main] INFO Application - Application started in 0.303 seconds.
2024-12-04 14:32:45.682 [main] INFO Application - Responding at http://0.0.0.0:8080
```
## I want to ensure tests are running
## Left to do
- [x] setup dynamo DB
- [x] faire la connexion avec Dynamo
- 1er endpoint
- [x] créer l'entité joueur
- [ ] créer le repo et le connecter à la BD
- [ ] tester unitairement le service
- [ ] tester l'intégration complète
- [ ] endpoint fonctionnel pour l'ajout d'un avec test
- [ ] tests d'inté
- [ ] tests unitaires
- [ ] tous les endpoints autres
- [ ] gestion de la sécurité
\ No newline at end of file
......@@ -3,11 +3,12 @@ val kotlin_version: String by project
val logback_version: String by project
val dynamo_version: String by project
val dynamo_kt_version: String by project
val mockk_version: String by project
plugins {
kotlin("jvm") version "2.1.10"
id("io.ktor.plugin") version "3.0.3"
id("io.ktor.plugin") version "2.3.13"
}
group = "betclic.test"
......@@ -39,5 +40,6 @@ dependencies {
implementation("software.amazon.awssdk:dynamodb:$dynamo_version")
implementation("dev.andrewohara:dynamokt:$dynamo_kt_version")
testImplementation("io.ktor:ktor-server-test-host")
testImplementation("io.mockk:mockk:$mockk_version")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
}
# Local Database
Use this docker-compose file to run a local database for development.
## Usage
### Pre-requisites
You need to have Docker and AWS CLI installed on your machine
### How to start the database
In `docker/db` folder, run the following command:
```bash
docker compose up
```
......@@ -3,5 +3,6 @@ koin_version=3.5.6
kotlin_version=2.1.10
dynamo_version=2.28.1
dynamo_kt_version=1.0.0
ktor_version=3.0.3
ktor_version=2.3.13
logback_version=1.4.14
mockk_version=1.10.0
package betclic.test
import betclic.test.player.configureRouting
import io.ktor.server.application.*
import kotlinx.coroutines.runBlocking
fun main(args: Array<String>) {
io.ktor.server.netty.EngineMain.main(args)
}
fun Application.module() {
configureSecurity()
fun Application.module() = runBlocking {
configureHTTP()
configureFrameworks()
configureKoin()
configureSerialization()
configureRouting()
}
package betclic.test
import betclic.test.player.PlayerEntity
import dev.andrewohara.dynamokt.DataClassTableSchema
import io.ktor.server.application.*
import kotlinx.coroutines.future.await
import org.slf4j.LoggerFactory
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedAsyncClient
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient
import java.net.URI
import kotlin.reflect.KClass
class DynamoDbConfiguration() {
private val logger = LoggerFactory.getLogger(DynamoDbConfiguration::class.java)
fun dataSource(): DynamoDbEnhancedAsyncClient {
logger.info("Using dynamo-db config")
return DynamoDbEnhancedAsyncClient.builder()
.dynamoDbClient(createDynamoDbClient())
.build()
}
}
private fun createDynamoDbClient(): DynamoDbAsyncClient {
return DynamoDbAsyncClient.builder().endpointOverride(URI("http://localhost:8000")).build()
}
fun Application.createEnhancedDynamoDbClient(dynamoDbClient: DynamoDbAsyncClient): DynamoDbEnhancedAsyncClient {
return DynamoDbEnhancedAsyncClient.builder()
.dynamoDbClient(dynamoDbClient)
.build()
}
suspend fun createNecessaryTables(
dynamoDbClient: DynamoDbAsyncClient,
dynamoDbEnhancedClient: DynamoDbEnhancedAsyncClient
) {
val existingTables = dynamoDbClient.listTables().await().tableNames().toList()
listOf(PlayerEntity::class).forEach {
createTableIfNotExists(existingTables, it, dynamoDbEnhancedClient)
}
}
private val logger = LoggerFactory.getLogger(Application::class.java)
private suspend fun <T : Any> createTableIfNotExists(
existingTables: List<String>,
item: KClass<T>,
dynamoDbEnhancedClient: DynamoDbEnhancedAsyncClient
) {
val tableSchema = DataClassTableSchema(item)
if (existingTables.contains(item.simpleName)) {
logger.info("Table '${item.simpleName}' already exists.")
} else {
dynamoDbEnhancedClient.table(item.simpleName, tableSchema).createTable().await()
logger.info("Table '${item.simpleName}' created successfully.")
}
}
\ No newline at end of file
package betclic.test
import com.fasterxml.jackson.databind.*
import io.ktor.serialization.jackson.*
import betclic.test.player.PlayerRepository
import betclic.test.player.PlayerService
import betclic.test.player.PlayerServiceImpl
import io.ktor.server.application.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.plugins.openapi.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import org.koin.dsl.module
import org.koin.ktor.plugin.Koin
import org.koin.logger.slf4jLogger
fun Application.configureFrameworks() {
fun Application.configureKoin() {
install(Koin) {
slf4jLogger()
modules(module {
single<HelloService> {
HelloService {
println(environment.log.info("Hello, World!"))
}
}
})
modules(playerModule)
}
}
val playerModule = module {
single { DynamoDbConfiguration().dataSource() }
single<PlayerRepository> { PlayerRepository(get()) }
single<PlayerService> { PlayerServiceImpl(get()) }
}
package betclic.test
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Application.configureRouting() {
routing {
get("/") {
call.respondText("Hello World!")
}
}
}
......@@ -4,3 +4,5 @@ ktor:
- betclic.test.ApplicationKt.module
deployment:
port: 8080
database:
dynamodbUrl: "http://localhost:8000"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment