-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from mmvpm/stub
Add stub
- Loading branch information
Showing
33 changed files
with
679 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
name: Build and run tests | ||
|
||
on: | ||
push: | ||
branches: | ||
- '*' | ||
pull_request: | ||
branches: | ||
- '*' | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Set up JDK 11 | ||
uses: actions/setup-java@v3 | ||
with: | ||
java-version: '11' | ||
distribution: 'temurin' | ||
cache: 'sbt' | ||
- name: Build | ||
run: sbt scalafmtSbtCheck scalafmtCheckAll compile | ||
- name: Run stub tests | ||
run: sbt stub/test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
*.class | ||
*.log | ||
|
||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml | ||
hs_err_pid* | ||
.idea | ||
target | ||
project/target | ||
.bsp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
version = 3.0.3 | ||
|
||
runner.dialect = scala213 | ||
|
||
style = default | ||
|
||
maxColumn = 120 | ||
|
||
trailingCommas = never | ||
|
||
rewrite.rules = [ | ||
AvoidInfix | ||
RedundantBraces | ||
RedundantParens | ||
AsciiSortImports | ||
PreferCurlyFors | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,11 @@ | ||
# OffersService | ||
# OffersService | ||
|
||
## How to launch | ||
|
||
```bash | ||
docker compose start | ||
``` | ||
|
||
```bash | ||
sbt "project stub" run | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
addCompilerPlugin(("org.typelevel" % "kind-projector" % "0.13.2").cross(CrossVersion.full)) | ||
|
||
ThisBuild / version := "0.1.0-SNAPSHOT" | ||
|
||
ThisBuild / scalaVersion := "2.13.12" | ||
|
||
val catsVersion = "2.9.0" | ||
val catsEffect3 = "3.4.8" | ||
val circeVersion = "0.14.6" | ||
val tapirVersion = "1.7.6" | ||
val tapirCirce = "1.9.5" | ||
val http4sVersion = "0.23.23" | ||
val logbackVersion = "1.4.11" | ||
val apacheCommonsVersion = "1.16.0" | ||
val pureConfigVersion = "0.17.4" | ||
val flywayVersion = "9.16.0" | ||
val doobieVersion = "1.0.0-RC2" | ||
val quillVersion = "4.6.0" | ||
val redisVersion = "3.42" | ||
val scrapperVersion = "3.0.0" | ||
val sttpClientVersion = "3.9.0" | ||
val catsRetryVersion = "3.1.0" | ||
val catsBackendVersion = "3.8.13" | ||
|
||
val testVersion = "1.4.0" | ||
val scalatestVersion = "3.2.17" | ||
val mockitoVersion = "3.2.16.0" | ||
val wireMockVersion = "3.0.0" | ||
val catsTestingVersion = "1.4.0" | ||
val testcontainersVersion = "0.40.15" | ||
val testcontainersRedis = "1.3.2" | ||
val testcontainersPostgresqlVersion = "0.40.12" | ||
|
||
val cats = Seq( | ||
"org.typelevel" %% "cats-core" % catsVersion, | ||
"org.typelevel" %% "cats-effect" % catsEffect3 | ||
) | ||
|
||
val circe = Seq( | ||
"io.circe" %% "circe-core" % circeVersion, | ||
"io.circe" %% "circe-generic" % circeVersion, | ||
"io.circe" %% "circe-parser" % circeVersion | ||
) | ||
|
||
val pureconfig = Seq( | ||
"com.github.pureconfig" %% "pureconfig" % pureConfigVersion | ||
) | ||
|
||
val redis = Seq( | ||
"net.debasishg" %% "redisclient" % redisVersion | ||
) | ||
|
||
val tapir = Seq( | ||
"com.softwaremill.sttp.tapir" %% "tapir-http4s-server" % tapirVersion, | ||
"com.softwaremill.sttp.tapir" %% "tapir-swagger-ui-bundle" % tapirVersion, | ||
"com.softwaremill.sttp.tapir" %% "tapir-json-circe" % tapirCirce | ||
) | ||
|
||
val http4s = Seq( | ||
"org.http4s" %% "http4s-ember-server" % http4sVersion | ||
) | ||
|
||
val logback = Seq( | ||
"ch.qos.logback" % "logback-classic" % logbackVersion | ||
) | ||
|
||
val apacheCommons = Seq( | ||
"commons-codec" % "commons-codec" % apacheCommonsVersion | ||
) | ||
|
||
val databases = Seq( | ||
"org.tpolecat" %% "doobie-core" % doobieVersion, | ||
"org.tpolecat" %% "doobie-postgres" % doobieVersion, | ||
"org.tpolecat" %% "doobie-hikari" % doobieVersion, | ||
"org.flywaydb" % "flyway-core" % flywayVersion | ||
) | ||
|
||
val sttpClient = Seq( | ||
"com.softwaremill.sttp.client3" %% "core" % sttpClientVersion, | ||
"com.softwaremill.sttp.client3" %% "circe" % sttpClientVersion, | ||
"com.softwaremill.sttp.client3" %% "async-http-client-backend-cats" % catsBackendVersion | ||
) | ||
|
||
val catsRetry = Seq( | ||
"com.github.cb372" %% "cats-retry" % catsRetryVersion | ||
) | ||
|
||
val scrapper = Seq( | ||
"net.ruippeixotog" %% "scala-scraper" % scrapperVersion | ||
) | ||
|
||
val testcontainers = Seq( | ||
"com.redislabs.testcontainers" % "testcontainers-redis" % testcontainersRedis, | ||
"com.dimafeng" %% "testcontainers-scala-scalatest" % testcontainersVersion, | ||
"com.dimafeng" %% "testcontainers-scala-postgresql" % testcontainersPostgresqlVersion | ||
) | ||
|
||
val scalatest = Seq( | ||
"org.scalatest" %% "scalatest" % scalatestVersion % Test | ||
) | ||
|
||
val mockito = Seq( | ||
"org.scalatestplus" %% "mockito-4-11" % mockitoVersion % Test | ||
) | ||
|
||
val catsTesting = Seq( | ||
"org.typelevel" %% "cats-effect-testing-scalatest" % catsTestingVersion % Test | ||
) | ||
|
||
val tapirStubServer = Seq( | ||
"com.softwaremill.sttp.tapir" %% "tapir-sttp-stub-server" % tapirVersion % Test | ||
) | ||
|
||
lazy val common = (project in file("common")) | ||
.settings( | ||
name := "common" | ||
) | ||
|
||
lazy val stub = (project in file("stub")) | ||
.dependsOn(common) | ||
.settings( | ||
name := "stub", | ||
libraryDependencies ++= Seq( | ||
cats, | ||
logback, | ||
pureconfig, | ||
tapir, | ||
http4s, | ||
databases | ||
).flatten | ||
) | ||
|
||
lazy val root = (project in file(".")) | ||
.settings( | ||
name := "OffersService" | ||
) | ||
.aggregate(common, stub) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package com.github.mmvpm.model | ||
|
||
case class Stub(id: StubID, data: String) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.github.mmvpm | ||
|
||
import java.util.UUID | ||
|
||
package object model { | ||
type StubID = UUID | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
version: '3.8' | ||
|
||
services: | ||
db: | ||
image: postgres:14.1-alpine | ||
restart: always | ||
environment: | ||
- POSTGRES_USER=postgres | ||
- POSTGRES_PASSWORD=postgres | ||
ports: | ||
- '5432:5432' | ||
volumes: | ||
- db:/var/lib/postgresql/data | ||
|
||
volumes: | ||
db: | ||
driver: local |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
sbt.version=1.8.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.1.0") | ||
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") | ||
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.0.9") | ||
addCompilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1") | ||
addCompilerPlugin(("org.scalamacros" % "paradise" % "2.1.1").cross(CrossVersion.full)) | ||
addCompilerPlugin(("org.typelevel" % "kind-projector" % "0.13.2").cross(CrossVersion.full)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
server { | ||
host = localhost | ||
port = 8080 | ||
} | ||
|
||
postgresql { | ||
url = "jdbc:postgresql://localhost:5432/postgres" | ||
user = "postgres" | ||
password = "postgres" | ||
pool-size = 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
create table stubs | ||
( | ||
id uuid primary key, | ||
data text | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.github.mmvpm.stub | ||
|
||
case class Config(server: ServerConfig, postgresql: PostgresqlConfig) | ||
|
||
case class ServerConfig(host: String, port: Int) | ||
|
||
case class PostgresqlConfig(url: String, user: String, password: String, poolSize: Int) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package com.github.mmvpm.stub | ||
|
||
import cats.data.EitherT | ||
import cats.effect.{ExitCode, IO, IOApp} | ||
import cats.implicits.catsSyntaxApplicativeError | ||
import com.comcast.ip4s.{Host, Port} | ||
import com.github.mmvpm.stub.api._ | ||
import com.github.mmvpm.stub.dao._ | ||
import com.github.mmvpm.stub.service._ | ||
import com.github.mmvpm.stub.util.FlywayMigration | ||
import com.github.mmvpm.stub.util.Postgresql.makeTransactor | ||
import doobie.Transactor | ||
import org.http4s.ember.server.EmberServerBuilder | ||
import org.http4s.server.Router | ||
import org.http4s.HttpRoutes | ||
import pureconfig.ConfigSource | ||
import pureconfig.generic.auto._ | ||
import sttp.tapir.server.http4s.Http4sServerInterpreter | ||
import sttp.tapir.server.ServerEndpoint | ||
import sttp.tapir.swagger.bundle.SwaggerInterpreter | ||
|
||
object Main extends IOApp { | ||
|
||
override def run(args: List[String]): IO[ExitCode] = { | ||
val config = ConfigSource.default.loadOrThrow[Config] | ||
makeTransactor[IO](config.postgresql).use(runServer(config)(_)) | ||
} | ||
|
||
private def runServer(config: Config)(implicit xa: Transactor[IO]): IO[ExitCode] = | ||
for { | ||
_ <- IO.pure(0) | ||
|
||
pingHandler: PingHandler[IO] = new PingHandler[IO] | ||
|
||
stubDao: StubDao[IO] = new StubDaoPostgresql[IO] | ||
stubService: StubService[IO] = new StubServiceImpl[IO](stubDao) | ||
stubHandler: StubHandler[IO] = new StubHandler[IO](stubService) | ||
|
||
handlers = List(pingHandler, stubHandler) | ||
endpoints <- IO.delay(handlers.flatMap(_.endpoints)) | ||
routes = Http4sServerInterpreter[IO].toRoutes(swaggerBy(endpoints) ++ endpoints) | ||
server <- serverBuilder(config, routes).value.rethrow | ||
|
||
_ <- FlywayMigration.migrate[IO](config.postgresql) | ||
|
||
_ <- server.build.use { server => | ||
val (host, port) = (server.address.getHostName, server.address.getPort) | ||
IO.println(s"SwaggerUI: http://$host:$port/docs") >> IO.never | ||
} | ||
} yield ExitCode.Success | ||
|
||
private def serverBuilder(config: Config, routes: HttpRoutes[IO]): EitherT[IO, Throwable, EmberServerBuilder[IO]] = | ||
for { | ||
host <- parseHost(config.server.host) | ||
port <- parsePort(config.server.port) | ||
builder <- IO.delay { | ||
EmberServerBuilder | ||
.default[IO] | ||
.withHost(host) | ||
.withPort(port) | ||
.withHttpApp( | ||
Router("/" -> routes).orNotFound | ||
) | ||
}.attemptT | ||
} yield builder | ||
|
||
private def parseHost(host: String): EitherT[IO, Throwable, Host] = | ||
EitherT.fromOption[IO](Host.fromString(host), new IllegalArgumentException(s"incorrect host '$host'")) | ||
|
||
private def parsePort(port: Int): EitherT[IO, Throwable, Port] = | ||
EitherT.fromOption[IO](Port.fromInt(port), new IllegalArgumentException(s"incorrect port '$port'")) | ||
|
||
private def swaggerBy[A](endpoints: List[ServerEndpoint[A, IO]]): List[ServerEndpoint[A, IO]] = | ||
SwaggerInterpreter().fromServerEndpoints[IO](endpoints, "offers-service", "1.0.0") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.github.mmvpm.stub.api | ||
|
||
import sttp.tapir.server.ServerEndpoint | ||
|
||
trait Handler[F[_]] { | ||
def endpoints: List[ServerEndpoint[Any, F]] | ||
} |
17 changes: 17 additions & 0 deletions
17
stub/src/main/scala/com/github/mmvpm/stub/api/PingHandler.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.github.mmvpm.stub.api | ||
import cats.Applicative | ||
import sttp.tapir._ | ||
import sttp.tapir.server.ServerEndpoint | ||
|
||
class PingHandler[F[_]: Applicative] extends Handler[F] { | ||
|
||
private val ping: ServerEndpoint[Any, F] = | ||
endpoint.get | ||
.summary("Ping") | ||
.in("api" / "v1" / "ping") | ||
.out(stringBody) | ||
.serverLogic(_ => Applicative[F].pure(Right("pong"))) | ||
|
||
override def endpoints: List[ServerEndpoint[Any, F]] = | ||
List(ping).map(_.withTag("util")) | ||
} |
Oops, something went wrong.