Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
dabliuw22 committed Dec 10, 2023
1 parent 5adc878 commit ee53c94
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 46 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ In this project an API rest with Ktot, Arrow, JDBC was created.

## Requirements

* JDK >= 17
* JDK >= 21
* Kotlin
* Docker
* Docker Compose
Expand Down
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ allprojects {
}

kotlin {
jvmToolchain(21)
compilerOptions {
apiVersion = KotlinVersion.KOTLIN_1_9
}
Expand All @@ -42,6 +43,7 @@ allprojects {
}
}


tasks.withType(KotlinCompile).configureEach {
kotlinOptions {
verbose = true
Expand Down Expand Up @@ -95,7 +97,7 @@ subprojects {
def groovy_version = "3.0.9"

buildscript {
ext.kotlin_version = '1.9.20'
ext.kotlin_version = '1.9.21'
repositories {
mavenCentral()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.leysoft.infrastructure.http

import arrow.core.Either
import arrow.core.Option
import arrow.core.*
import com.leysoft.core.error.BaseException
import com.leysoft.core.error.InfrastructureException
import io.ktor.http.*
import io.ktor.server.application.*
Expand Down Expand Up @@ -30,5 +30,11 @@ suspend inline fun <reified A : Any> ApplicationCall.respondJson(
fun ApplicationCall.getParam(key: String): Option<String> =
Option.fromNullable(parameters[key])

fun <A> ApplicationCall.getRequiredParam(key: String, f: (String) -> A): Either<BaseException, A> =
when (val id = getParam(key)) {
is Some -> f(id.value).right()
else -> RequiredParameterException(key).left()
}

data class RequiredParameterException(override val message: String) :
InfrastructureException(message)
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ interface Jdbc {
decoder: Decoder<A>
): Either<SqlException, A> =
withContext(this@CoroutineContext) {
Either.catch { first(query) { decoder.decode(it) } }
log.info("Start Jdbc.first(): ${query.statement}")
either<Throwable, A?> { first(query) { decoder.decode(it) } }
.mapLeft {
Data.QueryError(
it.message ?: "Error trying to execute first"
Expand All @@ -67,19 +68,20 @@ interface Jdbc {
.flatMap {
it?.right() ?: Data.SqlNotFound("Not Found").left()
}
.onLeft { error -> log.info("Error executing Jdbc.first(): $error") }
.onRight { log.info("End Jdbc.first(): ${query.statement}") }
}

override suspend fun <A> list(query: SqlQuery, decoder: Decoder<A>): Either<SqlException, List<A>> =
withContext(this@CoroutineContext) {
log.info("Start Jdbc.list()")
val result = either<Throwable, List<A>> { this@Session.list(query) { decoder.decode(it) } }
log.info("Start Jdbc.list(): ${query.statement}")
either<Throwable, List<A>> { this@Session.list(query) { decoder.decode(it) } }
.mapLeft {
Data.QueryError(
it.message ?: "Error trying to execute list"
)
}
log.info("End Jdbc.list()")
result
}.onLeft { error -> log.info("Error executing Jdbc.list(): $error") }
.onRight { log.info("End Jdbc.list(): ${query.statement}") }
}

override suspend fun command(command: SqlQuery): Either<SqlException, Int> =
Expand All @@ -90,12 +92,15 @@ interface Jdbc {

override suspend fun <A> transaction(program: (Transaction) -> A): Either<SqlException, A> =
withContext(this@CoroutineContext) {
log.info("Start Jdbc.transaction()")
either<Throwable, A> { this@Session.transaction { program(it) } }
.mapLeft {
Data.TransactionError(
it.message ?: "Error trying to execute transaction"
)
}
.onLeft { error -> log.info("Error executing Jdbc.transaction(): $error") }
.onRight { log.info("End Jdbc.transaction()") }
}
}
}
Expand Down
1 change: 1 addition & 0 deletions infrastructure/logger/src/main/resources/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<logger name="io.netty" level="INFO"/>
<logger name="io.vertx" level="INFO"/>
<logger name="reactor.util" level="INFO"/>
<logger name="io.ktor.routing" level="INFO"/>

<root level="all">
<appender-ref ref="stdOut"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.leysoft.products.adapter.`in`.api

import arrow.core.Either
import arrow.core.Some
import arrow.core.flatMap
import com.leysoft.core.domain.toProductId
import com.leysoft.core.error.BaseException
import com.leysoft.infrastructure.http.*
import com.leysoft.products.application.ProductService
import io.ktor.http.*
Expand Down Expand Up @@ -34,13 +32,12 @@ private fun Route.all(service: ProductService) {

private fun Route.get(service: ProductService) {
get("/{id}") {
val result = when (val id = call.getParam("id")) {
is Some -> service.getBy(id.value.toProductId())
else -> Either.Left<BaseException>(RequiredParameterException("id"))
}
result.handle({
call.respondJson(HttpStatusCode.OK, it)
}) { errorHandler(call) }
call.getRequiredParam("id") { it }
.map { it.toProductId() }
.flatMap { service.getBy(it) }
.handle({
call.respondJson(HttpStatusCode.OK, it)
}) { errorHandler(call) }
}
}

Expand All @@ -56,12 +53,11 @@ private fun Route.create(service: ProductService) {

private fun Route.delete(service: ProductService) {
delete("/{id}") {
val result = when (val id = call.getParam("id")) {
is Some -> service.deleteBy(id.value.toProductId())
else -> Either.Left<BaseException>(RequiredParameterException("id"))
}
result.handle({
call.response.status(HttpStatusCode.Accepted)
}) { errorHandler(call) }
call.getRequiredParam("id") { it }
.map { it.toProductId() }
.flatMap { service.deleteBy(it) }
.handle({
call.response.status(HttpStatusCode.Accepted)
}) { errorHandler(call) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.leysoft.products.adapter.out.persistence.memory

import arrow.core.Either
import arrow.core.flatMap
import arrow.core.left
import arrow.core.raise.either
import arrow.core.right
import arrow.fx.coroutines.Atomic
import com.leysoft.core.error.CreateProductException
Expand All @@ -18,33 +20,26 @@ class InMemoryProductRepository private constructor(private val storage: Storage
ProductRepository {

override suspend fun findBy(id: ProductId): Either<ProductException, Product> =
Either.catch({
NotFoundProductException("Not found product: $id")
}) { storage.get() }
either<Throwable, Map<String, Product>> { storage.get() }
.mapLeft { NotFoundProductException("Not found product: $id") }
.map { it[id.value] }
.flatMap { it?.right() ?: Either.Left(NotFoundProductException("Not found product: $id")) }
.flatMap { it?.right() ?: NotFoundProductException("Not found product: $id").left() }

override suspend fun findAll(): Either<ProductException, List<Product>> =
Either.catch({ NotFoundProductException("Not found products") }) {
either<Throwable, List<Product>> {
storage.get().values.toList()
}
}.mapLeft { NotFoundProductException("Not found products") }

override suspend fun save(product: Product): Either<ProductException, Unit> {
return when (val result = findBy(product.id)) {
is Either.Left ->
when (val error = result.value) {
is NotFoundProductException -> Either.catch({
CreateProductException("Not save Product: ${product.id}")
}) {
storage.update {
it.plus(Pair(product.id.value, product))
}
}
else -> Either.Left(error)
is NotFoundProductException -> either<Throwable, Unit> {
storage.update { it.plus(Pair(product.id.value, product)) }
}.mapLeft { CreateProductException("Not save Product: ${product.id}") }
else -> error.left()
}
else -> Either.Left(
CreateProductException("Not save Product: ${product.id}")
)
else -> CreateProductException("Not save Product: ${product.id}").left()
}
}

Expand All @@ -55,7 +50,7 @@ class InMemoryProductRepository private constructor(private val storage: Storage
storage.update { it.minus(id.value) }
}
}
is Either.Left -> Either.Left(result.value)
is Either.Left -> result.value.left()
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.leysoft.products.application

import arrow.core.Either
import arrow.core.flatMap
import arrow.core.right
import com.leysoft.core.domain.Product
import com.leysoft.core.domain.ProductId
import com.leysoft.core.error.ProductException
Expand All @@ -20,7 +22,8 @@ interface ProductService {
companion object Instance {
fun make(repository: ProductRepository): ProductService = object : ProductService {
override suspend fun getBy(id: ProductId): Either<ProductException, Product> =
repository.findBy(id.fromCore())
id.fromCore().right()
.flatMap { repository.findBy(it) }
.map { it.toCore() }

override suspend fun getAll(): Either<ProductException, List<Product>> =
Expand Down

0 comments on commit ee53c94

Please sign in to comment.