Merge branch 'feature/AddedHttp4sMerge' into develop

# Conflicts:
#	obp-api/src/main/scala/bootstrap/liftweb/Boot.scala
This commit is contained in:
hongwei 2025-12-05 11:30:45 +01:00
commit 5bb4046123
6 changed files with 247 additions and 1 deletions

View File

@ -84,6 +84,16 @@
<artifactId>bcpg-jdk15on</artifactId>
<version>1.70</version>
</dependency>
<dependency>
<groupId>org.http4s</groupId>
<artifactId>http4s-ember-server_${scala.version}</artifactId>
<version>${http4s.version}</version>
</dependency>
<dependency>
<groupId>org.http4s</groupId>
<artifactId>http4s-dsl_${scala.version}</artifactId>
<version>${http4s.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>

View File

@ -0,0 +1,41 @@
package bootstrap.http4s
import bootstrap.http4s.RestRoutes.{bankServices, helloWorldService}
import cats.data.{Kleisli, OptionT}
import scala.language.higherKinds
import cats.syntax.all._
import com.comcast.ip4s._
import org.http4s.ember.server._
import org.http4s.implicits._
import cats.effect._
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
val httpApp: Kleisli[IO, Request[IO], Response[IO]] = (services).orNotFound
//Start OBP relevant objects, and settings
new bootstrap.liftweb.Boot().boot
override def run(args: List[String]): IO[ExitCode] = EmberServerBuilder
.default[IO]
.withHost(ipv4"0.0.0.0")
.withPort(port"8081")
.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()
}

View File

@ -0,0 +1,26 @@
//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)
//
//}

View File

@ -0,0 +1,62 @@
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)))
}
}

View File

@ -0,0 +1,105 @@
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)
}

View File

@ -15,6 +15,7 @@
<akka.version>2.5.32</akka.version>
<avro.version>1.8.2</avro.version>
<lift.version>3.5.0</lift.version>
<http4s.version>0.23.30</http4s.version>
<jetty.version>9.4.50.v20221201</jetty.version>
<obp-ri.version>2016.11-RC6-SNAPSHOT</obp-ri.version>
<!-- Common plugin settings -->
@ -126,7 +127,7 @@
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>4.3.1</version>
<version>4.8.1</version>
<configuration>
<scalaVersion>${scala.compiler}</scalaVersion>
<charset>${project.build.sourceEncoding}</charset>
@ -143,6 +144,7 @@
<arg>-verbose</arg>
<arg>-deprecation</arg>
-->
<arg>-Ypartial-unification</arg>
</args>
</configuration>
<executions>