Skip to content

Commit

Permalink
Remove modules layer
Browse files Browse the repository at this point in the history
  • Loading branch information
mbore committed Jan 10, 2022
1 parent 4f39182 commit 3271ed7
Show file tree
Hide file tree
Showing 16 changed files with 134 additions and 245 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.softwaremill.bootzooka

import cats.data.NonEmptyList
import cats.effect.{IO, Resource}
import com.softwaremill.bootzooka.config.Config
import com.softwaremill.bootzooka.email.{EmailConfig, EmailModel, EmailService}
import com.softwaremill.bootzooka.email.sender.{DummyEmailSender, EmailSender, MailgunEmailSender, SmtpEmailSender}
import com.softwaremill.bootzooka.http.{Http, HttpApi, HttpConfig}
import com.softwaremill.bootzooka.infrastructure.{DB, DBConfig}
import com.softwaremill.bootzooka.metrics.{MetricsApi, VersionApi}
import com.softwaremill.bootzooka.passwordreset.{PasswordResetApi, PasswordResetAuthToken, PasswordResetCodeModel}
import com.softwaremill.bootzooka.security.{ApiKeyAuthToken, ApiKeyModel}
import com.softwaremill.bootzooka.user.UserApi
import com.softwaremill.bootzooka.util.{Clock, DefaultIdGenerator, IdGenerator}
import com.softwaremill.macwire.autocats.autowire
import doobie.util.transactor.Transactor
import io.prometheus.client.CollectorRegistry
import sttp.client3.SttpBackend

object DependenciesFactory {
private case class Modules(api: HttpApi, emailService: EmailService)

def resource(cfg: Config, sttpBackend: SttpBackend[IO, Any], clock: Clock): Resource[IO, (HttpApi, EmailService)] = {
lazy val collectorRegistry: CollectorRegistry = CollectorRegistry.defaultRegistry
lazy val idGenerator: IdGenerator = DefaultIdGenerator

def buildHttpApi(http: Http, userApi: UserApi, passwordResetApi: PasswordResetApi, metricsApi: MetricsApi, versionApi: VersionApi, collectorRegistry: CollectorRegistry, cfg: HttpConfig) =
new HttpApi(
http,
userApi.endpoints concatNel passwordResetApi.endpoints,
NonEmptyList.of(metricsApi.metricsEndpoint, versionApi.versionEndpoint),
collectorRegistry,
cfg)

def buildApiKeyAuthToken(apiKeyModel: ApiKeyModel): ApiKeyAuthToken = new ApiKeyAuthToken(apiKeyModel)

def buildPasswordResetAuthToken(passwordResetCodeModel: PasswordResetCodeModel): PasswordResetAuthToken = new PasswordResetAuthToken(passwordResetCodeModel)

def buildEmailSender(sttpBackend: SttpBackend[IO, Any], config: EmailConfig): EmailSender = if (config.mailgun.enabled) {
new MailgunEmailSender(config.mailgun, sttpBackend)
} else if (config.smtp.enabled) {
new SmtpEmailSender(config.smtp)
} else {
DummyEmailSender
}

def buildEmailScheduler(emailModel: EmailModel, idGenerator: IdGenerator, emailSender: EmailSender, config: EmailConfig, xa: Transactor[IO]) =
new EmailService(emailModel, idGenerator, emailSender, config, xa)

def buildTransactor(config: DBConfig) = (new DB(config)).transactorResource

autowire[Modules](
cfg.api,
cfg.db,
cfg.user,
cfg.passwordReset,
cfg.email,
idGenerator,
clock,
collectorRegistry,
sttpBackend,
buildHttpApi _,
buildApiKeyAuthToken _,
buildEmailScheduler _,
buildEmailSender _,
buildTransactor _,
buildPasswordResetAuthToken _
).map(modules => (modules.api, modules.emailService))
}
}
17 changes: 0 additions & 17 deletions backend/src/main/scala/com/softwaremill/bootzooka/InitModule.scala

This file was deleted.

50 changes: 31 additions & 19 deletions backend/src/main/scala/com/softwaremill/bootzooka/Main.scala
Original file line number Diff line number Diff line change
@@ -1,46 +1,58 @@
package com.softwaremill.bootzooka

import cats.effect.IO
import cats.data.NonEmptyList
import cats.effect.{IO, Resource}
import cats.effect.unsafe.implicits.global
import com.softwaremill.bootzooka.config.Config
import com.softwaremill.bootzooka.infrastructure.CorrelationId
import com.softwaremill.bootzooka.metrics.Metrics
import com.softwaremill.bootzooka.config.ConfigModule
import com.softwaremill.bootzooka.email.{EmailConfig, EmailModel, EmailService}
import com.softwaremill.bootzooka.email.sender.{DummyEmailSender, EmailSender, MailgunEmailSender, SmtpEmailSender}
import com.softwaremill.bootzooka.http.{Http, HttpApi, HttpConfig}
import com.softwaremill.bootzooka.infrastructure.{CorrelationId, DB, DBConfig, SetCorrelationIdBackend}
import com.softwaremill.bootzooka.metrics.{Metrics, MetricsApi, VersionApi}
import com.softwaremill.bootzooka.passwordreset.{PasswordResetApi, PasswordResetAuthToken, PasswordResetCode, PasswordResetCodeModel}
import com.softwaremill.bootzooka.security.{ApiKey, ApiKeyAuthToken, ApiKeyModel, Auth}
import com.softwaremill.bootzooka.user.UserApi
import com.softwaremill.bootzooka.util.{Clock, DefaultClock, DefaultIdGenerator, IdGenerator}
import com.typesafe.scalalogging.StrictLogging
import doobie.util.transactor
import sttp.client3.SttpBackend
import com.softwaremill.macwire.autocats._
import doobie.util.transactor.Transactor
import io.prometheus.client.CollectorRegistry
import sttp.capabilities.WebSockets
import sttp.capabilities.fs2.Fs2Streams
import sttp.client3.asynchttpclient.fs2.AsyncHttpClientFs2Backend
import sttp.client3.logging.slf4j.Slf4jLoggingBackend
import sttp.client3.prometheus.PrometheusBackend

object Main extends StrictLogging {
def main(args: Array[String]): Unit = {
CorrelationId.init()
Metrics.init()
Thread.setDefaultUncaughtExceptionHandler((t, e) => logger.error("Uncaught exception in thread: " + t, e))

val initModule = new InitModule {}
val configModule = new ConfigModule {}
configModule.logConfig()
val config = configModule.config

initModule.logConfig()
lazy val clock: Clock = DefaultClock

def buildMainModule(_xa: transactor.Transactor[IO], _baseSttpBackend: SttpBackend[IO, Any], _config: Config) = new MainModule {
override def xa: transactor.Transactor[IO] = _xa
override def baseSttpBackend: SttpBackend[IO, Any] = _baseSttpBackend
override def config: Config = _config
}
lazy val sttpBackend: Resource[IO, SetCorrelationIdBackend[Fs2Streams[IO] with WebSockets]] =
AsyncHttpClientFs2Backend.resource[IO]().map(baseSttpBackend => new SetCorrelationIdBackend(
Slf4jLoggingBackend(PrometheusBackend(baseSttpBackend), includeTiming = true)
))

val mainTask = autowire[MainModule](
initModule.db.transactorResource,
initModule.baseSttpBackend,
initModule.config,
buildMainModule _
).use { modules =>
val mainTask = sttpBackend.flatMap(DependenciesFactory.resource(config, _, clock)).use { case (httpApi, emailService) =>
/*
Sequencing two tasks using the >> operator:
- the first starts the background processes (such as an email sender)
- the second allocates the http api resource, and never releases it (so that the http server is available
as long as our application runs)
*/
modules.startBackgroundProcesses >> modules.httpApi.resource.use(_ => IO.never)
emailService.startProcesses().void >> httpApi.resource.use(_ => IO.never)
}

mainTask.unsafeRunSync()
}
}

case class Modules(emailService: EmailService, httpApi: HttpApi)
35 changes: 0 additions & 35 deletions backend/src/main/scala/com/softwaremill/bootzooka/MainModule.scala

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import org.flywaydb.core.Flyway
import scala.concurrent.duration._
import Doobie._
import com.softwaremill.bootzooka.config.Sensitive
import com.softwaremill.macwire.autocats.autowire

import scala.concurrent.ExecutionContext
import com.softwaremill.macwire.autocats._

/** Configures the database, setting up the connection pool and performing migrations.
*/
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 3271ed7

Please sign in to comment.