diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index be6afb0a4..be803a72d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,9 +33,10 @@ jobs: fail-fast: false matrix: os: - - macos-13 +# Commented until we find a way to run containertests on macOS and Windows +# - macos-13 - ubuntu-22.04 - - windows-2022 +# - windows-2022 java-version: [ 17, 21 ] java-distribution: - adopt diff --git a/.gitignore b/.gitignore index 302a2c4e0..a77f0ce32 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,9 @@ .idea/.gitignore .idea/vcs.xml .idea/ktfmt.xml +.idea/codeStyles/** +.idea/detekt.xml +.idea/ktlint-plugin.xml # CMake cmake-build-*/ diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index bef7e2c1b..521126d24 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -8,10 +8,17 @@ repositories { } dependencies { + implementation(libs.plugins.allOpen.asDependency()) implementation(libs.plugins.detekt.asDependency()) implementation(libs.plugins.kotlin.asDependency()) implementation(libs.plugins.kover.asDependency()) + implementation(libs.plugins.ksp.asDependency()) implementation(libs.plugins.ktfmt.asDependency()) + implementation(libs.plugins.micronaut.app.asDependency()) + implementation(libs.plugins.micronaut.aot.asDependency()) + implementation(libs.plugins.micronaut.test.asDependency()) + implementation(libs.micronaut.buildtools) + implementation(libs.plugins.shadow.asDependency()) } fun Provider.asDependency(): Provider = diff --git a/build-logic/src/main/kotlin/Utils.kt b/build-logic/src/main/kotlin/Utils.kt index b4057f837..d085a0e28 100644 --- a/build-logic/src/main/kotlin/Utils.kt +++ b/build-logic/src/main/kotlin/Utils.kt @@ -1,9 +1,13 @@ +import org.gradle.api.artifacts.ExternalModuleDependencyBundle import org.gradle.api.artifacts.MinimalExternalModuleDependency import org.gradle.api.artifacts.VersionCatalog import org.gradle.api.provider.Provider fun VersionCatalog.getLibrary(name: String): Provider = findLibrary(name).get() +fun VersionCatalog.getBundle(name: String): Provider = findBundle(name).get() + object JavaVersion { - const val target: Int = 17 + const val asInt: Int = 17 + val asVersion: org.gradle.api.JavaVersion = org.gradle.api.JavaVersion.toVersion(asInt) } diff --git a/build-logic/src/main/kotlin/kotlin-base.gradle.kts b/build-logic/src/main/kotlin/kotlin-base.gradle.kts index 1d3b47bed..cbd8cde1e 100644 --- a/build-logic/src/main/kotlin/kotlin-base.gradle.kts +++ b/build-logic/src/main/kotlin/kotlin-base.gradle.kts @@ -21,5 +21,5 @@ tasks.test { } kotlin { - jvmToolchain(JavaVersion.target) + jvmToolchain(JavaVersion.asInt) } diff --git a/build-logic/src/main/kotlin/micronaut-base.gradle.kts b/build-logic/src/main/kotlin/micronaut-base.gradle.kts new file mode 100644 index 000000000..9610edcf4 --- /dev/null +++ b/build-logic/src/main/kotlin/micronaut-base.gradle.kts @@ -0,0 +1,47 @@ +plugins { + id("kotlin-base") + id("org.jetbrains.kotlin.plugin.allopen") + id("com.google.devtools.ksp") + id("com.github.johnrengelman.shadow") + id("io.micronaut.application") + id("io.micronaut.aot") + id("io.micronaut.test-resources") +} + +val catalog: VersionCatalog = extensions.getByType().named("libs") + +dependencies { + ksp(catalog.getBundle("micronaut-ksp")) + implementation(catalog.getBundle("micronaut-kotlin")) + catalog.getLibrary("micronaut-httpClient").let { + compileOnly(it) + testImplementation(it) + } + runtimeOnly(catalog.getLibrary("logback")) + runtimeOnly(catalog.getLibrary("jackson-kotlin")) +} + +java { + sourceCompatibility = JavaVersion.asVersion +} + +graalvmNative.toolchainDetection.set(false) +micronaut { + runtime("netty") + testRuntime("kotest5") + processing { + incremental(true) + annotations("micronaut.playground.*") + } + aot { + // Please review carefully the optimizations enabled below + // Check https://micronaut-projects.github.io/micronaut-aot/latest/guide/ for more details + optimizeServiceLoading = false + convertYamlToJava = false + precomputeOperations = true + cacheEnvironment = true + optimizeClassLoading = true + deduceEnvironment = true + optimizeNetty = true + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 79741d23d..8abe7e9d3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,23 +11,45 @@ konsist = "0.13.0" kotest = "5.8.0" kotlin = "1.9.22" kover = "0.7.6" +ksp = "1.9.22-1.0.17" ktfmt = "0.17.0" +micronaut = "4.3.4" +micronautBuildTools = "2.4.0" +shadow = "8.1.1" [libraries] cucumber-bom = { module = "io.cucumber:cucumber-bom", version.ref = "cucumber-bom" } cucumber-java = { module = "io.cucumber:cucumber-java" } cucumber-junit = { module = "io.cucumber:cucumber-junit-platform-engine" } junit-platform = { module = "org.junit.platform:junit-platform-suite", version.ref = "junit-platform" } +jackson-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin" } +kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } +kotlin-stdlibJdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" } konsist = { module = "com.lemonappdev:konsist", version.ref = "konsist" } kotest = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" } +logback = { module = "ch.qos.logback:logback-classic" } +micronaut-buildtools = { module = "io.micronaut.testresources:micronaut-test-resources-build-tools", version.ref = "micronautBuildTools" } +micronaut-httpClient = { module = "io.micronaut:micronaut-http-client" } +micronaut-httpValidation = { module = "io.micronaut:micronaut-http-validation" } +micronaut-kotlinRuntime = { module = "io.micronaut.kotlin:micronaut-kotlin-runtime" } +micronaut-serdeJackson = { module = "io.micronaut.serde:micronaut-serde-jackson" } +micronaut-serdeProcessor = { module = "io.micronaut.serde:micronaut-serde-processor" } [plugins] +allOpen = { id = "org.jetbrains.kotlin.plugin.allopen", version.ref = "kotlin" } detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } gitSemVer = { id = "org.danilopianini.git-sensitive-semantic-versioning", version.ref = "gitSemVer" } kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } ktfmt = { id = "com.ncorti.ktfmt.gradle", version.ref = "ktfmt" } +micronaut-app = { id = "io.micronaut.application", version.ref = "micronaut" } +micronaut-aot = { id = "io.micronaut.application", version.ref = "micronaut" } +micronaut-test = { id = "io.micronaut.test-resources", version.ref = "micronaut" } +shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } [bundles] cucumberJunit = [ "cucumber-java", "cucumber-junit" ] +micronaut-ksp = [ "micronaut-httpValidation", "micronaut-serdeProcessor" ] +micronaut-kotlin = [ "kotlin-reflect", "kotlin-stdlibJdk8", "micronaut-kotlinRuntime", "micronaut-serdeJackson", ] diff --git a/micronaut-playground/.gitignore b/micronaut-playground/.gitignore new file mode 100644 index 000000000..5a03bc30a --- /dev/null +++ b/micronaut-playground/.gitignore @@ -0,0 +1,15 @@ +Thumbs.db +.DS_Store +.gradle +build/ +target/ +out/ +.micronaut/ +.idea +*.iml +*.ipr +*.iws +.project +.settings +.classpath +.factorypath diff --git a/micronaut-playground/application.yml b/micronaut-playground/application.yml new file mode 100644 index 000000000..875e3675f --- /dev/null +++ b/micronaut-playground/application.yml @@ -0,0 +1,4 @@ +application: + name: "My Application" + version: "1.0.0" + description: "My Application Description" diff --git a/micronaut-playground/build.gradle.kts b/micronaut-playground/build.gradle.kts new file mode 100644 index 000000000..d74ae531b --- /dev/null +++ b/micronaut-playground/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { id("micronaut-base") } + +application { mainClass.set("micronaut.playground.ApplicationKt") } + +dependencies { + ksp("io.micronaut.data:micronaut-data-document-processor") + implementation("io.micronaut.data:micronaut-data-mongodb") + runtimeOnly("org.mongodb:mongodb-driver-sync") +} diff --git a/micronaut-playground/gradle.properties b/micronaut-playground/gradle.properties new file mode 100644 index 000000000..58cfb62e8 --- /dev/null +++ b/micronaut-playground/gradle.properties @@ -0,0 +1,3 @@ +micronautVersion=4.3.2 +kotlinVersion=1.9.22 +org.gradle.jvmargs=-Xmx4096M diff --git a/micronaut-playground/micronaut-cli.yml b/micronaut-playground/micronaut-cli.yml new file mode 100644 index 000000000..bb018198e --- /dev/null +++ b/micronaut-playground/micronaut-cli.yml @@ -0,0 +1,6 @@ +applicationType: default +defaultPackage: micronaut.playground +testFramework: kotest +sourceLanguage: kotlin +buildTool: gradle_kotlin +features: [ app-name, gradle, http-client-test, kotest, kotlin, kotlin-application, ksp, logback, micronaut-aot, micronaut-build, micronaut-http-validation, netty-server, properties, readme, serialization-jackson, shade, static-resources ] \ No newline at end of file diff --git a/micronaut-playground/settings.gradle.kts b/micronaut-playground/settings.gradle.kts new file mode 100644 index 000000000..e4c841aa6 --- /dev/null +++ b/micronaut-playground/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "micronaut-playground" diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/Application.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/Application.kt new file mode 100644 index 000000000..8ca0e4f32 --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/Application.kt @@ -0,0 +1,20 @@ +package piperkt.services.template + +import io.micronaut.runtime.Micronaut.run + +fun main(vararg args: String) { + run(*args) +} + +// LEVEL -> WHATS -> DEPENDENCIES +// -------------------------------- +// DOMAIN -> Language: +// - Entities +// - Value Objects +// - Repositories +// - Factories +// APPLICATION -> Domain +// - Services +// INTERFACES -> +// - Controller (Indepedent of the framework) +// INFRASTRUCTURE diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/application/UserEventsService.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/application/UserEventsService.kt new file mode 100644 index 000000000..8790d5362 --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/application/UserEventsService.kt @@ -0,0 +1,12 @@ +package piperkt.services.template.application + +import piperkt.services.template.application.api.UserEventsApi +import piperkt.services.template.commons.events.UserCreated +import piperkt.services.template.domain.User +import piperkt.services.template.domain.UserRepository + +class UserEventsService(private val userRepository: UserRepository) : UserEventsApi { + override fun onUserCreated(userCreated: UserCreated) { + userRepository.save(User(email = userCreated.email, password = userCreated.password)) + } +} diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/application/UserService.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/application/UserService.kt new file mode 100644 index 000000000..34deb3701 --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/application/UserService.kt @@ -0,0 +1,27 @@ +package piperkt.services.template.application + +import piperkt.services.template.application.api.UserServiceApi +import piperkt.services.template.commons.events.EventPublisher +import piperkt.services.template.commons.events.UserCreated +import piperkt.services.template.domain.User +import piperkt.services.template.domain.UserRepository + +open class UserService( + private val userRepository: UserRepository, + private val eventPublisher: EventPublisher, +) : UserServiceApi { + override fun registerUser( + email: String, + password: String, + ): User { + val user = User(email = email, password = password) + return userRepository.save(user).also { + eventPublisher.publish(UserCreated(email = email, password = password)) + } + } + + override fun loginUser( + email: String, + password: String, + ): User? = userRepository.findByEmail(email)?.takeIf { it.password == password } +} diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/application/api/UserEventsApi.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/application/api/UserEventsApi.kt new file mode 100644 index 000000000..790a69e0b --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/application/api/UserEventsApi.kt @@ -0,0 +1,7 @@ +package piperkt.services.template.application.api + +import piperkt.services.template.commons.events.UserCreated + +interface UserEventsApi { + fun onUserCreated(userCreated: UserCreated) +} diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/application/api/UserServiceApi.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/application/api/UserServiceApi.kt new file mode 100644 index 000000000..455b64b0b --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/application/api/UserServiceApi.kt @@ -0,0 +1,15 @@ +package piperkt.services.template.application.api + +import piperkt.services.template.domain.User + +interface UserServiceApi { + fun registerUser( + email: String, + password: String, + ): User + + fun loginUser( + email: String, + password: String, + ): User? +} diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/commons/events/Event.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/commons/events/Event.kt new file mode 100644 index 000000000..9dfa4c22f --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/commons/events/Event.kt @@ -0,0 +1,7 @@ +package piperkt.services.template.commons.events + +interface Event + +interface EventPublisher { + fun publish(event: Event) +} diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/commons/events/UserCreated.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/commons/events/UserCreated.kt new file mode 100644 index 000000000..c7abb5c11 --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/commons/events/UserCreated.kt @@ -0,0 +1,6 @@ +package piperkt.services.template.commons.events + +data class UserCreated( + val email: String, + val password: String, +) : Event diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/domain/User.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/domain/User.kt new file mode 100644 index 000000000..177e7b229 --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/domain/User.kt @@ -0,0 +1,6 @@ +package piperkt.services.template.domain + +data class User( + val email: String, + val password: String, +) diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/domain/UserRepository.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/domain/UserRepository.kt new file mode 100644 index 000000000..5539dce46 --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/domain/UserRepository.kt @@ -0,0 +1,7 @@ +package piperkt.services.template.domain + +interface UserRepository { + fun findByEmail(email: String): User? + + fun save(user: User): User +} diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/events/KafkaEventPublisher.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/events/KafkaEventPublisher.kt new file mode 100644 index 000000000..73c91f2d7 --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/events/KafkaEventPublisher.kt @@ -0,0 +1,28 @@ +package piperkt.services.template.infrastructure.events + +import jakarta.inject.Singleton +import piperkt.services.template.commons.events.Event +import piperkt.services.template.commons.events.EventPublisher + +@Singleton +class KafkaEventPublisher : EventPublisher { + override fun publish(event: Event) { + println("Publishing event: $event") + } +} + +/** + * @Singleton class KafkaEventPublisher(): EventPublisher { + * + * override fun publish(any: Any) { + * + * } + * + * } + * + * @KafkaListener class KafkaListener(userEventsService: UserEventsService): UserEventsApi { + * @Topic("user-created") override fun onUserCreated(userCreated: UserCreated) { + * userEventsService.onUserCreated(userCreated) } + * + * } + */ diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/implementation/UserServiceImpl.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/implementation/UserServiceImpl.kt new file mode 100644 index 000000000..5045448bf --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/implementation/UserServiceImpl.kt @@ -0,0 +1,11 @@ +package piperkt.services.template.infrastructure.implementation + +import jakarta.inject.Singleton +import piperkt.services.template.commons.events.EventPublisher +import piperkt.services.template.domain.UserRepository + +@Singleton +class UserServiceImpl( + userRepository: UserRepository, + eventPublisher: EventPublisher, +) : piperkt.services.template.application.UserService(userRepository, eventPublisher) diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/persistence/model/UserEntity.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/persistence/model/UserEntity.kt new file mode 100644 index 000000000..953375a9c --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/persistence/model/UserEntity.kt @@ -0,0 +1,15 @@ +package piperkt.services.template.infrastructure.persistence.model + +import io.micronaut.data.annotation.Id +import io.micronaut.data.annotation.MappedEntity +import io.micronaut.data.mongodb.annotation.MongoRepository +import io.micronaut.data.repository.CrudRepository +import jakarta.validation.constraints.NotBlank + +@MappedEntity +data class UserEntity( + @Id val email: String, + @NotBlank val password: String, +) + +@MongoRepository interface UserModelRepository : CrudRepository diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/persistence/repository/InMemoryRepository.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/persistence/repository/InMemoryRepository.kt new file mode 100644 index 000000000..cd14828ed --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/persistence/repository/InMemoryRepository.kt @@ -0,0 +1,17 @@ +package piperkt.services.template.infrastructure.persistence.repository + +import jakarta.inject.Named +import piperkt.services.template.domain.User +import piperkt.services.template.domain.UserRepository + +@Named("inMemory") +class InMemoryRepository : UserRepository { + val users = mutableListOf() + + override fun findByEmail(email: String): User? = users.find { it.email == email } + + override fun save(user: User): User { + users.add(user) + return user + } +} diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/persistence/repository/UserRepositoryImpl.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/persistence/repository/UserRepositoryImpl.kt new file mode 100644 index 000000000..c949461e8 --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/persistence/repository/UserRepositoryImpl.kt @@ -0,0 +1,20 @@ +package piperkt.services.template.infrastructure.persistence.repository + +import io.micronaut.context.annotation.Primary +import jakarta.inject.Singleton +import piperkt.services.template.domain.User +import piperkt.services.template.domain.UserRepository +import piperkt.services.template.infrastructure.persistence.model.UserEntity +import piperkt.services.template.infrastructure.persistence.model.UserModelRepository + +@Singleton +@Primary +class UserRepositoryImpl(private val userModelRepository: UserModelRepository) : UserRepository { + override fun findByEmail(email: String): User? = + userModelRepository.findById(email).map { User(it.email, it.password) }.orElse(null) + + override fun save(user: User): User { + val userModel = UserEntity(user.email, user.password) + return userModelRepository.save(userModel).let { User(it.email, it.password) } + } +} diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/web/UserHTTPController.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/web/UserHTTPController.kt new file mode 100644 index 000000000..4b3e1a46a --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/web/UserHTTPController.kt @@ -0,0 +1,30 @@ +package piperkt.services.template.infrastructure.web + +import io.micronaut.http.annotation.Body +import io.micronaut.http.annotation.Controller +import io.micronaut.http.annotation.Post +import piperkt.services.template.infrastructure.web.api.LoginRequest +import piperkt.services.template.infrastructure.web.api.LoginResponse +import piperkt.services.template.infrastructure.web.api.RegisterRequest +import piperkt.services.template.infrastructure.web.api.RegisterResponse + +@Controller("/users") +class UserHTTPController( + private val userService: piperkt.services.template.application.UserService, +) { + @Post("/login", consumes = ["application/json"], produces = ["application/json"]) + fun login( + @Body request: LoginRequest, + ): LoginResponse { + val result = userService.loginUser(request.email, request.password) + return LoginResponse(result?.email.orEmpty()) + } + + @Post("/register") + fun register( + @Body request: RegisterRequest, + ): RegisterResponse { + val result = userService.registerUser(request.email, request.password) + return RegisterResponse(result.email) + } +} diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/web/api/Login.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/web/api/Login.kt new file mode 100644 index 000000000..c61b48014 --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/web/api/Login.kt @@ -0,0 +1,12 @@ +package piperkt.services.template.infrastructure.web.api + +import io.micronaut.serde.annotation.Serdeable +import jakarta.validation.constraints.NotBlank + +@Serdeable +data class LoginRequest( + @NotBlank val email: String, + val password: String, +) + +@Serdeable data class LoginResponse(val email: String) diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/web/api/Register.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/web/api/Register.kt new file mode 100644 index 000000000..9ed2b0d41 --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/web/api/Register.kt @@ -0,0 +1,15 @@ +package piperkt.services.template.infrastructure.web.api + +import io.micronaut.serde.annotation.Serdeable +import jakarta.validation.constraints.NotBlank + +@Serdeable +data class RegisterRequest( + @NotBlank val email: String, + @NotBlank val password: String, +) + +@Serdeable +data class RegisterResponse( + @NotBlank val email: String, +) diff --git a/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/websocket/WebsocketServer.kt b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/websocket/WebsocketServer.kt new file mode 100644 index 000000000..6bbde1729 --- /dev/null +++ b/micronaut-playground/src/main/kotlin/piperkt/services/template/infrastructure/websocket/WebsocketServer.kt @@ -0,0 +1,18 @@ +package piperkt.services.template.infrastructure.websocket + +import io.micronaut.websocket.annotation.OnMessage +import io.micronaut.websocket.annotation.OnOpen +import io.micronaut.websocket.annotation.ServerWebSocket + +@ServerWebSocket("/ws") +class WebsocketServer { + @OnOpen + fun onOpen() { + println("Client connected") + } + + @OnMessage + fun onMessage(message: String) { + println("Received message: $message") + } +} diff --git a/micronaut-playground/src/main/resources/application.properties b/micronaut-playground/src/main/resources/application.properties new file mode 100644 index 000000000..ec2059a50 --- /dev/null +++ b/micronaut-playground/src/main/resources/application.properties @@ -0,0 +1,2 @@ +#Thu Feb 22 11:03:09 CET 2024 +micronaut.application.name=micronaut-playground \ No newline at end of file diff --git a/micronaut-playground/src/main/resources/logback.xml b/micronaut-playground/src/main/resources/logback.xml new file mode 100644 index 000000000..4b0818562 --- /dev/null +++ b/micronaut-playground/src/main/resources/logback.xml @@ -0,0 +1,15 @@ + + + + + + %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n + + + + + + + + diff --git a/micronaut-playground/src/test/kotlin/io/kotest/provided/ProjectConfig.kt b/micronaut-playground/src/test/kotlin/io/kotest/provided/ProjectConfig.kt new file mode 100644 index 000000000..a328bf464 --- /dev/null +++ b/micronaut-playground/src/test/kotlin/io/kotest/provided/ProjectConfig.kt @@ -0,0 +1,8 @@ +package io.kotest.provided + +import io.kotest.core.config.AbstractProjectConfig +import io.micronaut.test.extensions.kotest5.MicronautKotest5Extension + +object ProjectConfig : AbstractProjectConfig() { + override fun extensions() = listOf(MicronautKotest5Extension) +} diff --git a/micronaut-playground/src/test/kotlin/piperkt/services/template/DatabaseRepositoryTest.kt b/micronaut-playground/src/test/kotlin/piperkt/services/template/DatabaseRepositoryTest.kt new file mode 100644 index 000000000..fd3a812b7 --- /dev/null +++ b/micronaut-playground/src/test/kotlin/piperkt/services/template/DatabaseRepositoryTest.kt @@ -0,0 +1,14 @@ +package piperkt.services.template + +import io.kotest.core.spec.style.AnnotationSpec +import io.micronaut.test.extensions.kotest5.annotation.MicronautTest +import piperkt.services.template.domain.UserRepository + +@MicronautTest +class DatabaseRepositoryTest(private val userRepository: UserRepository) : AnnotationSpec() { + @Test + fun testUserRepository() { + val users = userRepository.findByEmail("email") + assert(users == null) + } +} diff --git a/micronaut-playground/src/test/kotlin/piperkt/services/template/MicronautPlaygroundTest.kt b/micronaut-playground/src/test/kotlin/piperkt/services/template/MicronautPlaygroundTest.kt new file mode 100644 index 000000000..3a2ba1730 --- /dev/null +++ b/micronaut-playground/src/test/kotlin/piperkt/services/template/MicronautPlaygroundTest.kt @@ -0,0 +1,9 @@ +package piperkt.services.template + +import io.kotest.core.spec.style.StringSpec +import io.micronaut.runtime.EmbeddedApplication +import io.micronaut.test.extensions.kotest5.annotation.MicronautTest + +@MicronautTest +class MicronautPlaygroundTest(private val application: EmbeddedApplication<*>) : + StringSpec({ "test the server is running" { assert(application.isRunning) } }) diff --git a/micronaut-playground/src/test/kotlin/piperkt/services/template/UserControllerTest.kt b/micronaut-playground/src/test/kotlin/piperkt/services/template/UserControllerTest.kt new file mode 100644 index 000000000..bd599871f --- /dev/null +++ b/micronaut-playground/src/test/kotlin/piperkt/services/template/UserControllerTest.kt @@ -0,0 +1,6 @@ +package piperkt.services.template + +import io.kotest.core.spec.style.AnnotationSpec +import io.micronaut.test.extensions.kotest5.annotation.MicronautTest + +@MicronautTest class UserControllerTest : AnnotationSpec() diff --git a/settings.gradle.kts b/settings.gradle.kts index b964a67d2..157561cc6 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -35,3 +35,4 @@ include("bdd") include("commons") include("users-service") include("servers-service") +include("micronaut-playground")