Skip to content

Commit

Permalink
using non depreciated apis
Browse files Browse the repository at this point in the history
  • Loading branch information
psuzn committed Jun 7, 2024
1 parent 5cfabe7 commit bd440db
Show file tree
Hide file tree
Showing 36 changed files with 730 additions and 810 deletions.
6 changes: 5 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ ij_kotlin_name_count_to_use_star_import_for_members = 99999
ij_java_names_count_to_use_import_on_demand = 99999

ktlint_code_style = ktlint_official
ktlint_standard_filename = disabled
ktlint_standard_filename = disabled
ktlint_function_signature_body_expression_wrapping = default
ktlint_standard_multiline-expression-wrapping = disabled
ktlint_standard_string-template-indent = disabled
ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 5
18 changes: 8 additions & 10 deletions backend/src/main/kotlin/me/sujanpoudel/playdeals/DIConfigurer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import com.google.firebase.messaging.FirebaseMessaging
import io.vertx.core.Vertx
import io.vertx.core.eventbus.DeliveryOptions
import io.vertx.core.json.jackson.DatabindCodec
import io.vertx.pgclient.PgBuilder
import io.vertx.pgclient.PgConnectOptions
import io.vertx.pgclient.PgPool
import io.vertx.sqlclient.PoolOptions
import me.sujanpoudel.playdeals.api.ApiVerticle
import me.sujanpoudel.playdeals.jobs.AndroidAppExpiryCheckScheduler
Expand Down Expand Up @@ -50,10 +50,7 @@ import java.time.Duration

inline fun <reified T : Any> DI.get(tag: String? = null) = direct.instance<T>(tag)

fun configureDI(
vertx: Vertx,
conf: Conf,
) = DI {
fun configureDI(vertx: Vertx, conf: Conf) = DI {
bindSingleton { conf }

bindSingleton { ApiVerticle(di = this) }
Expand Down Expand Up @@ -93,11 +90,12 @@ fun configureDI(
}

bindSingleton {
PgPool.client(vertx, instance<PgConnectOptions>(), PoolOptions().setMaxSize(conf.db.poolSize))
}

bindSingleton {
PgPool.pool(vertx, instance<PgConnectOptions>(), PoolOptions())
PgBuilder
.client()
.using(vertx)
.connectingTo(instance<PgConnectOptions>())
.with(PoolOptions().setMaxSize(conf.db.poolSize))
.build()
}

bindSingleton<JobActivator> {
Expand Down
28 changes: 13 additions & 15 deletions backend/src/main/kotlin/me/sujanpoudel/playdeals/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,20 @@ import org.kodein.di.instance
import kotlin.system.exitProcess

private val vertx = Vertx.vertx()
val configuration =
buildConf(System.getenv()).getOrThrow {
(it as BootstrapException).violations.forEach(::println)
exitProcess(-1)
}
val configuration = buildConf(System.getenv()).getOrThrow {
(it as BootstrapException).violations.forEach(::println)
exitProcess(-1)
}

val primaryDI = configureDI(vertx, configuration)

fun main(): Unit =
runBlocking {
primaryDI.direct.instance<ObjectMapper>()
fun main(): Unit = runBlocking {
primaryDI.direct.instance<ObjectMapper>()

vertx.deployVerticle(primaryDI.direct.instance<MainVerticle>())
.onSuccess { logger.infoNotify("Deployed MainVerticle : $it") }
.onFailure {
logger.error(it) { "Error deploying main verticle" }
vertx.close()
}.coAwait()
}
vertx.deployVerticle(primaryDI.direct.instance<MainVerticle>())
.onSuccess { logger.infoNotify("Deployed MainVerticle : $it") }
.onFailure {
logger.error(it) { "Error deploying main verticle" }
vertx.close()
}.coAwait()
}
26 changes: 11 additions & 15 deletions backend/src/main/kotlin/me/sujanpoudel/playdeals/api/ForexRate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,15 @@ import me.sujanpoudel.playdeals.usecases.executeUseCase
import org.kodein.di.DirectDI
import org.kodein.di.instance

fun forexRateApi(
di: DirectDI,
vertx: io.vertx.core.Vertx,
): Router =
Router.router(vertx).apply {
get()
.coHandler { ctx ->
ctx.executeUseCase(
useCase = di.instance<GetForexUseCase>(),
toContext = { },
toInput = { },
) {
ctx.json(jsonResponse(data = it))
}
fun forexRateApi(di: DirectDI, vertx: io.vertx.core.Vertx): Router = Router.router(vertx).apply {
get()
.coHandler { ctx ->
ctx.executeUseCase(
useCase = di.instance<GetForexUseCase>(),
toContext = { },
toInput = { },
) {
ctx.json(jsonResponse(data = it))
}
}
}
}
44 changes: 20 additions & 24 deletions backend/src/main/kotlin/me/sujanpoudel/playdeals/api/Health.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,30 @@ import me.sujanpoudel.playdeals.usecases.DBHealthUseCase
import org.kodein.di.DirectDI
import org.kodein.di.instance

fun healthApi(
di: DirectDI,
vertx: Vertx,
): Router =
Router.router(vertx).apply {
val dbHealthChecker = di.instance<DBHealthUseCase>()
fun healthApi(di: DirectDI, vertx: Vertx): Router = Router.router(vertx).apply {
val dbHealthChecker = di.instance<DBHealthUseCase>()

val livenessHandler = HealthCheckHandler.create(vertx)
val readinessHandler = HealthCheckHandler.create(vertx)
val livenessHandler = HealthCheckHandler.create(vertx)
val readinessHandler = HealthCheckHandler.create(vertx)

livenessHandler.register("status") { promise ->
promise.complete(Status.OK())
}
livenessHandler.register("status") { promise ->
promise.complete(Status.OK())
}

readinessHandler.register("status") { promise ->
promise.complete(Status.OK())
}
readinessHandler.register("status") { promise ->
promise.complete(Status.OK())
}

readinessHandler.register("postgres") { promise ->
CoroutineScope(Dispatchers.IO).launch(vertx.dispatcher()) {
if (dbHealthChecker.execute(Unit)) {
promise.complete(Status.OK())
} else {
promise.complete(Status.KO())
}
readinessHandler.register("postgres") { promise ->
CoroutineScope(Dispatchers.IO).launch(vertx.dispatcher()) {
if (dbHealthChecker.execute(Unit)) {
promise.complete(Status.OK())
} else {
promise.complete(Status.KO())
}
}

get("/liveness").handler(livenessHandler)
get("/readiness").handler(readinessHandler)
}

get("/liveness").handler(livenessHandler)
get("/readiness").handler(readinessHandler)
}
46 changes: 21 additions & 25 deletions backend/src/main/kotlin/me/sujanpoudel/playdeals/api/deals/Api.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,27 @@ import me.sujanpoudel.playdeals.usecases.executeUseCase
import org.kodein.di.DirectDI
import org.kodein.di.instance

fun appDealsApi(
di: DirectDI,
vertx: Vertx,
): Router =
Router.router(vertx).apply {
get()
.coHandler { ctx ->
ctx.executeUseCase(
useCase = di.instance<GetDealsUseCase>(),
toContext = { GetDealsContext(ctx.request().params()) },
toInput = { GetDealsUseCase.Input(it.skip, it.take) },
) {
ctx.json(jsonResponse(data = it))
}
fun appDealsApi(di: DirectDI, vertx: Vertx): Router = Router.router(vertx).apply {
get()
.coHandler { ctx ->
ctx.executeUseCase(
useCase = di.instance<GetDealsUseCase>(),
toContext = { GetDealsContext(ctx.request().params()) },
toInput = { GetDealsUseCase.Input(it.skip, it.take) },
) {
ctx.json(jsonResponse(data = it))
}
}

post()
.consumes(ContentTypes.JSON)
.coHandler { ctx ->
ctx.executeUseCase(
useCase = di.instance<NewDealUseCase>(),
toContext = { NewDealContext(ctx.request().body().coAwait().toJsonObject()) },
toInput = { it.packageName },
) {
ctx.json(jsonResponse<Any>("App added for queue"))
}
post()
.consumes(ContentTypes.JSON)
.coHandler { ctx ->
ctx.executeUseCase(
useCase = di.instance<NewDealUseCase>(),
toContext = { NewDealContext(ctx.request().body().coAwait().toJsonObject()) },
toInput = { it.packageName },
) {
ctx.json(jsonResponse<Any>("App added for queue"))
}
}
}
}
114 changes: 54 additions & 60 deletions backend/src/main/kotlin/me/sujanpoudel/playdeals/common/Conf.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,72 +9,66 @@ import java.util.Base64

class BootstrapException(val violations: List<String>) : RuntimeException()

fun buildConf(envs: Map<String, String>) =
com.github.michaelbull.result.runCatching {
val violations = mutableListOf<String>()
fun buildConf(envs: Map<String, String>) = com.github.michaelbull.result.runCatching {
val violations = mutableListOf<String>()

@Suppress("UNCHECKED_CAST")
fun <T> env(
envVarName: String,
default: String? = null,
converter: (String) -> T? = { it as? T },
): T? =
(
envs[envVarName] ?: default ?: run {
violations += "No '$envVarName' env var defined!".also { logger.error { it } }
null
}
)?.let(converter) ?: run {
violations += "Invalid '$envVarName'"
null
}
@Suppress("UNCHECKED_CAST")
fun <T> env(envVarName: String, default: String? = null, converter: (String) -> T? = { it as? T }): T? = (
envs[envVarName] ?: default ?: run {
violations += "No '$envVarName' env var defined!".also { logger.error { it } }
null
}
)?.let(converter) ?: run {
violations += "Invalid '$envVarName'"
null
}

val environment = env("ENV", Environment.PRODUCTION.name) { it.asEnumOrNull<Environment>() }
val environment = env("ENV", Environment.PRODUCTION.name) { it.asEnumOrNull<Environment>() }

val appPort = env("APP_PORT", "8888") { it.toIntOrNull() }
val cors = env<String>("CORS", ".*.")
val appPort = env("APP_PORT", "8888") { it.toIntOrNull() }
val cors = env<String>("CORS", ".*.")

val dbPort = env("DB_PORT", "5432") { it.toIntOrNull() }
val dbName = env<String>("DB_NAME", "play_deals")
val dbPoolSize = env("DB_POOL_SIZE", "5") { it.toIntOrNull() }
val dbHost = env<String>("DB_HOST")
val dbUsername = env<String>("DB_USERNAME")
val dbPassword = env<String>("DB_PASSWORD", "password")
val dbPort = env("DB_PORT", "5432") { it.toIntOrNull() }
val dbName = env<String>("DB_NAME", "play_deals")
val dbPoolSize = env("DB_POOL_SIZE", "5") { it.toIntOrNull() }
val dbHost = env<String>("DB_HOST")
val dbUsername = env<String>("DB_USERNAME")
val dbPassword = env<String>("DB_PASSWORD", "password")

val dashboardEnabled = env("DASHBOARD", "true") { it.toBooleanStrictOrNull() }
val dashboardUser = env<String>("DASHBOARD_USER", "admin")
val dashboardPassword = env<String>("DASHBOARD_PASS", "admin")
val dashboardEnabled = env("DASHBOARD", "true") { it.toBooleanStrictOrNull() }
val dashboardUser = env<String>("DASHBOARD_USER", "admin")
val dashboardPassword = env<String>("DASHBOARD_PASS", "admin")

val firebaseAuthCredential =
env("FIREBASE_ADMIN_AUTH_CREDENTIALS") {
Base64.getDecoder().decode(it).decodeToString()
}
val firebaseAuthCredential =
env("FIREBASE_ADMIN_AUTH_CREDENTIALS") {
Base64.getDecoder().decode(it).decodeToString()
}

val forexApiKey = env<String>("FOREX_API_KEY")
val forexApiKey = env<String>("FOREX_API_KEY")

if (violations.isNotEmpty()) {
throw BootstrapException(violations)
} else {
Conf(
api = Conf.Api(appPort!!, cors = cors!!),
environment = environment!!,
db =
Conf.DB(
host = dbHost!!,
port = dbPort!!,
name = dbName!!,
username = dbUsername!!,
password = dbPassword!!,
poolSize = dbPoolSize!!,
),
backgroundTask =
Conf.BackgroundTask(
dashboardEnabled = dashboardEnabled!!,
dashboardUserName = dashboardUser!!,
dashboardPassword = dashboardPassword!!,
),
firebaseAuthCredential = firebaseAuthCredential!!,
forexApiKey = forexApiKey!!,
)
}
if (violations.isNotEmpty()) {
throw BootstrapException(violations)
} else {
Conf(
api = Conf.Api(appPort!!, cors = cors!!),
environment = environment!!,
db =
Conf.DB(
host = dbHost!!,
port = dbPort!!,
name = dbName!!,
username = dbUsername!!,
password = dbPassword!!,
poolSize = dbPoolSize!!,
),
backgroundTask =
Conf.BackgroundTask(
dashboardEnabled = dashboardEnabled!!,
dashboardUserName = dashboardUser!!,
dashboardPassword = dashboardPassword!!,
),
firebaseAuthCredential = firebaseAuthCredential!!,
forexApiKey = forexApiKey!!,
)
}
}
11 changes: 5 additions & 6 deletions backend/src/main/kotlin/me/sujanpoudel/playdeals/common/Enums.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package me.sujanpoudel.playdeals.common

inline fun <reified T : Enum<T>> String.asEnum() = enumValueOf<T>(this)

inline fun <reified T : Enum<T>> String.asEnumOrNull() =
try {
asEnum<T>()
} catch (e: Exception) {
null
}
inline fun <reified T : Enum<T>> String.asEnumOrNull() = try {
asEnum<T>()
} catch (e: Exception) {
null
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import me.sujanpoudel.playdeals.logger
import kotlin.time.DurationUnit
import kotlin.time.measureTimedValue

inline fun <T> loggingExecutionTime(
message: String,
action: () -> T,
): T {
inline fun <T> loggingExecutionTime(message: String, action: () -> T): T {
val timedValue =
measureTimedValue {
action.invoke()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,10 @@ fun Route.coHandler(fn: suspend (RoutingContext) -> Unit): Route {

fun HttpServerResponse.contentType(value: String): HttpServerResponse = putHeader("Content-Type", value)

fun <T> jsonResponse(
message: String = "Success",
data: T? = null,
): JsonObject =
jsonObjectOf(
"message" to message,
"data" to data,
)
fun <T> jsonResponse(message: String = "Success", data: T? = null): JsonObject = jsonObjectOf(
"message" to message,
"data" to data,
)

const val UNKNOWN_ERROR_MESSAGE = "Something went wrong"

Expand Down
Loading

0 comments on commit bd440db

Please sign in to comment.