org.http4s.server.blaze.BlazeServerBuilder Scala Examples
The following examples show how to use org.http4s.server.blaze.BlazeServerBuilder.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: MockHttpServer.scala From cornichon with Apache License 2.0 | 6 votes |
package com.github.agourlay.cornichon.http.server import java.net.NetworkInterface import com.github.agourlay.cornichon.core.CornichonError import monix.eval.Task import monix.execution.Scheduler import org.http4s.HttpRoutes import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.implicits._ import scala.jdk.CollectionConverters._ import scala.concurrent.duration._ import scala.util.Random class MockHttpServer[A](interface: Option[String], port: Option[Range], mockService: HttpRoutes[Task], maxRetries: Int = 5)(useFromAddress: String => Task[A])(implicit scheduler: Scheduler) { private val selectedInterface = interface.getOrElse(bestInterface()) private val randomPortOrder = port.fold(0 :: Nil)(r => Random.shuffle(r.toList)) private val mockRouter = Router("/" -> mockService).orNotFound def useServer(): Task[A] = if (randomPortOrder.isEmpty) Task.raiseError(MockHttpServerError.toException) else startServerTryPorts(randomPortOrder) private def startServerTryPorts(ports: List[Int], retry: Int = 0): Task[A] = startBlazeServer(ports.head).onErrorHandleWith { case _: java.net.BindException if ports.length > 1 => startServerTryPorts(ports.tail, retry) case _: java.net.BindException if retry < maxRetries => val sleepFor = retry + 1 println(s"Could not start server on any port. Retrying in $sleepFor seconds...") startServerTryPorts(randomPortOrder, retry = retry + 1).delayExecution(sleepFor.seconds) } private def startBlazeServer(port: Int): Task[A] = BlazeServerBuilder[Task](executionContext = scheduler) .bindHttp(port, selectedInterface) .withoutBanner .withHttpApp(mockRouter) .withNio2(true) .resource .use(server => useFromAddress(s"http://${server.address.getHostString}:${server.address.getPort}")) private def bestInterface(): String = NetworkInterface.getNetworkInterfaces.asScala .filter(_.isUp) .flatMap(_.getInetAddresses.asScala) .find(_.isSiteLocalAddress) .map(_.getHostAddress) .getOrElse("localhost") } case object MockHttpServerError extends CornichonError { val baseErrorMessage = "the range of ports provided for the HTTP mock is invalid" }
Example 2
Source File: MultipleEndpointsDocumentationHttp4sServer.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.examples import java.util.concurrent.atomic.AtomicReference import cats.effect._ import cats.implicits._ import com.github.ghik.silencer.silent import io.circe.generic.auto._ import org.http4s.HttpRoutes import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.syntax.kleisli._ import sttp.tapir._ import sttp.tapir.docs.openapi._ import sttp.tapir.json.circe._ import sttp.tapir.openapi.OpenAPI import sttp.tapir.openapi.circe.yaml._ import sttp.tapir.server.http4s._ import sttp.tapir.swagger.http4s.SwaggerHttp4s import scala.concurrent.ExecutionContext object MultipleEndpointsDocumentationHttp4sServer extends App { // endpoint descriptions case class Author(name: String) case class Book(title: String, year: Int, author: Author) val booksListing: Endpoint[Unit, Unit, Vector[Book], Nothing] = endpoint.get .in("books") .in("list" / "all") .out(jsonBody[Vector[Book]]) val addBook: Endpoint[Book, Unit, Unit, Nothing] = endpoint.post .in("books") .in("add") .in( jsonBody[Book] .description("The book to add") .example(Book("Pride and Prejudice", 1813, Author("Jane Austen"))) ) // server-side logic implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global implicit val contextShift: ContextShift[IO] = IO.contextShift(ec) implicit val timer: Timer[IO] = IO.timer(ec) val books = new AtomicReference( Vector( Book("The Sorrows of Young Werther", 1774, Author("Johann Wolfgang von Goethe")), Book("Iliad", -8000, Author("Homer")), Book("Nad Niemnem", 1888, Author("Eliza Orzeszkowa")), Book("The Colour of Magic", 1983, Author("Terry Pratchett")), Book("The Art of Computer Programming", 1968, Author("Donald Knuth")), Book("Pharaoh", 1897, Author("Boleslaw Prus")) ) ) val booksListingRoutes: HttpRoutes[IO] = booksListing.toRoutes(_ => IO(books.get().asRight[Unit])) @silent("discarded") val addBookRoutes: HttpRoutes[IO] = addBook.toRoutes(book => IO((books.getAndUpdate(books => books :+ book): Unit).asRight[Unit])) val routes: HttpRoutes[IO] = booksListingRoutes <+> addBookRoutes // generating the documentation in yml; extension methods come from imported packages val openApiDocs: OpenAPI = List(booksListing, addBook).toOpenAPI("The tapir library", "1.0.0") val openApiYml: String = openApiDocs.toYaml // starting the server BlazeServerBuilder[IO](ec) .bindHttp(8080, "localhost") .withHttpApp(Router("/" -> (routes <+> new SwaggerHttp4s(openApiYml).routes[IO])).orNotFound) .resource .use { _ => IO { println("Go to: http://localhost:8080/docs") println("Press any key to exit ...") scala.io.StdIn.readLine() } } .unsafeRunSync() }
Example 3
Source File: FederatedApp.scala From caliban with Apache License 2.0 | 5 votes |
package caliban.federation import caliban.Http4sAdapter import caliban.federation.FederationData.characters.sampleCharacters import caliban.federation.FederationData.episodes.sampleEpisodes import cats.data.Kleisli import cats.effect.Blocker import org.http4s.StaticFile import org.http4s.implicits._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.server.middleware.CORS import zio._ import zio.blocking.Blocking import zio.interop.catz._ import scala.concurrent.ExecutionContext object FederatedApp extends CatsApp { type ExampleTask[A] = RIO[ZEnv, A] val service1 = CharacterService .make(sampleCharacters) .memoize .use(layer => for { blocker <- ZIO.access[Blocking](_.get.blockingExecutor.asEC).map(Blocker.liftExecutionContext) interpreter <- FederatedApi.Characters.api.interpreter.map(_.provideCustomLayer(layer)) _ <- BlazeServerBuilder[ExampleTask](ExecutionContext.global) .bindHttp(8089, "localhost") .withHttpApp( Router[ExampleTask]( "/api/graphql" -> CORS(Http4sAdapter.makeHttpService(interpreter)), "/graphiql" -> Kleisli.liftF(StaticFile.fromResource("/graphiql.html", blocker, None)) ).orNotFound ) .resource .toManaged .useForever } yield () ) val service2 = EpisodeService .make(sampleEpisodes) .memoize .use(layer => for { blocker <- ZIO.access[Blocking](_.get.blockingExecutor.asEC).map(Blocker.liftExecutionContext) interpreter <- FederatedApi.Episodes.api.interpreter.map(_.provideCustomLayer(layer)) _ <- BlazeServerBuilder[ExampleTask](ExecutionContext.global) .bindHttp(8088, "localhost") .withHttpApp( Router[ExampleTask]( "/api/graphql" -> CORS(Http4sAdapter.makeHttpService(interpreter)), "/graphiql" -> Kleisli.liftF(StaticFile.fromResource("/graphiql.html", blocker, None)) ).orNotFound ) .resource .toManaged .useForever } yield () ) override def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = (service1 race service2).exitCode }
Example 4
Source File: Main.scala From pfps-shopping-cart with Apache License 2.0 | 5 votes |
package shop import cats.effect._ import cats.implicits._ import io.chrisdavenport.log4cats.Logger import io.chrisdavenport.log4cats.slf4j.Slf4jLogger import org.http4s.server.blaze.BlazeServerBuilder import shop.modules._ object Main extends IOApp { implicit val logger = Slf4jLogger.getLogger[IO] override def run(args: List[String]): IO[ExitCode] = config.load[IO].flatMap { cfg => Logger[IO].info(s"Loaded config $cfg") >> AppResources.make[IO](cfg).use { res => for { security <- Security.make[IO](cfg, res.psql, res.redis) algebras <- Algebras.make[IO](res.redis, res.psql, cfg.cartExpiration) clients <- HttpClients.make[IO](cfg.paymentConfig, res.client) programs <- Programs.make[IO](cfg.checkoutConfig, algebras, clients) api <- HttpApi.make[IO](algebras, programs, security) _ <- BlazeServerBuilder[IO] .bindHttp( cfg.httpServerConfig.port.value, cfg.httpServerConfig.host.value ) .withHttpApp(api.httpApp) .serve .compile .drain } yield ExitCode.Success } } }
Example 5
Source File: BackendServer.scala From zio-telemetry with Apache License 2.0 | 5 votes |
package zio.telemetry.opentracing.example import cats.effect.{ ExitCode => catsExitCode } import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.syntax.kleisli._ import zio.interop.catz._ import zio.telemetry.opentracing.example.JaegerTracer.makeService import zio.telemetry.opentracing.example.config.Configuration import zio.telemetry.opentracing.example.http.{ AppTask, StatusService } import zio.{ ExitCode, ZEnv, ZIO } object BackendServer extends CatsApp { override def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = (for { conf <- Configuration.load.provideLayer(Configuration.live) service = makeService(conf.tracer.host, "zio-backend") router = Router[AppTask]("/" -> StatusService.status(service)).orNotFound result <- BlazeServerBuilder[AppTask] .bindHttp(conf.backend.port, conf.backend.host) .withHttpApp(router) .serve .compile[AppTask, AppTask, catsExitCode] .drain .as(ExitCode.success) } yield result).orElse(ZIO.succeed(ExitCode.failure)) }
Example 6
Source File: ProxyServer.scala From zio-telemetry with Apache License 2.0 | 5 votes |
package zio.telemetry.opentracing.example import cats.effect.{ ExitCode => catsExitCode } import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.syntax.kleisli._ import sttp.model.Uri import zio.interop.catz._ import zio.telemetry.opentracing.example.JaegerTracer.makeService import zio.telemetry.opentracing.example.config.Configuration import zio.telemetry.opentracing.example.http.{ AppTask, StatusesService } import zio.{ ExitCode, ZEnv, ZIO } object ProxyServer extends CatsApp { override def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = (for { conf <- Configuration.load.provideLayer(Configuration.live) service = makeService(conf.tracer.host, "zio-proxy") backendUrl <- ZIO.fromEither(Uri.safeApply(conf.backend.host, conf.backend.port)) router = Router[AppTask]("/" -> StatusesService.statuses(backendUrl, service)).orNotFound result <- BlazeServerBuilder[AppTask] .bindHttp(conf.proxy.port, conf.proxy.host) .withHttpApp(router) .serve .compile[AppTask, AppTask, catsExitCode] .drain .as(ExitCode.success) } yield result) orElse ZIO.succeed(ExitCode.failure) }
Example 7
Source File: BackendServer.scala From zio-telemetry with Apache License 2.0 | 5 votes |
package zio.telemetry.opentelemetry.example import org.http4s.server.{ Router, _ } import org.http4s.server.blaze.BlazeServerBuilder import zio.clock.Clock import zio.interop.catz._ import zio.telemetry.opentelemetry.Tracing import zio.telemetry.opentelemetry.example.config.{ Config, Configuration } import zio.telemetry.opentelemetry.example.http.{ AppEnv, AppTask, Client, StatusService } import zio.{ ExitCode, Managed, ZIO, ZLayer } import org.http4s.syntax.kleisli._ import sttp.client.asynchttpclient.zio.AsyncHttpClientZioBackend object BackendServer extends zio.App { val router = Router[AppTask]("/" -> StatusService.routes).orNotFound val server = ZIO .runtime[AppEnv] .flatMap(implicit runtime => BlazeServerBuilder[AppTask] .bindHttp( runtime.environment.get[Config].backend.host.port.getOrElse(defaults.HttpPort), runtime.environment.get[Config].backend.host.host ) .withHttpApp(router) .serve .compile .drain ) val httpBackend = ZLayer.fromManaged(Managed.make(AsyncHttpClientZioBackend())(_.close.ignore)) val client = Configuration.live ++ httpBackend >>> Client.live val tracer = Configuration.live >>> JaegerTracer.live("zio-backend") val envLayer = tracer ++ Clock.live >>> Tracing.live ++ Configuration.live ++ client override def run(args: List[String]) = server.provideCustomLayer(envLayer).fold(_ => ExitCode.failure, _ => ExitCode.success) }
Example 8
Source File: ProxyServer.scala From zio-telemetry with Apache License 2.0 | 5 votes |
package zio.telemetry.opentelemetry.example import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.server.{ defaults, Router } import zio.clock.Clock import zio.interop.catz._ import zio.telemetry.opentelemetry.Tracing import zio.telemetry.opentelemetry.example.config.{ Config, Configuration } import zio.telemetry.opentelemetry.example.http.{ AppEnv, AppTask, Client, StatusesService } import zio.{ ExitCode, Managed, ZIO, ZLayer } import org.http4s.syntax.kleisli._ import sttp.client.asynchttpclient.zio.AsyncHttpClientZioBackend object ProxyServer extends zio.App { val router = Router[AppTask]("/" -> StatusesService.routes).orNotFound val server = ZIO .runtime[AppEnv] .flatMap(implicit runtime => BlazeServerBuilder[AppTask] .bindHttp( runtime.environment.get[Config].proxy.host.port.getOrElse(defaults.HttpPort), runtime.environment.get[Config].proxy.host.host ) .withHttpApp(router) .serve .compile .drain ) val httpBackend = ZLayer.fromManaged(Managed.make(AsyncHttpClientZioBackend())(_.close.ignore)) val client = Configuration.live ++ httpBackend >>> Client.live val tracer = Configuration.live >>> JaegerTracer.live("zio-proxy") val envLayer = tracer ++ Clock.live >>> Tracing.live ++ Configuration.live ++ client override def run(args: List[String]) = server.provideCustomLayer(envLayer).fold(_ => ExitCode.failure, _ => ExitCode.success) }
Example 9
Source File: Main.scala From http4s-poc-api with MIT License | 5 votes |
package server import java.util.concurrent.Executors import com.github.ghik.silencer.silent import external.{TeamOneHttpApi, TeamThreeCacheApi, TeamTwoHttpApi} import io.circe.generic.auto._ import log.effect.zio.ZioLogWriter._ import model.DomainModel._ import org.http4s.circe._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.syntax.kleisli._ import org.http4s.{EntityDecoder, EntityEncoder, HttpApp} import service.PriceService import zio.interop.catz._ import zio.interop.catz.implicits._ import zio.{ExitCode, RIO, Task, ZEnv, ZIO} import scala.concurrent.ExecutionContext import model.DomainModelCodecs._ @silent object Main extends zio.interop.catz.CatsApp with Pools with Codecs { private[this] val priceService: RIO[String, PriceService[Task]] = log4sFromName map { log => PriceService[Task]( TeamThreeCacheApi.productCache, TeamOneHttpApi(), TeamTwoHttpApi(), log ) } private[this] val httpApp: RIO[PriceService[Task], HttpApp[Task]] = ZIO.access { ps => Router( "/pricing-api/prices" -> PriceRoutes[Task].make(ps), "/pricing-api/health-check" -> HealthCheckRoutes[Task].make(ps.logger) ).orNotFound } private[this] val runningServer: RIO[HttpApp[Task], Unit] = ZIO.accessM { app => BlazeServerBuilder[Task](serverPool) .bindHttp(17171, "0.0.0.0") .withConnectorPoolSize(connectorPoolSize) .enableHttp2(true) .withHttpApp(app) .serve .compile .drain } private[this] val serviceRuntime: RIO[String, Unit] = priceService >>> httpApp >>> runningServer def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = serviceRuntime.fold(_ => ExitCode.failure, _ => ExitCode.success) provide "App log" } sealed trait Pools { protected val connectorPoolSize = Runtime.getRuntime.availableProcessors() * 2 protected val mainThreadNumber = Runtime.getRuntime.availableProcessors() + 1 protected val serverPool = ExecutionContext.fromExecutor( Executors.newWorkStealingPool(mainThreadNumber) ) } sealed trait Codecs { implicit val priceRequestPayloadDecoder: EntityDecoder[Task, PricesRequestPayload] = jsonOf[Task, PricesRequestPayload] implicit val priceResponsePayloadEncoder: EntityEncoder[Task, List[Price]] = jsonEncoderOf[Task, List[Price]] implicit val healthCheckResponsePayloadEncoder: EntityEncoder[Task, ServiceSignature] = jsonEncoderOf[Task, ServiceSignature] }
Example 10
Source File: ExampleApp.scala From caliban with Apache License 2.0 | 5 votes |
package caliban.tapir import caliban.interop.tapir._ import caliban.tapir.Endpoints._ import caliban.{ GraphQL, Http4sAdapter } import cats.data.Kleisli import cats.effect.Blocker import org.http4s.StaticFile import org.http4s.implicits._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.server.middleware.CORS import sttp.tapir.server.ServerEndpoint import zio._ import zio.blocking.Blocking import zio.interop.catz._ import zio.interop.catz.implicits._ import scala.concurrent.ExecutionContext object ExampleApp extends CatsApp { // approach 1: using `Endpoint` and providing the logic val graphql: GraphQL[Any] = addBook.toGraphQL((bookAddLogic _).tupled) |+| deleteBook.toGraphQL((bookDeleteLogic _).tupled) |+| booksListing.toGraphQL((bookListingLogic _).tupled) // approach 2: using the `ServerEndpoint` where logic is already provided type MyIO[+A] = IO[String, A] val addBookEndpoint: ServerEndpoint[(Book, String), String, Unit, Nothing, MyIO] = addBook.serverLogic[MyIO] { case (book, token) => bookAddLogic(book, token).either } val deleteBookEndpoint: ServerEndpoint[(String, String), String, Unit, Nothing, MyIO] = deleteBook.serverLogic[MyIO] { case (title, token) => bookDeleteLogic(title, token).either } val booksListingEndpoint: ServerEndpoint[(Option[Int], Option[Int]), Nothing, List[Book], Nothing, UIO] = booksListing.serverLogic[UIO] { case (year, limit) => bookListingLogic(year, limit).map(Right(_)) } val graphql2: GraphQL[Any] = addBookEndpoint.toGraphQL |+| deleteBookEndpoint.toGraphQL |+| booksListingEndpoint.toGraphQL override def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = (for { blocker <- ZIO.access[Blocking](_.get.blockingExecutor.asEC).map(Blocker.liftExecutionContext) interpreter <- graphql.interpreter _ <- BlazeServerBuilder[Task](ExecutionContext.global) .bindHttp(8088, "localhost") .withHttpApp( Router[Task]( "/api/graphql" -> CORS(Http4sAdapter.makeHttpService(interpreter)), "/graphiql" -> Kleisli.liftF(StaticFile.fromResource("/graphiql.html", blocker, None)) ).orNotFound ) .resource .toManaged .useForever } yield ()).exitCode }
Example 11
Source File: StreamingHttp4sFs2Server.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.examples import java.nio.charset.StandardCharsets import cats.effect._ import cats.implicits._ import org.http4s.HttpRoutes import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.syntax.kleisli._ import sttp.client._ import sttp.tapir._ import sttp.tapir.server.http4s._ import fs2._ import sttp.model.HeaderNames import scala.concurrent.ExecutionContext import scala.concurrent.duration._ // https://github.com/softwaremill/tapir/issues/367 object StreamingHttp4sFs2Server extends App { // corresponds to: GET /receive?name=... // We need to provide both the schema of the value (for documentation), as well as the format (media type) of the // body. Here, the schema is a `string` and the media type is `text/plain`. val streamingEndpoint = endpoint.get .in("receive") .out(header[Long](HeaderNames.ContentLength)) .out(streamBody[Stream[IO, Byte]](schemaFor[String], CodecFormat.TextPlain(), Some(StandardCharsets.UTF_8))) // mandatory implicits implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global implicit val contextShift: ContextShift[IO] = IO.contextShift(ec) implicit val timer: Timer[IO] = IO.timer(ec) // converting an endpoint to a route (providing server-side logic); extension method comes from imported packages val streamingRoutes: HttpRoutes[IO] = streamingEndpoint.toRoutes { _ => val size = 100L Stream .emit(List[Char]('a', 'b', 'c', 'd')) .repeat .flatMap(list => Stream.chunk(Chunk.seq(list))) .metered[IO](100.millis) .take(size) .covary[IO] .map(_.toByte) .pure[IO] .map(s => Right((size, s))) } // starting the server BlazeServerBuilder[IO](ec) .bindHttp(8080, "localhost") .withHttpApp(Router("/" -> streamingRoutes).orNotFound) .resource .use { _ => IO { implicit val backend: SttpBackend[Identity, Nothing, NothingT] = HttpURLConnectionBackend() val result: String = basicRequest.response(asStringAlways).get(uri"http://localhost:8080/receive").send().body println("Got result: " + result) assert(result == "abcd" * 25) } } .unsafeRunSync() }
Example 12
Source File: HelloWorldHttp4sServer.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.examples import cats.effect._ import sttp.client._ import org.http4s.HttpRoutes import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.syntax.kleisli._ import sttp.tapir._ import sttp.tapir.server.http4s._ import cats.implicits._ import scala.concurrent.ExecutionContext object HelloWorldHttp4sServer extends App { // the endpoint: single fixed path input ("hello"), single query parameter // corresponds to: GET /hello?name=... val helloWorld: Endpoint[String, Unit, String, Nothing] = endpoint.get.in("hello").in(query[String]("name")).out(stringBody) // mandatory implicits implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global implicit val contextShift: ContextShift[IO] = IO.contextShift(ec) implicit val timer: Timer[IO] = IO.timer(ec) // converting an endpoint to a route (providing server-side logic); extension method comes from imported packages val helloWorldRoutes: HttpRoutes[IO] = helloWorld.toRoutes(name => IO(s"Hello, $name!".asRight[Unit])) // starting the server BlazeServerBuilder[IO](ec) .bindHttp(8080, "localhost") .withHttpApp(Router("/" -> helloWorldRoutes).orNotFound) .resource .use { _ => IO { implicit val backend: SttpBackend[Identity, Nothing, NothingT] = HttpURLConnectionBackend() val result: String = basicRequest.response(asStringAlways).get(uri"http://localhost:8080/hello?name=Frodo").send().body println("Got result: " + result) assert(result == "Hello, Frodo!") } } .unsafeRunSync() }
Example 13
Source File: ZioExampleHttp4sServer.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.examples import org.http4s._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.syntax.kleisli._ import zio.interop.catz._ import zio.interop.catz.implicits._ import zio.{Has, IO, Runtime, Task, UIO, ZIO, ZLayer, ZEnv} import sttp.tapir.ztapir._ import sttp.tapir.server.http4s.ztapir._ import sttp.tapir.swagger.http4s.SwaggerHttp4s import cats.implicits._ import UserLayer.UserService import sttp.tapir.examples.ZioExampleHttp4sServer.Pet import zio.console.Console object ZioExampleHttp4sServer extends App { case class Pet(species: String, url: String) import io.circe.generic.auto._ import sttp.tapir.json.circe._ // Sample endpoint, with the logic implemented directly using .toRoutes val petEndpoint: ZEndpoint[Int, String, Pet] = endpoint.get.in("pet" / path[Int]("petId")).errorOut(stringBody).out(jsonBody[Pet]) val petRoutes: HttpRoutes[Task] = petEndpoint.toRoutes { petId => if (petId == 35) { UIO(Pet("Tapirus terrestris", "https://en.wikipedia.org/wiki/Tapir")) } else { IO.fail("Unknown pet id") } } // Same endpoint as above, but using a custom application layer val pet2Endpoint: ZEndpoint[Int, String, Pet] = endpoint.get.in("pet2" / path[Int]("petId")).errorOut(stringBody).out(jsonBody[Pet]) val pet2Routes: HttpRoutes[Task] = pet2Endpoint.toRoutes(petId => UserService.hello(petId).provideLayer(UserLayer.liveEnv)) // Final service is just a conjunction of different Routes implicit val runtime: Runtime[ZEnv] = Runtime.default val service: HttpRoutes[Task] = petRoutes <+> pet2Routes // // Same as above, but combining endpoint description with server logic: // val petServerEndpoint = petEndpoint.zServerLogic { petId => if (petId == 35) { UIO(Pet("Tapirus terrestris", "https://en.wikipedia.org/wiki/Tapir")) } else { IO.fail("Unknown pet id") } } val petServerRoutes: HttpRoutes[Task] = petServerEndpoint.toRoutes val pet2ServerEndpoint = pet2Endpoint.zServerLogic { petId => UserService.hello(petId).provideLayer(UserLayer.liveEnv) } val pet2ServerRoutes: HttpRoutes[Task] = petServerEndpoint.toRoutes import sttp.tapir.docs.openapi._ import sttp.tapir.openapi.circe.yaml._ val yaml = List(petEndpoint).toOpenAPI("Our pets", "1.0").toYaml val serve = BlazeServerBuilder[Task](runtime.platform.executor.asEC) .bindHttp(8080, "localhost") .withHttpApp(Router("/" -> (service <+> new SwaggerHttp4s(yaml).routes[Task])).orNotFound) .serve .compile .drain runtime.unsafeRun(serve) } object UserLayer { type UserService = Has[UserService.Service] object UserService { trait Service { def hello(id: Int): ZIO[Any, String, Pet] } val live: ZLayer[Console, Nothing, Has[Service]] = ZLayer.fromFunction { console: Console => (id: Int) => { console.get.putStrLn(s"Got Pet request for $id") >> ZIO.succeed(Pet(id.toString, "https://zio.dev")) } } def hello(id: Int): ZIO[UserService, String, Pet] = ZIO.accessM(_.get.hello(id)) } val liveEnv: ZLayer[Any, Nothing, Has[UserService.Service]] = Console.live >>> UserService.live }
Example 14
Source File: Http4sServerTests.scala From tapir with Apache License 2.0 | 5 votes |
package sttp.tapir.server.http4s import cats.data.{Kleisli, NonEmptyList} import cats.effect._ import cats.implicits._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.syntax.kleisli._ import org.http4s.{EntityBody, HttpRoutes, Request, Response} import sttp.tapir.server.tests.ServerTests import sttp.tapir.Endpoint import sttp.tapir._ import sttp.client._ import sttp.tapir.server.{DecodeFailureHandler, ServerDefaults, ServerEndpoint} import sttp.tapir.tests.{Port, PortCounter} import scala.concurrent.ExecutionContext import scala.reflect.ClassTag class Http4sServerTests extends ServerTests[IO, EntityBody[IO], HttpRoutes[IO]] { implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global implicit val contextShift: ContextShift[IO] = IO.contextShift(ec) implicit val timer: Timer[IO] = IO.timer(ec) override def pureResult[T](t: T): IO[T] = IO.pure(t) override def suspendResult[T](t: => T): IO[T] = IO.apply(t) override def route[I, E, O]( e: ServerEndpoint[I, E, O, EntityBody[IO], IO], decodeFailureHandler: Option[DecodeFailureHandler] = None ): HttpRoutes[IO] = { implicit val serverOptions: Http4sServerOptions[IO] = Http4sServerOptions .default[IO] .copy( decodeFailureHandler = decodeFailureHandler.getOrElse(ServerDefaults.decodeFailureHandler) ) e.toRoutes } override def routeRecoverErrors[I, E <: Throwable, O](e: Endpoint[I, E, O, EntityBody[IO]], fn: I => IO[O])(implicit eClassTag: ClassTag[E] ): HttpRoutes[IO] = { e.toRouteRecoverErrors(fn) } override def server(routes: NonEmptyList[HttpRoutes[IO]], port: Port): Resource[IO, Unit] = { val service: Kleisli[IO, Request[IO], Response[IO]] = routes.reduceK.orNotFound BlazeServerBuilder[IO](ExecutionContext.global) .bindHttp(port, "localhost") .withHttpApp(service) .resource .void } override lazy val portCounter: PortCounter = new PortCounter(56000) if (testNameFilter.isEmpty) { test("should work with a router and routes in a context") { val e = endpoint.get.in("test" / "router").out(stringBody).serverLogic(_ => IO.pure("ok".asRight[Unit])) val routes = e.toRoutes val port = portCounter.next() BlazeServerBuilder[IO](ExecutionContext.global) .bindHttp(port, "localhost") .withHttpApp(Router("/api" -> routes).orNotFound) .resource .use { _ => basicRequest.get(uri"http://localhost:$port/api/test/router").send().map(_.body shouldBe Right("ok")) } .unsafeRunSync() } } }
Example 15
Source File: InvoicesServer.scala From event-sourcing-kafka-streams with MIT License | 5 votes |
package org.amitayh.invoices.web import java.util.UUID import cats.effect.{ExitCode, IO, IOApp} import cats.syntax.functor._ import fs2.Stream import fs2.concurrent.Topic import org.amitayh.invoices.common.Config.Topics import org.amitayh.invoices.common.domain.{Command, CommandResult, InvoiceSnapshot} import org.amitayh.invoices.dao.{InvoiceList, MySqlInvoiceList} import org.amitayh.invoices.web.PushEvents._ import org.http4s.implicits._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder object InvoicesServer extends IOApp { override def run(args: List[String]): IO[ExitCode] = stream.compile.drain.as(ExitCode.Success) private val stream: Stream[IO, ExitCode] = for { invoiceList <- Stream.resource(MySqlInvoiceList.resource[IO]) producer <- Stream.resource(Kafka.producer[IO, UUID, Command](Topics.Commands)) commandResultsTopic <- Stream.eval(Topic[IO, CommandResultRecord](None)) invoiceUpdatesTopic <- Stream.eval(Topic[IO, InvoiceSnapshotRecord](None)) server <- httpServer(invoiceList, producer, commandResultsTopic, invoiceUpdatesTopic) concurrently commandResults.through(commandResultsTopic.publish) concurrently invoiceUpdates.through(invoiceUpdatesTopic.publish) } yield server private def commandResults: Stream[IO, CommandResultRecord] = Kafka.subscribe[IO, UUID, CommandResult]( topic = Topics.CommandResults, groupId = "invoices.websocket.command-results").map(Some(_)) private def invoiceUpdates: Stream[IO, InvoiceSnapshotRecord] = Kafka.subscribe[IO, UUID, InvoiceSnapshot]( topic = Topics.Snapshots, groupId = "invoices.websocket.snapshots").map(Some(_)) private def httpServer(invoiceList: InvoiceList[IO], producer: Kafka.Producer[IO, UUID, Command], commandResultsTopic: Topic[IO, CommandResultRecord], invoiceUpdatesTopic: Topic[IO, InvoiceSnapshotRecord]): Stream[IO, ExitCode] = BlazeServerBuilder[IO] .bindHttp(8080, "0.0.0.0") .withHttpApp( Router( "/api" -> InvoicesApi[IO].service(invoiceList, producer, commandResultsTopic), "/events" -> PushEvents[IO].service(commandResultsTopic, invoiceUpdatesTopic), "/" -> Statics[IO].service).orNotFound) .serve }
Example 16
Source File: Http4sBlazeServerModule.scala From scala-server-toolkit with MIT License | 5 votes |
package com.avast.sst.http4s.server import java.net.{InetSocketAddress, StandardSocketOptions} import cats.effect.{ConcurrentEffect, Resource, Timer} import org.http4s.HttpApp import org.http4s.server.Server import org.http4s.server.blaze.BlazeServerBuilder import scala.concurrent.ExecutionContext import scala.concurrent.duration.Duration object Http4sBlazeServerModule { def make[F[_]: ConcurrentEffect: Timer]( config: Http4sBlazeServerConfig, httpApp: HttpApp[F], executionContext: ExecutionContext ): Resource[F, Server[F]] = { for { inetSocketAddress <- Resource.liftF( ConcurrentEffect[F].delay( InetSocketAddress.createUnresolved(config.listenAddress, config.listenPort) ) ) server <- BlazeServerBuilder[F](executionContext) .bindSocketAddress(inetSocketAddress) .withHttpApp(httpApp) .withoutBanner .withNio2(config.nio2Enabled) .withWebSockets(config.webSocketsEnabled) .enableHttp2(config.http2Enabled) .withResponseHeaderTimeout(Duration.fromNanos(config.responseHeaderTimeout.toNanos)) .withIdleTimeout(Duration.fromNanos(config.idleTimeout.toNanos)) .withBufferSize(config.bufferSize) .withMaxRequestLineLength(config.maxRequestLineLength) .withMaxHeadersLength(config.maxHeadersLength) .withChunkBufferMaxSize(config.chunkBufferMaxSize) .withConnectorPoolSize(config.connectorPoolSize) .withChannelOption[java.lang.Boolean](StandardSocketOptions.TCP_NODELAY, config.socketOptions.tcpNoDelay) .resource } yield server } }
Example 17
Source File: CorrelationIdMiddlewareTest.scala From scala-server-toolkit with MIT License | 5 votes |
package com.avast.sst.http4s.server.middleware import java.net.InetSocketAddress import cats.effect.{ContextShift, IO, Resource, Timer} import com.avast.sst.http4s.server.Http4sRouting import org.http4s.client.blaze.BlazeClientBuilder import org.http4s.dsl.Http4sDsl import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.util.CaseInsensitiveString import org.http4s.{Header, HttpRoutes, Request, Uri} import org.scalatest.funsuite.AsyncFunSuite import scala.concurrent.ExecutionContext @SuppressWarnings(Array("scalafix:Disable.get", "scalafix:Disable.toString", "scalafix:Disable.createUnresolved")) class CorrelationIdMiddlewareTest extends AsyncFunSuite with Http4sDsl[IO] { implicit private val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global) implicit private val timer: Timer[IO] = IO.timer(ExecutionContext.global) test("CorrelationIdMiddleware fills Request attributes and HTTP response header") { val test = for { middleware <- Resource.liftF(CorrelationIdMiddleware.default[IO]) routes = Http4sRouting.make { middleware.wrap { HttpRoutes.of[IO] { case req @ GET -> Root / "test" => val id = middleware.retrieveCorrelationId(req) Ok("test").map(_.withHeaders(Header("Attribute-Value", id.toString))) } } } server <- BlazeServerBuilder[IO](ExecutionContext.global) .bindSocketAddress(InetSocketAddress.createUnresolved("127.0.0.1", 0)) .withHttpApp(routes) .resource client <- BlazeClientBuilder[IO](ExecutionContext.global).resource } yield (server, client) test .use { case (server, client) => client .run( Request[IO](uri = Uri.unsafeFromString(s"http://${server.address.getHostString}:${server.address.getPort}/test")) .withHeaders(Header("Correlation-Id", "test-value")) ) .use { response => IO.delay { assert(response.headers.get(CaseInsensitiveString("Correlation-Id")).get.value === "test-value") assert(response.headers.get(CaseInsensitiveString("Attribute-Value")).get.value === "Some(CorrelationId(test-value))") } } } .unsafeToFuture() } }
Example 18
Source File: Http4sRpcServer.scala From iotchain with MIT License | 5 votes |
package jbok.network.rpc.http import cats.effect.{ConcurrentEffect, Resource, Sync, Timer} import cats.implicits._ import io.circe.Json import io.circe.syntax._ import jbok.network.rpc.{RpcRequest, RpcService} import org.http4s.HttpRoutes import org.http4s.circe.CirceEntityCodec._ import org.http4s.dsl.Http4sDsl import org.http4s.implicits._ import org.http4s.server.Server import org.http4s.server.blaze.BlazeServerBuilder object Http4sRpcServer { def routes[F[_]](service: RpcService[F, Json])(implicit F: Sync[F]): HttpRoutes[F] = { val dsl = Http4sDsl[F] import dsl._ HttpRoutes.of[F] { case req @ POST -> path => for { json <- req.as[Json] result <- service.handle(RpcRequest(path.toList, json)) resp <- Ok(result.asJson) } yield resp } } def server[F[_]](service: RpcService[F, Json])(implicit F: ConcurrentEffect[F], T: Timer[F]): Resource[F, Server[F]] = BlazeServerBuilder[F] .bindLocal(0) .withHttpApp(routes[F](service).orNotFound) .withWebSockets(true) .resource }
Example 19
Source File: AuthExampleApp.scala From caliban with Apache License 2.0 | 5 votes |
package caliban.http4s import caliban.GraphQL._ import caliban.schema.GenericSchema import caliban.{ Http4sAdapter, RootResolver } import org.http4s.HttpRoutes import org.http4s.dsl.Http4sDsl import org.http4s.implicits._ import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.server.{ Router, ServiceErrorHandler } import org.http4s.util.CaseInsensitiveString import zio._ import zio.interop.catz._ import zio.interop.catz.implicits._ import scala.concurrent.ExecutionContext object AuthExampleApp extends CatsApp { // Simple service that returns the token coming from the request type Auth = Has[Auth.Service] object Auth { trait Service { def token: String } } type AuthTask[A] = RIO[Auth, A] case class MissingToken() extends Throwable // http4s middleware that extracts a token from the request and eliminate the Auth layer dependency object AuthMiddleware { def apply(route: HttpRoutes[AuthTask]): HttpRoutes[Task] = Http4sAdapter.provideLayerFromRequest( route, _.headers.get(CaseInsensitiveString("token")) match { case Some(value) => ZLayer.succeed(new Auth.Service { override def token: String = value.value }) case None => ZLayer.fail(MissingToken()) } ) } // http4s error handler to customize the response for our throwable object dsl extends Http4sDsl[Task] import dsl._ val errorHandler: ServiceErrorHandler[Task] = _ => { case MissingToken() => Forbidden() } // our GraphQL API val schema: GenericSchema[Auth] = new GenericSchema[Auth] {} import schema._ case class Query(token: RIO[Auth, String]) private val resolver = RootResolver(Query(ZIO.access[Auth](_.get[Auth.Service].token))) private val api = graphQL(resolver) override def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = (for { interpreter <- api.interpreter route = AuthMiddleware(Http4sAdapter.makeHttpService(interpreter)) _ <- BlazeServerBuilder[Task](ExecutionContext.global) .withServiceErrorHandler(errorHandler) .bindHttp(8088, "localhost") .withHttpApp(Router[Task]("/api/graphql" -> route).orNotFound) .resource .toManaged .useForever } yield ()).exitCode }
Example 20
Source File: ExampleApp.scala From caliban with Apache License 2.0 | 5 votes |
package caliban.http4s import caliban.ExampleData._ import caliban.ExampleService.ExampleService import caliban.{ ExampleApi, ExampleService, Http4sAdapter } import cats.data.Kleisli import cats.effect.Blocker import org.http4s.StaticFile import org.http4s.implicits._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.server.middleware.CORS import zio._ import zio.blocking.Blocking import zio.interop.catz._ import scala.concurrent.ExecutionContext object ExampleApp extends App { type ExampleTask[A] = RIO[ZEnv with ExampleService, A] override def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = ZIO .runtime[ZEnv with ExampleService] .flatMap(implicit runtime => for { blocker <- ZIO.access[Blocking](_.get.blockingExecutor.asEC).map(Blocker.liftExecutionContext) interpreter <- ExampleApi.api.interpreter _ <- BlazeServerBuilder[ExampleTask](ExecutionContext.global) .bindHttp(8088, "localhost") .withHttpApp( Router[ExampleTask]( "/api/graphql" -> CORS(Http4sAdapter.makeHttpService(interpreter)), "/ws/graphql" -> CORS(Http4sAdapter.makeWebSocketService(interpreter)), "/graphiql" -> Kleisli.liftF(StaticFile.fromResource("/graphiql.html", blocker, None)) ).orNotFound ) .resource .toManaged .useForever } yield () ) .provideCustomLayer(ExampleService.make(sampleCharacters)) .exitCode }
Example 21
Source File: Server.scala From scala-pet-store with Apache License 2.0 | 5 votes |
package io.github.pauljamescleary.petstore import config._ import domain.users._ import domain.orders._ import domain.pets._ import infrastructure.endpoint._ import infrastructure.repository.doobie.{ DoobieAuthRepositoryInterpreter, DoobieOrderRepositoryInterpreter, DoobiePetRepositoryInterpreter, DoobieUserRepositoryInterpreter, } import cats.effect._ import org.http4s.server.{Router, Server => H4Server} import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.implicits._ import tsec.passwordhashers.jca.BCrypt import doobie.util.ExecutionContexts import io.circe.config.parser import domain.authentication.Auth import tsec.authentication.SecuredRequestHandler import tsec.mac.jca.HMACSHA256 object Server extends IOApp { def createServer[F[_]: ContextShift: ConcurrentEffect: Timer]: Resource[F, H4Server[F]] = for { conf <- Resource.liftF(parser.decodePathF[F, PetStoreConfig]("petstore")) serverEc <- ExecutionContexts.cachedThreadPool[F] connEc <- ExecutionContexts.fixedThreadPool[F](conf.db.connections.poolSize) txnEc <- ExecutionContexts.cachedThreadPool[F] xa <- DatabaseConfig.dbTransactor(conf.db, connEc, Blocker.liftExecutionContext(txnEc)) key <- Resource.liftF(HMACSHA256.generateKey[F]) authRepo = DoobieAuthRepositoryInterpreter[F, HMACSHA256](key, xa) petRepo = DoobiePetRepositoryInterpreter[F](xa) orderRepo = DoobieOrderRepositoryInterpreter[F](xa) userRepo = DoobieUserRepositoryInterpreter[F](xa) petValidation = PetValidationInterpreter[F](petRepo) petService = PetService[F](petRepo, petValidation) userValidation = UserValidationInterpreter[F](userRepo) orderService = OrderService[F](orderRepo) userService = UserService[F](userRepo, userValidation) authenticator = Auth.jwtAuthenticator[F, HMACSHA256](key, authRepo, userRepo) routeAuth = SecuredRequestHandler(authenticator) httpApp = Router( "/users" -> UserEndpoints .endpoints[F, BCrypt, HMACSHA256](userService, BCrypt.syncPasswordHasher[F], routeAuth), "/pets" -> PetEndpoints.endpoints[F, HMACSHA256](petService, routeAuth), "/orders" -> OrderEndpoints.endpoints[F, HMACSHA256](orderService, routeAuth), ).orNotFound _ <- Resource.liftF(DatabaseConfig.initializeDb(conf.db)) server <- BlazeServerBuilder[F](serverEc) .bindHttp(conf.server.port, conf.server.host) .withHttpApp(httpApp) .resource } yield server def run(args: List[String]): IO[ExitCode] = createServer.use(_ => IO.never).as(ExitCode.Success) }
Example 22
Source File: ReverseAPI.scala From cornichon with Apache License 2.0 | 5 votes |
package com.github.agourlay.cornichon.framework.examples.propertyCheck.stringReverse import com.github.agourlay.cornichon.framework.examples.HttpServer import monix.eval.Task import monix.execution.{ CancelableFuture, Scheduler } import org.http4s._ import org.http4s.implicits._ import org.http4s.dsl._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder class ReverseAPI extends Http4sDsl[Task] { implicit val s = Scheduler.Implicits.global object WordQueryParamMatcher extends QueryParamDecoderMatcher[String]("word") private val reverseService = HttpRoutes.of[Task] { case POST -> Root / "double-reverse" :? WordQueryParamMatcher(word) => Ok(word.reverse.reverse) } private val routes = Router( "/" -> reverseService ) def start(httpPort: Int): CancelableFuture[HttpServer] = BlazeServerBuilder[Task](executionContext = s) .bindHttp(httpPort, "localhost") .withoutBanner .withNio2(true) .withHttpApp(routes.orNotFound) .allocated .map { case (_, stop) => new HttpServer(stop) } .runToFuture }
Example 23
Source File: TurnstileAPI.scala From cornichon with Apache License 2.0 | 5 votes |
package com.github.agourlay.cornichon.framework.examples.propertyCheck.turnstile import com.github.agourlay.cornichon.framework.examples.HttpServer import monix.eval.Task import monix.execution.atomic.AtomicBoolean import monix.execution.{ CancelableFuture, Scheduler } import org.http4s._ import org.http4s.implicits._ import org.http4s.dsl._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder class TurnstileAPI extends Http4sDsl[Task] { implicit val s = Scheduler.Implicits.global private val turnstileLocked = AtomicBoolean(true) private val turnstileService = HttpRoutes.of[Task] { case POST -> Root / "push-coin" => if (turnstileLocked.get()) { turnstileLocked.set(false) Ok("payment accepted") } else BadRequest("payment refused") case POST -> Root / "walk-through" => if (turnstileLocked.get()) BadRequest("door blocked") else { turnstileLocked.set(true) Ok("door turns") } } private val routes = Router( "/" -> turnstileService ) def start(httpPort: Int): CancelableFuture[HttpServer] = BlazeServerBuilder[Task](executionContext = s) .bindHttp(httpPort, "localhost") .withoutBanner .withNio2(true) .withHttpApp(routes.orNotFound) .allocated .map { case (_, stop) => new HttpServer(stop) } .runToFuture }
Example 24
Source File: EndpointWirings.scala From ticket-booking-aecor with Apache License 2.0 | 5 votes |
package ru.pavkin.booking import cats.effect.{ConcurrentEffect, Timer} import org.http4s.HttpRoutes import org.http4s.implicits._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import ru.pavkin.booking.booking.endpoint.{BookingRoutes, DefaultBookingEndpoint} import ru.pavkin.booking.config.HttpServer import scala.concurrent.duration.{Duration => _} final class EndpointWirings[F[_] : ConcurrentEffect : Timer]( httpServer: HttpServer, postgresWirings: PostgresWirings[F], entityWirings: EntityWirings[F]) { import entityWirings._ import postgresWirings._ val bookingsEndpoint = new DefaultBookingEndpoint(bookings, bookingViewRepo) val bookingRoutes = new BookingRoutes(bookingsEndpoint) val routes: HttpRoutes[F] = bookingRoutes.routes def launchHttpService: F[Unit] = BlazeServerBuilder[F] .bindHttp(httpServer.port, httpServer.interface) .withHttpApp(Router("/" -> routes).orNotFound) .serve .compile .drain }
Example 25
Source File: Main.scala From http4s-tracer with Apache License 2.0 | 5 votes |
package dev.profunktor.tracer import scala.concurrent.ExecutionContext import cats.effect._ import cats.implicits._ import cats.Parallel import dev.profunktor.tracer.module._ import dev.profunktor.tracer.module.tracer._ import dev.profunktor.tracer.Trace.Trace import org.http4s.client.blaze.BlazeClientBuilder import org.http4s.server.blaze.BlazeServerBuilder class Main[F[_]: ConcurrentEffect: Parallel: Timer: Tracer: λ[T[_] => TracerLog[Trace[T, ?]]]] { val server: F[Unit] = BlazeClientBuilder[F](ExecutionContext.global).resource.use { client => for { repos <- LiveRepositories[F] tracedRepos = TracedRepositories[F](repos) tracedClients = TracedHttpClients[F](client) tracedPrograms = TracedPrograms[F](tracedRepos, tracedClients) httpApi = HttpApi[F](tracedPrograms) _ <- BlazeServerBuilder .apply[F](ExecutionContext.global) .bindHttp(8080, "0.0.0.0") .withHttpApp(httpApi.httpApp) .serve .compile .drain } yield () } }
Example 26
Source File: JoexServer.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.joex import cats.effect._ import cats.effect.concurrent.Ref import fs2.Stream import fs2.concurrent.SignallingRef import docspell.common.Pools import docspell.joex.routes._ import org.http4s.HttpApp import org.http4s.implicits._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.server.middleware.Logger object JoexServer { private case class App[F[_]]( httpApp: HttpApp[F], termSig: SignallingRef[F, Boolean], exitRef: Ref[F, ExitCode] ) def stream[F[_]: ConcurrentEffect: ContextShift]( cfg: Config, pools: Pools )(implicit T: Timer[F]): Stream[F, Nothing] = { val app = for { signal <- Resource.liftF(SignallingRef[F, Boolean](false)) exitCode <- Resource.liftF(Ref[F].of(ExitCode.Success)) joexApp <- JoexAppImpl .create[F](cfg, signal, pools.connectEC, pools.httpClientEC, pools.blocker) httpApp = Router( "/api/info" -> InfoRoutes(), "/api/v1" -> JoexRoutes(joexApp) ).orNotFound // With Middlewares in place finalHttpApp = Logger.httpApp(false, false)(httpApp) } yield App(finalHttpApp, signal, exitCode) Stream .resource(app) .flatMap(app => BlazeServerBuilder[F](pools.restEC) .bindHttp(cfg.bind.port, cfg.bind.address) .withHttpApp(app.httpApp) .withoutBanner .serveWhile(app.termSig, app.exitRef) ) }.drain }
Example 27
Source File: CpgServerMain.scala From codepropertygraph with Apache License 2.0 | 5 votes |
package io.shiftleft.cpgserver import cats.effect.{ExitCode, IO, IOApp} import cats.implicits._ import org.http4s.implicits._ import org.http4s.server.blaze.BlazeServerBuilder import io.shiftleft.cpgserver.config.ServerConfiguration import io.shiftleft.cpgserver.cpg.DummyCpgProvider import io.shiftleft.cpgserver.query.{DefaultAmmoniteExecutor, ServerAmmoniteExecutor} import io.shiftleft.cpgserver.route.{CpgRoute, HttpErrorHandler, SwaggerRoute} object CpgServerMain extends IOApp { private val banner: String = """| ██████╗██████╗ ██████╗ ███████╗███████╗██████╗ ██╗ ██╗███████╗██████╗ |██╔════╝██╔══██╗██╔════╝ ██╔════╝██╔════╝██╔══██╗██║ ██║██╔════╝██╔══██╗ |██║ ██████╔╝██║ ███╗ ███████╗█████╗ ██████╔╝██║ ██║█████╗ ██████╔╝ |██║ ██╔═══╝ ██║ ██║ ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██╔══╝ ██╔══██╗ |╚██████╗██║ ╚██████╔╝ ███████║███████╗██║ ██║ ╚████╔╝ ███████╗██║ ██║ | ╚═════╝╚═╝ ╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝ |""".stripMargin private val cpgProvider: DummyCpgProvider = new DummyCpgProvider private val ammoniteExecutor: ServerAmmoniteExecutor = new DefaultAmmoniteExecutor private implicit val httpErrorHandler: HttpErrorHandler = CpgRoute.CpgHttpErrorHandler private val serverConfig: ServerConfiguration = ServerConfiguration.config.getOrElse(ServerConfiguration.default) private val httpRoutes = CpgRoute(cpgProvider, ammoniteExecutor, serverConfig.files).routes <+> SwaggerRoute().routes override def run(args: List[String]): IO[ExitCode] = { BlazeServerBuilder[IO] .withBanner(List(banner)) .bindHttp(serverConfig.port, serverConfig.host) .withHttpApp(httpRoutes.orNotFound) .serve .compile .drain .as(ExitCode.Success) } }
Example 28
Source File: ServerInterpreterTest.scala From endpoints4s with MIT License | 5 votes |
package endpoints4s.http4s.server import java.net.ServerSocket import cats.effect.{ContextShift, IO, Timer} import endpoints4s.{Invalid, Valid} import endpoints4s.algebra.server.{ BasicAuthenticationTestSuite, DecodedUrl, EndpointsTestSuite, JsonEntitiesFromSchemasTestSuite, SumTypedEntitiesTestSuite, TextEntitiesTestSuite } import org.http4s.server.Router import org.http4s.{HttpRoutes, Uri} import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.syntax.kleisli._ import scala.concurrent.ExecutionContext class ServerInterpreterTest extends EndpointsTestSuite[EndpointsTestApi] with BasicAuthenticationTestSuite[EndpointsTestApi] with JsonEntitiesFromSchemasTestSuite[EndpointsTestApi] with TextEntitiesTestSuite[EndpointsTestApi] with SumTypedEntitiesTestSuite[EndpointsTestApi] { val serverApi = new EndpointsTestApi() def decodeUrl[A](url: serverApi.Url[A])(rawValue: String): DecodedUrl[A] = { val uri = Uri.fromString(rawValue).getOrElse(sys.error(s"Illegal URI: $rawValue")) url.decodeUrl(uri) match { case None => DecodedUrl.NotMatched case Some(Invalid(errors)) => DecodedUrl.Malformed(errors) case Some(Valid(a)) => DecodedUrl.Matched(a) } } private def serveGeneralEndpoint[Req, Resp]( endpoint: serverApi.Endpoint[Req, Resp], request2response: Req => Resp )(runTests: Int => Unit): Unit = { val port = { val socket = new ServerSocket(0) try socket.getLocalPort finally if (socket != null) socket.close() } implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global) implicit val timer: Timer[IO] = IO.timer(ExecutionContext.global) val service = HttpRoutes.of[IO](endpoint.implementedBy(request2response)) val httpApp = Router("/" -> service).orNotFound val server = BlazeServerBuilder[IO](ExecutionContext.global) .bindHttp(port, "localhost") .withHttpApp(httpApp) server.resource.use(_ => IO(runTests(port))).unsafeRunSync() } def serveEndpoint[Resp]( endpoint: serverApi.Endpoint[_, Resp], response: => Resp )(runTests: Int => Unit): Unit = serveGeneralEndpoint(endpoint, (_: Any) => response)(runTests) def serveIdentityEndpoint[Resp]( endpoint: serverApi.Endpoint[Resp, Resp] )(runTests: Int => Unit): Unit = serveGeneralEndpoint(endpoint, identity[Resp])(runTests) }
Example 29
Source File: Hook.scala From canoe with MIT License | 5 votes |
package canoe.api.sources import canoe.api.{TelegramClient} import canoe.methods.webhooks.{DeleteWebhook, SetWebhook} import canoe.models.{InputFile, Update} import canoe.syntax.methodOps import cats.Monad import cats.effect.{ConcurrentEffect, Resource, Timer} import cats.syntax.all._ import fs2.Stream import fs2.concurrent.Queue import io.chrisdavenport.log4cats.Logger import io.chrisdavenport.log4cats.slf4j.Slf4jLogger import org.http4s._ import org.http4s.circe.jsonOf import org.http4s.dsl.Http4sDsl import org.http4s.implicits._ import org.http4s.server.Server import org.http4s.server.blaze.BlazeServerBuilder class Hook[F[_]](queue: Queue[F, Update]) { def updates: Stream[F, Update] = queue.dequeue } object Hook { private def listenServer[F[_]: ConcurrentEffect: Timer: Logger](port: Int): Resource[F, Hook[F]] = { val dsl = Http4sDsl[F] import dsl._ def app(queue: Queue[F, Update]): HttpApp[F] = HttpRoutes .of[F] { case req @ POST -> Root => req .decodeWith(jsonOf[F, Update], strict = true)(queue.enqueue1(_) *> Ok()) .recoverWith { case InvalidMessageBodyFailure(details, _) => F.error(s"Received unknown type of update. $details") *> Ok() } } .orNotFound def server(queue: Queue[F, Update]): Resource[F, Server[F]] = BlazeServerBuilder[F].bindHttp(port).withHttpApp(app(queue)).resource Resource.suspend(Queue.unbounded[F, Update].map(q => server(q).map(_ => new Hook[F](q)))) } }
Example 30
Source File: HttpMetricsSpec.scala From kamon-http4s with Apache License 2.0 | 5 votes |
package kamon.http4s import cats.effect._ import kamon.testkit.InstrumentInspection import org.http4s.HttpRoutes import org.http4s.dsl.io._ import org.http4s.server.Server import org.http4s.server.blaze.BlazeServerBuilder import org.scalatest.concurrent.Eventually import org.scalatest.time.SpanSugar import org.scalatest.{Matchers, OptionValues, WordSpec} import cats.implicits._ import kamon.http4s.middleware.server.KamonSupport import kamon.instrumentation.http.HttpServerMetrics import org.http4s.client.blaze.BlazeClientBuilder import org.http4s.client.Client import scala.concurrent.ExecutionContext import org.http4s.implicits._ class HttpMetricsSpec extends WordSpec with Matchers with Eventually with SpanSugar with InstrumentInspection.Syntax with OptionValues { implicit val contextShift: ContextShift[IO] = IO.contextShift(ExecutionContext.global) implicit val timer: Timer[IO] = IO.timer(ExecutionContext.global) val srv = BlazeServerBuilder[IO] .bindLocal(43567) .withHttpApp(KamonSupport(HttpRoutes.of[IO] { case GET -> Root / "tracing" / "ok" => Ok("ok") case GET -> Root / "tracing" / "not-found" => NotFound("not-found") case GET -> Root / "tracing" / "error" => InternalServerError("This page will generate an error!") }, "/127.0.0.1", 43567).orNotFound) .resource val client = BlazeClientBuilder[IO](ExecutionContext.global).withMaxTotalConnections(10).resource val metrics = Resource.liftF(IO(HttpServerMetrics.of("http4s.server", "/127.0.0.1", 43567))) def withServerAndClient[A](f: (Server[IO], Client[IO], HttpServerMetrics.HttpServerInstruments) => IO[A]): A = (srv, client, metrics).tupled.use(f.tupled).unsafeRunSync() private def get[F[_]: ConcurrentEffect](path: String)(server: Server[F], client: Client[F]): F[String] = { client.expect[String](s"http://127.0.0.1:${server.address.getPort}$path") } "The HttpMetrics" should { "track the total of active requests" in withServerAndClient { (server, client, serverMetrics) => val requests = List .fill(100) { get("/tracing/ok")(server, client) }.parSequence_ val test = IO { serverMetrics.activeRequests.distribution().max should be > 1L serverMetrics.activeRequests.distribution().min shouldBe 0L } requests *> test } "track the response time with status code 2xx" in withServerAndClient { (server, client, serverMetrics) => val requests: IO[Unit] = List.fill(100)(get("/tracing/ok")(server, client)).sequence_ val test = IO(serverMetrics.requestsSuccessful.value should be >= 0L) requests *> test } "track the response time with status code 4xx" in withServerAndClient { (server, client, serverMetrics) => val requests: IO[Unit] = List.fill(100)(get("/tracing/not-found")(server, client).attempt).sequence_ val test = IO(serverMetrics.requestsClientError.value should be >= 0L) requests *> test } "track the response time with status code 5xx" in withServerAndClient { (server, client, serverMetrics) => val requests: IO[Unit] = List.fill(100)(get("/tracing/error")(server, client).attempt).sequence_ val test = IO(serverMetrics.requestsServerError.value should be >= 0L) requests *> test } } }
Example 31
Source File: main.scala From seals with Apache License 2.0 | 5 votes |
package com.example.messaging import scala.concurrent.ExecutionContext.Implicits.global import cats.implicits._ import cats.effect.{ IO, IOApp, ExitCode } import org.http4s._ import org.http4s.dsl.io._ import org.http4s.client.Client import org.http4s.circe._ import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.server.Router import org.http4s.implicits._ import dev.tauri.seals._ import dev.tauri.seals.circe.Codecs._ object Protocol { final case class Ping(seqNr: Long, payload: Vector[Int]) final case class Pong(seqNr: Long) final case class PingIncompatible(seqNr: Long, payload: Vector[Int], flags: Int) } object MyClient extends IOApp { import org.http4s.client.blaze._ import Protocol._ override def run(args: List[String]): IO[ExitCode] = { BlazeClientBuilder[IO](global).resource.use { client => for { pongGood <- ping(client, jsonEncoderOf[IO, Envelope[Ping]].toEntity( Envelope(Ping(42L, Vector(1, 2, 3, 4))) )) _ <- IO { assert(pongGood == Pong(42L)) } _ <- IO { println(pongGood) } pongBad <- ping(client, jsonEncoderOf[IO, Envelope[PingIncompatible]].toEntity( Envelope(PingIncompatible(99L, Vector(4, 5), 0)) )) _ <- IO { println(pongBad) } } yield ExitCode.Success } } def ping(client: Client[IO], ping: Entity[IO]): IO[Pong] = { for { pong <- client .expect(Request( POST, Uri(authority = Some(Uri.Authority(port = Some(1234))), path = "/test"), body = ping.body ))(jsonOf[IO, Envelope[Pong]]) } yield pong.value } } object MyServer extends IOApp { import org.http4s.server.blaze._ import Protocol._ val service = HttpRoutes.of[IO] { case p @ POST -> Root / "test" => for { env <- p.as(implicitly, jsonOf[IO, Envelope[Ping]]) resp <- Ok(Envelope(Pong(env.value.seqNr)))(implicitly, jsonEncoderOf) } yield resp } override def run(args: List[String]): IO[ExitCode] = { BlazeServerBuilder[IO] .bindHttp(1234, "localhost") .withHttpApp(Router("/" -> service).orNotFound) .serve .compile .drain .as(ExitCode.Success) } }
Example 32
Source File: HttpService.scala From iotchain with MIT License | 5 votes |
package jbok.app.service import cats.effect.{ConcurrentEffect, Resource, Timer} import io.circe.Json import cats.implicits._ import fs2._ import javax.net.ssl.SSLContext import jbok.network.http.server.middleware.{CORSMiddleware, GzipMiddleware, LoggerMiddleware, MetricsMiddleware} import jbok.core.config.ServiceConfig import jbok.core.api._ import jbok.crypto.ssl.SSLConfig import jbok.network.rpc.RpcService import jbok.network.rpc.http.Http4sRpcServer import org.http4s.HttpRoutes import org.http4s.implicits._ import org.http4s.server.{SSLClientAuthMode, Server} import org.http4s.server.blaze.BlazeServerBuilder final class HttpService[F[_]]( config: ServiceConfig, sslConfig: SSLConfig, account: AccountAPI[F], admin: AdminAPI[F], block: BlockAPI[F], contract: ContractAPI[F], miner: MinerAPI[F], personal: PersonalAPI[F], transaction: TransactionAPI[F], sslOpt: Option[SSLContext] )(implicit F: ConcurrentEffect[F], T: Timer[F]) { import jbok.codec.impl.circe._ import _root_.io.circe.generic.auto._ import jbok.codec.json.implicits._ val rpcService: RpcService[F, Json] = { var service = RpcService[F, Json] if (config.apis.contains("account")) service = service.mount(account) else () if (config.apis.contains("admin")) service = service.mount(admin) else () if (config.apis.contains("block")) service = service.mount(block) else () if (config.apis.contains("contract")) service = service.mount(contract) else () if (config.apis.contains("miner")) service = service.mount(miner) else () if (config.apis.contains("personal")) service = service.mount(personal) else () if (config.apis.contains("transaction")) service = service.mount(transaction) else () service } val routes: HttpRoutes[F] = Http4sRpcServer.routes(rpcService) private val builder: F[BlazeServerBuilder[F]] = { val httpApp = for { exportRoute <- MetricsMiddleware.exportService[F] withMetrics <- MetricsMiddleware[F](routes, config.enableMetrics) withLogger = LoggerMiddleware[F](config.logHeaders, config.logBody)((withMetrics <+> exportRoute).orNotFound) withCORS = CORSMiddleware[F](withLogger, config.allowedOrigins) app = GzipMiddleware[F](withCORS) } yield app val builder = httpApp.map { app => BlazeServerBuilder[F] .withHttpApp(app) .withNio2(true) .enableHttp2(config.enableHttp2) .withWebSockets(config.enableWebsockets) .bindHttp(config.port, config.local) } val sslLClientAuthMode = sslConfig.clientAuth match { case "NotRequested" => SSLClientAuthMode.NotRequested case "Requested" => SSLClientAuthMode.Requested case "Required" => SSLClientAuthMode.Requested case x => throw new IllegalArgumentException(s"SSLClientAuthMode ${x} is not supported") } sslOpt match { case Some(ssl) => builder.map(_.withSSLContext(ssl, sslLClientAuthMode)) case None => builder.map(_.enableHttp2(false)) } } val resource: Resource[F, Server[F]] = Resource.liftF(builder).flatMap(_.resource) val stream: Stream[F, Unit] = if (config.enable) { Stream.eval(builder).flatMap(_.serve).drain } else { Stream.empty } }