-
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.
Feat: add
Reaktoro
integration (#11)
* feat(all): integrate ReactionService & fix comments * feat(tests): fix tests using service integration * feat(reaktoro): add Reaktoro service & redo arch (separation of concerns) * fix(preprocessor): fix JSON decoding issue & improve services' pipelines * feat(env): create .env example * feat(reaktoro): integrate Reaktoro service & fix tests * fix(docker): add repositories explicitly * fix(reaktoro): include routes into the Main & fix tests
- Loading branch information
1 parent
85d87c3
commit 30d9191
Showing
36 changed files
with
1,167 additions
and
444 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 |
---|---|---|
|
@@ -20,7 +20,7 @@ RUN sbt update | |
|
||
COPY src/ ./src/ | ||
|
||
RUN sbt compile | ||
RUN sbt clean compile | ||
|
||
COPY . . | ||
|
||
|
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
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,13 @@ | ||
AKKA_LICENSE_KEY=... | ||
|
||
CHEMIST_FLOW_HOST=localhost | ||
CHEMIST_FLOW_PORT=8081 | ||
|
||
POSTGRE_URL=jdbc:postgresql://localhost:5432/chemist_db | ||
POSTGRE_USER=chemist | ||
POSTGRE_PASSWORD=chemist_password | ||
POSTGRE_DRIVER=org.postgresql.Driver | ||
|
||
CHEMIST_PREPROCESSOR_BASE_URI=http://localhost:8080 | ||
|
||
CHEMIST_ENGINE_BASE_URI=http://localhost:8082 |
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,4 +1,11 @@ | ||
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0") | ||
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.10.4") | ||
addSbtPlugin("org.http4s" % "sbt-http4s-org" % "0.17.5") | ||
resolvers += "Scalafmt Releases" at "https://oss.sonatype.org/content/repositories/releases" | ||
|
||
resolvers ++= Seq( | ||
"Scalafmt Releases" at "https://oss.sonatype.org/content/repositories/releases", | ||
"Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases", | ||
"Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/", | ||
"Maven Central" at "https://repo1.maven.org/maven2/", | ||
"Akka repository" at "https://repo.akka.io/maven" | ||
) |
This file was deleted.
Oops, something went wrong.
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
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,54 @@ | ||
package api.endpoints.flow | ||
|
||
import cats.effect.IO | ||
|
||
import org.http4s.HttpRoutes | ||
import org.http4s.dsl.io._ | ||
import org.http4s.server.Router | ||
import org.http4s.server.middleware.Logger | ||
import org.http4s.circe.CirceEntityEncoder.circeEntityEncoder | ||
import org.http4s.circe.CirceSensitiveDataEntityDecoder.circeEntityDecoder | ||
|
||
import io.circe.syntax._ | ||
import io.circe.generic.auto.deriveEncoder | ||
|
||
import core.services.flow.ReaktoroService | ||
import core.domain.preprocessor.ReactionId | ||
import core.domain.flow.{DataBase, MoleculeAmountList} | ||
|
||
case class ComputePropsRequest( | ||
reactionId: ReactionId, | ||
database: DataBase, | ||
amounts: MoleculeAmountList | ||
) | ||
|
||
object ComputePropsRequest { | ||
import io.circe.{Decoder, Encoder} | ||
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder} | ||
|
||
implicit val decoder: Decoder[ComputePropsRequest] = deriveDecoder | ||
implicit val encoder: Encoder[ComputePropsRequest] = deriveEncoder | ||
} | ||
|
||
class ReaktoroEndpoints( | ||
reaktoroService: ReaktoroService[IO] | ||
) { | ||
|
||
private val computeSystemPropsForReactionRoute: HttpRoutes[IO] = HttpRoutes.of[IO] { | ||
case req @ POST -> Root / "system" / "properties" => | ||
req.as[ComputePropsRequest].flatMap { | ||
case ComputePropsRequest(reactionId, database, amounts) => | ||
reaktoroService | ||
.computeSystemPropsForReaction(reactionId, database, amounts) | ||
.flatMap(result => Ok(result.asJson)) | ||
.handleErrorWith(ex => InternalServerError(("InternalError", ex.getMessage).asJson)) | ||
} | ||
} | ||
|
||
val routes: HttpRoutes[IO] = Logger.httpRoutes(logHeaders = true, logBody = true)( | ||
Router( | ||
"/api" -> computeSystemPropsForReactionRoute | ||
) | ||
) | ||
|
||
} |
84 changes: 84 additions & 0 deletions
84
src/main/scala/api/endpoints/preprocessor/PreprocessorEndpoints.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,84 @@ | ||
package api.endpoints.preprocessor | ||
|
||
import cats.effect.IO | ||
import cats.syntax.semigroupk.toSemigroupKOps | ||
|
||
import io.circe.syntax.EncoderOps | ||
|
||
import org.http4s.HttpRoutes | ||
import org.http4s.dsl.io._ | ||
import org.http4s.server.Router | ||
import org.http4s.server.middleware.Logger | ||
import org.http4s.circe.CirceEntityEncoder.circeEntityEncoder | ||
import org.http4s.circe.CirceSensitiveDataEntityDecoder.circeEntityDecoder | ||
|
||
import core.services.preprocessor.{MechanismService, ReactionService} | ||
import core.domain.preprocessor.{MechanismDetails, Reaction, ReactionDetails} | ||
import core.errors.http.preprocessor.ReactionError | ||
|
||
class PreprocessorEndpoints( | ||
reactionService: ReactionService[IO], | ||
mechanismService: MechanismService[IO] | ||
) { | ||
|
||
private val getReactionRoute: HttpRoutes[IO] = HttpRoutes.of[IO] { | ||
case GET -> Root / "reaction" / id => | ||
validateId(id) match { | ||
case Some(validId) => | ||
reactionService.getReaction(validId).flatMap { | ||
(reactionDetails: ReactionDetails) => Ok(reactionDetails.asJson) | ||
}.handleErrorWith { | ||
case _: ReactionError.NotFoundError => NotFound(("NotFound", s"Reaction with ID $validId not found")) | ||
case ex => InternalServerError(("InternalError", ex.getMessage)) | ||
} | ||
case None => BadRequest(("BadRequest", "ID must be an integer")) | ||
} | ||
} | ||
|
||
private val postReactionRoute: HttpRoutes[IO] = HttpRoutes.of[IO] { | ||
case req @ POST -> Root / "reaction" => | ||
req.as[Reaction].flatMap { reaction => | ||
reactionService.createReaction(reaction).flatMap { | ||
createdReaction => Created(createdReaction.asJson) | ||
}.handleErrorWith { | ||
case _: ReactionError.CreationError => BadRequest(("CreationError", "Failed to create reaction")) | ||
case ex => InternalServerError(("InternalError", ex.getMessage)) | ||
} | ||
} | ||
} | ||
|
||
private val deleteReactionRoute: HttpRoutes[IO] = HttpRoutes.of[IO] { | ||
case DELETE -> Root / "reaction" / id => | ||
validateId(id) match { | ||
case Some(validId) => | ||
reactionService.deleteReaction(validId).flatMap { | ||
case Right(_) => NoContent() | ||
case Left(error) => BadRequest(("DeletionError", error.message)) | ||
} | ||
case None => BadRequest(("BadRequest", "ID must be an integer")) | ||
} | ||
} | ||
|
||
private val getMechanismRoute: HttpRoutes[IO] = HttpRoutes.of[IO] { | ||
case GET -> Root / "mechanism" / id => | ||
validateId(id) match { | ||
case Some(validId) => | ||
mechanismService.getMechanism(validId).flatMap { | ||
(mechanismDetails: MechanismDetails) => Ok(mechanismDetails.asJson) | ||
}.handleErrorWith { | ||
case _: ReactionError.NotFoundError => NotFound(("NotFound", s"Mechanism with ID $validId not found")) | ||
case ex => InternalServerError(("InternalError", ex.getMessage)) | ||
} | ||
case None => BadRequest(("BadRequest", "ID must be an integer")) | ||
} | ||
} | ||
|
||
private def validateId(id: String): Option[Int] = id.toIntOption | ||
|
||
val routes: HttpRoutes[IO] = Logger.httpRoutes(logHeaders = false, logBody = true)( | ||
Router( | ||
"/api" -> (getReactionRoute <+> postReactionRoute <+> deleteReactionRoute <+> getMechanismRoute) | ||
) | ||
) | ||
|
||
} |
Oops, something went wrong.