mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 13:26:51 +00:00
Refactor/Http4sServer to use v7.0.0 API and remove deprecated routes. Introduce new JSONFactory for v7.0.0 and update server configuration to use dynamic host and port settings. Clean up unused Middleware and RestRoutes files.
This commit is contained in:
parent
2ae58966c5
commit
a8f16a87f2
@ -1,6 +1,5 @@
|
||||
package bootstrap.http4s
|
||||
|
||||
import bootstrap.http4s.RestRoutes.{bankServices, helloWorldService}
|
||||
import cats.data.{Kleisli, OptionT}
|
||||
|
||||
import scala.language.higherKinds
|
||||
@ -9,33 +8,29 @@ import com.comcast.ip4s._
|
||||
import org.http4s.ember.server._
|
||||
import org.http4s.implicits._
|
||||
import cats.effect._
|
||||
import code.api.util.APIUtil
|
||||
import org.http4s._
|
||||
object Http4sServer extends IOApp {
|
||||
|
||||
val services: Kleisli[({type λ[β$0$] = OptionT[IO, β$0$]})#λ, Request[IO], Response[IO]] =
|
||||
bankServices <+>
|
||||
helloWorldService <+>
|
||||
code.api.v1_3_0.Http4s130.wrappedRoutesV130Services
|
||||
code.api.v7_0_0.Http4s700.wrappedRoutesV700Services
|
||||
|
||||
val httpApp: Kleisli[IO, Request[IO], Response[IO]] = (services).orNotFound
|
||||
|
||||
//Start OBP relevant objects, and settings
|
||||
new bootstrap.liftweb.Boot().boot
|
||||
|
||||
val port = APIUtil.getPropsAsIntValue("http4s.port",8181)
|
||||
val host = APIUtil.getPropsValue("http4s.host","127.0.0.1")
|
||||
|
||||
|
||||
override def run(args: List[String]): IO[ExitCode] = EmberServerBuilder
|
||||
.default[IO]
|
||||
.withHost(ipv4"0.0.0.0")
|
||||
.withPort(port"8081")
|
||||
.withHost(Host.fromString(host).get)
|
||||
.withPort(Port.fromInt(port).get)
|
||||
.withHttpApp(httpApp)
|
||||
.build
|
||||
.use(_ => IO.never)
|
||||
.as(ExitCode.Success)
|
||||
}
|
||||
|
||||
//this is testing code
|
||||
object myApp extends App{
|
||||
import cats.effect.unsafe.implicits.global
|
||||
Http4sServer.run(Nil).unsafeRunSync()
|
||||
// Http4sServer.run(Nil).unsafeToFuture()//.unsafeRunSync()
|
||||
}
|
||||
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
//package bootstrap.http4s
|
||||
//
|
||||
//import cats._
|
||||
//import cats.effect._
|
||||
//import cats.implicits._
|
||||
//import cats.data._
|
||||
//import code.api.util.CallContext
|
||||
//import org.http4s._
|
||||
//import org.http4s.dsl.io._
|
||||
//import org.http4s.server._
|
||||
//
|
||||
//object Middleware {
|
||||
//
|
||||
// val authUser: Kleisli[OptionT[IO, *], Request[IO], CallContext] =
|
||||
// Kleisli(_ => OptionT.liftF(IO(???)))
|
||||
//
|
||||
// val middleware: AuthMiddleware[IO, CallContext] = AuthMiddleware(authUser)
|
||||
//
|
||||
// val authedRoutes: AuthedRoutes[CallContext, IO] =
|
||||
// AuthedRoutes.of {
|
||||
// case GET -> Root / "welcome" as callContext => Ok(s"Welcome, ${callContext}")
|
||||
// }
|
||||
//
|
||||
// val service: HttpRoutes[IO] = middleware(authedRoutes)
|
||||
//
|
||||
//}
|
||||
@ -1,62 +0,0 @@
|
||||
package bootstrap.http4s
|
||||
|
||||
import cats.effect._
|
||||
import org.http4s.{HttpRoutes, _}
|
||||
import org.http4s.dsl.io._
|
||||
import cats.implicits._
|
||||
import code.api.util.{APIUtil, CustomJsonFormats}
|
||||
import code.bankconnectors.Connector
|
||||
import code.model.dataAccess.MappedBank
|
||||
import com.openbankproject.commons.model.BankCommons
|
||||
import net.liftweb.json.Formats
|
||||
import org.http4s.HttpRoutes
|
||||
import org.http4s.dsl.Http4sDsl
|
||||
|
||||
import scala.language.higherKinds
|
||||
import cats.effect._
|
||||
import code.api.v4_0_0.JSONFactory400
|
||||
import org.http4s._
|
||||
import org.http4s.dsl.io._
|
||||
import net.liftweb.json.JsonAST.{JValue, prettyRender}
|
||||
import net.liftweb.json.{Extraction, MappingException, compactRender, parse}
|
||||
|
||||
object RestRoutes {
|
||||
implicit val formats: Formats = CustomJsonFormats.formats
|
||||
|
||||
val helloWorldService: HttpRoutes[IO] = HttpRoutes.of[IO] {
|
||||
case GET -> Root / "hello" / name =>
|
||||
Ok(s"Hello, $name.")
|
||||
}
|
||||
|
||||
val bankServices: HttpRoutes[IO] = HttpRoutes.of[IO] {
|
||||
case GET -> Root / "banks" =>
|
||||
val banks = Connector.connector.vend.getBanksLegacy(None).map(_._1).openOrThrowException("xxxxx")
|
||||
Ok(prettyRender(Extraction.decompose(banks)))
|
||||
case GET -> Root / "banks"/ "future" =>
|
||||
import scala.concurrent.Future
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
Ok(IO.fromFuture(IO(
|
||||
for {
|
||||
(banks, callContext) <- code.api.util.NewStyle.function.getBanks(None)
|
||||
} yield {
|
||||
prettyRender(Extraction.decompose(JSONFactory400.createBanksJson(banks)))
|
||||
}
|
||||
)))
|
||||
|
||||
val banks = Connector.connector.vend.getBanksLegacy(None).map(_._1).openOrThrowException("xxxxx")
|
||||
Ok(prettyRender(Extraction.decompose(banks)))
|
||||
case GET -> Root / "banks" / IntVar(bankId) =>
|
||||
val bank = BankCommons(
|
||||
bankId = com.openbankproject.commons.model.BankId("bankIdExample.value"),
|
||||
shortName = "bankShortNameExample.value",
|
||||
fullName = "bankFullNameExample.value",
|
||||
logoUrl = "bankLogoUrlExample.value",
|
||||
websiteUrl = "bankWebsiteUrlExample.value",
|
||||
bankRoutingScheme = "bankRoutingSchemeExample.value",
|
||||
bankRoutingAddress = "bankRoutingAddressExample.value",
|
||||
swiftBic = "bankSwiftBicExample.value",
|
||||
nationalIdentifier = "bankNationalIdentifierExample.value")
|
||||
Ok(prettyRender(Extraction.decompose(bank)))
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,105 +0,0 @@
|
||||
package code.api.v1_3_0
|
||||
|
||||
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.FutureUtil.EndpointContext
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.api.util.{ApiRole, NewStyle}
|
||||
import code.api.v1_2_1.JSONFactory
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import com.openbankproject.commons.model.BankId
|
||||
import com.openbankproject.commons.util.{ApiVersion, ScannedApiVersion}
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.concurrent.Future
|
||||
import cats.effect._
|
||||
import org.http4s.{HttpRoutes, _}
|
||||
import org.http4s.dsl.io._
|
||||
import cats.implicits._
|
||||
import code.api.util.{APIUtil, CustomJsonFormats}
|
||||
import code.bankconnectors.Connector
|
||||
import code.model.dataAccess.MappedBank
|
||||
import com.openbankproject.commons.model.BankCommons
|
||||
import net.liftweb.json.Formats
|
||||
import org.http4s.HttpRoutes
|
||||
import org.http4s.dsl.Http4sDsl
|
||||
|
||||
import scala.language.{higherKinds, implicitConversions}
|
||||
import cats.effect._
|
||||
import code.api.v4_0_0.JSONFactory400
|
||||
import org.http4s._
|
||||
import org.http4s.dsl.io._
|
||||
import net.liftweb.json.JsonAST.{JValue, prettyRender}
|
||||
import net.liftweb.json.{Extraction, MappingException, compactRender, parse}
|
||||
import cats.effect._
|
||||
import cats.data.Kleisli
|
||||
import org.http4s._
|
||||
import org.http4s.dsl.io._
|
||||
import org.http4s.implicits._
|
||||
import org.http4s.ember.server.EmberServerBuilder
|
||||
import com.comcast.ip4s._
|
||||
|
||||
import cats.effect.IO
|
||||
import org.http4s.{HttpRoutes, Request, Response}
|
||||
import org.http4s.dsl.io._
|
||||
import org.typelevel.vault.Key
|
||||
|
||||
object Http4s130 {
|
||||
|
||||
implicit val formats: Formats = CustomJsonFormats.formats
|
||||
implicit def convertAnyToJsonString(any: Any): String = prettyRender(Extraction.decompose(any))
|
||||
|
||||
val apiVersion: ScannedApiVersion = ApiVersion.v1_3_0
|
||||
|
||||
case class CallContext(userId: String, requestId: String)
|
||||
import cats.effect.unsafe.implicits.global
|
||||
val callContextKey: Key[CallContext] = Key.newKey[IO, CallContext].unsafeRunSync()
|
||||
|
||||
object CallContextMiddleware {
|
||||
|
||||
|
||||
def withCallContext(routes: HttpRoutes[IO]): HttpRoutes[IO] = Kleisli { req: Request[IO] =>
|
||||
val callContext = CallContext(userId = "example-user", requestId = java.util.UUID.randomUUID().toString)
|
||||
val updatedAttributes = req.attributes.insert(callContextKey, callContext)
|
||||
val updatedReq = req.withAttributes(updatedAttributes)
|
||||
routes(updatedReq)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val v130Services: HttpRoutes[IO] = HttpRoutes.of[IO] {
|
||||
case req @ GET -> Root / apiVersion / "root" =>
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
val callContext = req.attributes.lookup(callContextKey).get.asInstanceOf[CallContext]
|
||||
Ok(IO.fromFuture(IO(
|
||||
for {
|
||||
_ <- Future() // Just start async call
|
||||
} yield {
|
||||
convertAnyToJsonString(
|
||||
JSONFactory.getApiInfoJSON(OBPAPI1_3_0.version, s"Hello, ${callContext.userId}! Your request ID is ${callContext.requestId}.")
|
||||
)
|
||||
}
|
||||
)))
|
||||
|
||||
// case req @ GET -> Root / apiVersion / "cards" => {
|
||||
// Ok(IO.fromFuture(IO({
|
||||
// val callContext = req.attributes.lookup(callContextKey).get.asInstanceOf[CallContext]
|
||||
// import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
// for {
|
||||
// (Full(u), callContext) <- authenticatedAccess(None)
|
||||
// (cards, callContext) <- NewStyle.function.getPhysicalCardsForUser(u, callContext)
|
||||
// } yield {
|
||||
// convertAnyToJsonString(
|
||||
// JSONFactory1_3_0.createPhysicalCardsJSON(cards, u)
|
||||
// )
|
||||
// }
|
||||
// })))
|
||||
// }
|
||||
}
|
||||
|
||||
val wrappedRoutesV130Services = CallContextMiddleware.withCallContext(v130Services)
|
||||
}
|
||||
69
obp-api/src/main/scala/code/api/v7_0_0/Http4s700.scala
Normal file
69
obp-api/src/main/scala/code/api/v7_0_0/Http4s700.scala
Normal file
@ -0,0 +1,69 @@
|
||||
package code.api.v7_0_0
|
||||
|
||||
import cats.data.Kleisli
|
||||
import cats.effect._
|
||||
import cats.implicits._
|
||||
import code.api.util.{APIUtil, CustomJsonFormats}
|
||||
import code.api.v4_0_0.JSONFactory400
|
||||
import code.bankconnectors.Connector
|
||||
import com.openbankproject.commons.util.{ApiVersion, ScannedApiVersion}
|
||||
import net.liftweb.json.Formats
|
||||
import net.liftweb.json.JsonAST.prettyRender
|
||||
import net.liftweb.json.Extraction
|
||||
import org.http4s._
|
||||
import org.http4s.dsl.io._
|
||||
import org.typelevel.vault.Key
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.language.{higherKinds, implicitConversions}
|
||||
|
||||
object Http4s700 {
|
||||
|
||||
implicit val formats: Formats = CustomJsonFormats.formats
|
||||
implicit def convertAnyToJsonString(any: Any): String = prettyRender(Extraction.decompose(any))
|
||||
|
||||
val apiVersion: ScannedApiVersion = ApiVersion.v7_0_0
|
||||
val apiVersionString: String = apiVersion.toString
|
||||
|
||||
case class CallContext(userId: String, requestId: String)
|
||||
import cats.effect.unsafe.implicits.global
|
||||
val callContextKey: Key[CallContext] = Key.newKey[IO, CallContext].unsafeRunSync()
|
||||
|
||||
object CallContextMiddleware {
|
||||
|
||||
def withCallContext(routes: HttpRoutes[IO]): HttpRoutes[IO] = Kleisli { req: Request[IO] =>
|
||||
val callContext = CallContext(userId = "example-user", requestId = java.util.UUID.randomUUID().toString)
|
||||
val updatedAttributes = req.attributes.insert(callContextKey, callContext)
|
||||
val updatedReq = req.withAttributes(updatedAttributes)
|
||||
routes(updatedReq)
|
||||
}
|
||||
}
|
||||
|
||||
val v700Services: HttpRoutes[IO] = HttpRoutes.of[IO] {
|
||||
case req @ GET -> Root / "obp" / `apiVersionString` / "root" =>
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
val callContext = req.attributes.lookup(callContextKey).get.asInstanceOf[CallContext]
|
||||
Ok(IO.fromFuture(IO(
|
||||
for {
|
||||
_ <- Future() // Just start async call
|
||||
} yield {
|
||||
convertAnyToJsonString(
|
||||
JSONFactory700.getApiInfoJSON(apiVersion, s"Hello, ${callContext.userId}! Your request ID is ${callContext.requestId}.")
|
||||
)
|
||||
}
|
||||
)))
|
||||
|
||||
case req @ GET -> Root / "obp" / `apiVersionString` / "banks" =>
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
Ok(IO.fromFuture(IO(
|
||||
for {
|
||||
(banks, callContext) <- code.api.util.NewStyle.function.getBanks(None)
|
||||
} yield {
|
||||
convertAnyToJsonString(JSONFactory400.createBanksJson(banks))
|
||||
}
|
||||
)))
|
||||
}
|
||||
|
||||
val wrappedRoutesV700Services: HttpRoutes[IO] = CallContextMiddleware.withCallContext(v700Services)
|
||||
}
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
package code.api.v7_0_0
|
||||
|
||||
import code.api.Constant
|
||||
import code.api.util.APIUtil
|
||||
import code.api.util.ErrorMessages.MandatoryPropertyIsNotSet
|
||||
import code.api.v4_0_0.{EnergySource400, HostedAt400, HostedBy400}
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import net.liftweb.util.Props
|
||||
|
||||
object JSONFactory700 extends MdcLoggable {
|
||||
|
||||
// Get git commit from build info
|
||||
lazy val gitCommit: String = {
|
||||
val commit = try {
|
||||
Props.get("git.commit.id", "unknown")
|
||||
} catch {
|
||||
case _: Throwable => "unknown"
|
||||
}
|
||||
commit
|
||||
}
|
||||
|
||||
case class APIInfoJsonV700(
|
||||
version: String,
|
||||
version_status: String,
|
||||
git_commit: String,
|
||||
stage: String,
|
||||
connector: String,
|
||||
hostname: String,
|
||||
local_identity_provider: String,
|
||||
hosted_by: HostedBy400,
|
||||
hosted_at: HostedAt400,
|
||||
energy_source: EnergySource400,
|
||||
resource_docs_requires_role: Boolean,
|
||||
message: String
|
||||
)
|
||||
|
||||
def getApiInfoJSON(apiVersion: ApiVersion, message: String): APIInfoJsonV700 = {
|
||||
val organisation = APIUtil.getPropsValue("hosted_by.organisation", "TESOBE")
|
||||
val email = APIUtil.getPropsValue("hosted_by.email", "contact@tesobe.com")
|
||||
val phone = APIUtil.getPropsValue("hosted_by.phone", "+49 (0)30 8145 3994")
|
||||
val organisationWebsite = APIUtil.getPropsValue("organisation_website", "https://www.tesobe.com")
|
||||
val hostedBy = new HostedBy400(organisation, email, phone, organisationWebsite)
|
||||
|
||||
val organisationHostedAt = APIUtil.getPropsValue("hosted_at.organisation", "")
|
||||
val organisationWebsiteHostedAt = APIUtil.getPropsValue("hosted_at.organisation_website", "")
|
||||
val hostedAt = HostedAt400(organisationHostedAt, organisationWebsiteHostedAt)
|
||||
|
||||
val organisationEnergySource = APIUtil.getPropsValue("energy_source.organisation", "")
|
||||
val organisationWebsiteEnergySource = APIUtil.getPropsValue("energy_source.organisation_website", "")
|
||||
val energySource = EnergySource400(organisationEnergySource, organisationWebsiteEnergySource)
|
||||
|
||||
val connector = code.api.Constant.CONNECTOR.openOrThrowException(s"$MandatoryPropertyIsNotSet. The missing prop is `connector` ")
|
||||
val resourceDocsRequiresRole = APIUtil.getPropsAsBoolValue("resource_docs_requires_role", false)
|
||||
|
||||
APIInfoJsonV700(
|
||||
version = apiVersion.vDottedApiVersion,
|
||||
version_status = "BLEEDING_EDGE",
|
||||
git_commit = gitCommit,
|
||||
connector = connector,
|
||||
hostname = Constant.HostName,
|
||||
stage = System.getProperty("run.mode"),
|
||||
local_identity_provider = Constant.localIdentityProvider,
|
||||
hosted_by = hostedBy,
|
||||
hosted_at = hostedAt,
|
||||
energy_source = energySource,
|
||||
resource_docs_requires_role = resourceDocsRequiresRole,
|
||||
message = message
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ object ApiShortVersions extends Enumeration {
|
||||
val `v5.0.0` = Value("v5.0.0")
|
||||
val `v5.1.0` = Value("v5.1.0")
|
||||
val `v6.0.0` = Value("v6.0.0")
|
||||
val `v7.0.0` = Value("v7.0.0")
|
||||
val `dynamic-endpoint` = Value("dynamic-endpoint")
|
||||
val `dynamic-entity` = Value("dynamic-entity")
|
||||
}
|
||||
@ -114,6 +115,7 @@ object ApiVersion {
|
||||
val v5_0_0 = ScannedApiVersion(urlPrefix,ApiStandards.obp.toString,ApiShortVersions.`v5.0.0`.toString)
|
||||
val v5_1_0 = ScannedApiVersion(urlPrefix,ApiStandards.obp.toString,ApiShortVersions.`v5.1.0`.toString)
|
||||
val v6_0_0 = ScannedApiVersion(urlPrefix,ApiStandards.obp.toString,ApiShortVersions.`v6.0.0`.toString)
|
||||
val v7_0_0 = ScannedApiVersion(urlPrefix,ApiStandards.obp.toString,ApiShortVersions.`v7.0.0`.toString)
|
||||
val `dynamic-endpoint` = ScannedApiVersion(urlPrefix,ApiStandards.obp.toString,ApiShortVersions.`dynamic-endpoint`.toString)
|
||||
val `dynamic-entity` = ScannedApiVersion(urlPrefix,ApiStandards.obp.toString,ApiShortVersions.`dynamic-entity`.toString)
|
||||
|
||||
@ -131,6 +133,7 @@ object ApiVersion {
|
||||
v5_0_0 ::
|
||||
v5_1_0 ::
|
||||
v6_0_0 ::
|
||||
v7_0_0 ::
|
||||
`dynamic-endpoint` ::
|
||||
`dynamic-entity`::
|
||||
Nil
|
||||
|
||||
Loading…
Reference in New Issue
Block a user