diff --git a/obp-api/pom.xml b/obp-api/pom.xml index 0a1501d84..a9eaadb93 100644 --- a/obp-api/pom.xml +++ b/obp-api/pom.xml @@ -84,6 +84,16 @@ bcpg-jdk15on 1.70 + + org.http4s + http4s-ember-server_${scala.version} + ${http4s.version} + + + org.http4s + http4s-dsl_${scala.version} + ${http4s.version} + org.bouncycastle bcpkix-jdk15on diff --git a/obp-api/src/main/scala/bootstrap/http4s/Http4sServer.scala b/obp-api/src/main/scala/bootstrap/http4s/Http4sServer.scala new file mode 100644 index 000000000..812e5c488 --- /dev/null +++ b/obp-api/src/main/scala/bootstrap/http4s/Http4sServer.scala @@ -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() +} + diff --git a/obp-api/src/main/scala/bootstrap/http4s/Middleware.scala b/obp-api/src/main/scala/bootstrap/http4s/Middleware.scala new file mode 100644 index 000000000..777cdf317 --- /dev/null +++ b/obp-api/src/main/scala/bootstrap/http4s/Middleware.scala @@ -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) +// +//} diff --git a/obp-api/src/main/scala/bootstrap/http4s/RestRoutes.scala b/obp-api/src/main/scala/bootstrap/http4s/RestRoutes.scala new file mode 100644 index 000000000..4262f95a3 --- /dev/null +++ b/obp-api/src/main/scala/bootstrap/http4s/RestRoutes.scala @@ -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))) + } + +} \ No newline at end of file diff --git a/obp-api/src/main/scala/code/api/v1_3_0/Http4s130.scala b/obp-api/src/main/scala/code/api/v1_3_0/Http4s130.scala new file mode 100644 index 000000000..f1279c0f2 --- /dev/null +++ b/obp-api/src/main/scala/code/api/v1_3_0/Http4s130.scala @@ -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) +} diff --git a/pom.xml b/pom.xml index 2d8cadc37..52827eb8a 100644 --- a/pom.xml +++ b/pom.xml @@ -15,6 +15,7 @@ 2.5.32 1.8.2 3.5.0 + 0.23.30 9.4.50.v20221201 2016.11-RC6-SNAPSHOT @@ -126,7 +127,7 @@ net.alchim31.maven scala-maven-plugin - 4.3.1 + 4.8.1 ${scala.compiler} ${project.build.sourceEncoding} @@ -143,6 +144,7 @@ -verbose -deprecation --> + -Ypartial-unification