akka.http.scaladsl.model.RequestEntity Scala Examples

The following examples show how to use akka.http.scaladsl.model.RequestEntity. 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: ClickhouseQueryBuilder.scala    From clickhouse-scala-client   with GNU Lesser General Public License v3.0 5 votes vote down vote up
package com.crobox.clickhouse.internal

import akka.http.scaladsl.model.Uri.Query
import akka.http.scaladsl.model.headers.{HttpEncodingRange, RawHeader}
import akka.http.scaladsl.model.{HttpMethods, HttpRequest, RequestEntity, Uri}
import com.crobox.clickhouse.internal.QuerySettings.ReadQueries
import com.crobox.clickhouse.internal.progress.ProgressHeadersAsEventsStage
import com.typesafe.config.Config
import com.typesafe.scalalogging.LazyLogging

import scala.collection.immutable

private[clickhouse] trait ClickhouseQueryBuilder extends LazyLogging {

  private val Headers = {
    import HttpEncodingRange.apply
    import akka.http.scaladsl.model.headers.HttpEncodings.{deflate, gzip}
    import akka.http.scaladsl.model.headers.`Accept-Encoding`
    immutable.Seq(`Accept-Encoding`(gzip, deflate))
  }
  private val MaxUriSize = 16 * 1024

  protected def toRequest(uri: Uri,
                          query: String,
                          queryIdentifier: Option[String],
                          settings: QuerySettings,
                          entity: Option[RequestEntity])(config: Config): HttpRequest = {
    val urlQuery = uri.withQuery(Query(Query("query" -> query) ++ settings.withFallback(config).asQueryParams: _*))
    entity match {
      case Some(e) =>
        logger.debug(s"Executing clickhouse query [$query] on host [${uri
          .toString()}] with entity payload of length ${e.contentLengthOption}")
        HttpRequest(
          method = HttpMethods.POST,
          uri = urlQuery,
          entity = e,
          headers = Headers ++ queryIdentifier.map(RawHeader(ProgressHeadersAsEventsStage.InternalQueryIdentifier, _))
        )
      case None
          if settings.idempotent.contains(true) && settings.readOnly == ReadQueries && urlQuery
            .toString()
            .getBytes
            .length < MaxUriSize => //max url size
        logger.debug(s"Executing clickhouse idempotent query [$query] on host [${uri.toString()}]")
        HttpRequest(
          method = HttpMethods.GET,
          uri = urlQuery.withQuery(
            urlQuery
              .query()
              .filterNot(
                _._1 == "readonly"
              ) //get requests are readonly by default, if we send the readonly flag clickhouse will fail the request
          ),
          headers = Headers ++ queryIdentifier.map(RawHeader(ProgressHeadersAsEventsStage.InternalQueryIdentifier, _))
        )
      case None =>
        logger.debug(s"Executing clickhouse query [$query] on host [${uri.toString()}]")
        HttpRequest(
          method = HttpMethods.POST,
          uri = uri.withQuery(settings.withFallback(config).asQueryParams),
          entity = query,
          headers = Headers ++ queryIdentifier.map(RawHeader(ProgressHeadersAsEventsStage.InternalQueryIdentifier, _))
        )
    }
  }

} 
Example 2
Source File: AkkaHttpMarshallingSuite.scala    From telegram   with Apache License 2.0 5 votes vote down vote up
package com.bot4s.telegram.marshalling

import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.RequestEntity
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.testkit.ScalatestRouteTest
import akka.util.ByteString
import com.bot4s.telegram.api.TestUtils
import com.bot4s.telegram.marshalling.AkkaHttpMarshalling.underscore_case_marshaller
import com.bot4s.telegram.methods.SendDocument
import com.bot4s.telegram.models.{AkkaInputFile, InputFile}
import org.scalatest.{FunSuite, Matchers}

class AkkaHttpMarshallingSuite extends FunSuite with ScalatestRouteTest with Matchers with TestUtils {

  test("Correctly serialize top-level string members in Akka multipart requests") {
    val captionWithLineBreak = "this is a line\nand then\t another line"
    val channelId = "this_is_a_channel"
    val fileId = "and_a_file_id"

    val entity = SendDocument(channelId, InputFile(fileId), caption = Some(captionWithLineBreak))
    Post("/", Marshal(entity).to[RequestEntity]) ~> {
      formFields(('caption, 'chat_id, 'document)) {
        (caption, chat_id, document) => complete(caption + chat_id + document)
      }
    } ~> check {
      responseAs[String] shouldEqual (captionWithLineBreak + channelId + fileId)
    }
  }

  test("Handles AkkaInputFile") {
    val channelId = "this_is_a_channel"
    val content = "file content"
    val entity = SendDocument(channelId, AkkaInputFile("Pepe", ByteString(content)))
    Post("/", Marshal(entity).to[RequestEntity]) ~> {
      formFields('document) {
        document => complete(document)
      }
    } ~> check {
      responseAs[ByteString] shouldEqual ByteString(content)
    }
  }
} 
Example 3
Source File: AkkaBodyBuilder.scala    From chronicler   with Apache License 2.0 5 votes vote down vote up
package com.github.fsanaulla.chronicler.akka.shared.handlers

import java.nio.file.Path

import akka.http.scaladsl.model.{HttpEntity, MediaTypes, RequestEntity}
import akka.stream.scaladsl.FileIO
import com.github.fsanaulla.chronicler.core.alias.ErrorOr
import com.github.fsanaulla.chronicler.core.components.BodyBuilder
import com.github.fsanaulla.chronicler.core.either
import com.github.fsanaulla.chronicler.core.either.EitherOps
import com.github.fsanaulla.chronicler.core.model.{Appender, InfluxWriter, Point}

class AkkaBodyBuilder extends BodyBuilder[RequestEntity] with Appender {
  override def fromFile(filePath: Path, enc: String): RequestEntity =
    HttpEntity(
      MediaTypes.`application/octet-stream`,
      FileIO
        .fromPath(filePath)
    )

  override def fromString(string: String): RequestEntity =
    HttpEntity(string)

  override def fromStrings(strings: Seq[String]): RequestEntity =
    HttpEntity(strings.mkString("\n"))

  override def fromPoint(point: Point): RequestEntity =
    HttpEntity(point.serialize)

  override def fromPoints(points: Seq[Point]): RequestEntity =
    HttpEntity(points.map(_.serialize).mkString("\n"))

  override def fromT[T](meas: String, t: T)(implicit wr: InfluxWriter[T]): ErrorOr[RequestEntity] =
    wr.write(t).mapRight(append(meas, _))

  override def fromSeqT[T](
      meas: String,
      ts: Seq[T]
    )(implicit wr: InfluxWriter[T]
    ): ErrorOr[RequestEntity] =
    either.seq(ts.map(wr.write)).mapRight(append(meas, _))
} 
Example 4
Source File: AkkaManagementClient.scala    From chronicler   with Apache License 2.0 5 votes vote down vote up
package com.github.fsanaulla.chronicler.akka.management

import _root_.akka.actor.ActorSystem
import _root_.akka.http.scaladsl.HttpsConnectionContext
import akka.http.scaladsl.model.{HttpResponse, RequestEntity, Uri}
import akka.stream.ActorMaterializer
import com.github.fsanaulla.chronicler.akka.shared.InfluxAkkaClient
import com.github.fsanaulla.chronicler.akka.shared.handlers._
import com.github.fsanaulla.chronicler.core.ManagementClient
import com.github.fsanaulla.chronicler.core.alias.ErrorOr
import com.github.fsanaulla.chronicler.core.model._

import scala.concurrent.{ExecutionContext, Future}

final class AkkaManagementClient(
    host: String,
    port: Int,
    credentials: Option[InfluxCredentials],
    httpsContext: Option[HttpsConnectionContext],
    terminateActorSystem: Boolean
  )(implicit val ex: ExecutionContext,
    val system: ActorSystem,
    val F: Functor[Future],
    val FK: FunctionK[Future, Future])
  extends InfluxAkkaClient(terminateActorSystem, httpsContext)
  with ManagementClient[Future, Future, HttpResponse, Uri, RequestEntity] {

  implicit val mat: ActorMaterializer  = ActorMaterializer()
  implicit val qb: AkkaQueryBuilder    = new AkkaQueryBuilder(schema, host, port, credentials)
  implicit val jh: AkkaJsonHandler     = new AkkaJsonHandler(new AkkaBodyUnmarshaller(false))
  implicit val re: AkkaRequestExecutor = new AkkaRequestExecutor(ctx)
  implicit val rh: AkkaResponseHandler = new AkkaResponseHandler(jh)

  override def ping: Future[ErrorOr[InfluxDBInfo]] = {
    re.get(qb.buildQuery("/ping"), compressed = false)
      .flatMap(rh.pingResult)
  }
} 
Example 5
Source File: AkkaMeasurementApi.scala    From chronicler   with Apache License 2.0 5 votes vote down vote up
package com.github.fsanaulla.chronicler.akka.io

import akka.http.scaladsl.model.{HttpResponse, RequestEntity, Uri}
import akka.stream.scaladsl.Source
import com.github.fsanaulla.chronicler.akka.shared.handlers.{
  AkkaQueryBuilder,
  AkkaRequestExecutor,
  AkkaResponseHandler
}
import com.github.fsanaulla.chronicler.core.alias.ErrorOr
import com.github.fsanaulla.chronicler.core.api.MeasurementApi
import com.github.fsanaulla.chronicler.core.components.BodyBuilder
import com.github.fsanaulla.chronicler.core.enums.{Epoch, Epochs}
import com.github.fsanaulla.chronicler.core.model.{Failable, Functor, InfluxReader}

import scala.concurrent.Future
import scala.reflect.ClassTag

final class AkkaMeasurementApi[T: ClassTag](
    dbName: String,
    measurementName: String,
    gzipped: Boolean
  )(implicit qb: AkkaQueryBuilder,
    bd: BodyBuilder[RequestEntity],
    re: AkkaRequestExecutor,
    rh: AkkaResponseHandler,
    F: Functor[Future],
    FA: Failable[Future])
  extends MeasurementApi[Future, Future, HttpResponse, Uri, RequestEntity, T](
    dbName,
    measurementName,
    gzipped
  ) {

  
  def readChunked(
      query: String,
      epoch: Epoch = Epochs.None,
      pretty: Boolean = false,
      chunkSize: Int
    )(implicit rd: InfluxReader[T]
    ): Future[Source[ErrorOr[Array[T]], Any]] = {
    val uri = chunkedQuery(dbName, query, epoch, pretty, chunkSize)
    F.map(re.get(uri, compressed = false))(rh.queryChunkedResult[T])
  }
} 
Example 6
Source File: AkkaIOClient.scala    From chronicler   with Apache License 2.0 5 votes vote down vote up
package com.github.fsanaulla.chronicler.akka.io

import akka.actor.ActorSystem
import akka.http.scaladsl.HttpsConnectionContext
import akka.http.scaladsl.model.{HttpResponse, RequestEntity, Uri}
import akka.stream.ActorMaterializer
import com.github.fsanaulla.chronicler.akka.shared.InfluxAkkaClient
import com.github.fsanaulla.chronicler.akka.shared.handlers._
import com.github.fsanaulla.chronicler.akka.shared.implicits._
import com.github.fsanaulla.chronicler.core.IOClient
import com.github.fsanaulla.chronicler.core.alias.ErrorOr
import com.github.fsanaulla.chronicler.core.model.{InfluxCredentials, InfluxDBInfo}

import scala.concurrent.{ExecutionContext, Future}
import scala.reflect.ClassTag

final class AkkaIOClient(
    host: String,
    port: Int,
    credentials: Option[InfluxCredentials],
    compress: Boolean,
    httpsContext: Option[HttpsConnectionContext],
    terminateActorSystem: Boolean
  )(implicit ex: ExecutionContext,
    system: ActorSystem)
  extends InfluxAkkaClient(terminateActorSystem, httpsContext)
  with IOClient[Future, Future, HttpResponse, Uri, RequestEntity] {

  implicit val mat: ActorMaterializer  = ActorMaterializer()
  implicit val bb: AkkaBodyBuilder     = new AkkaBodyBuilder()
  implicit val qb: AkkaQueryBuilder    = new AkkaQueryBuilder(schema, host, port, credentials)
  implicit val jh: AkkaJsonHandler     = new AkkaJsonHandler(new AkkaBodyUnmarshaller(compress))
  implicit val re: AkkaRequestExecutor = new AkkaRequestExecutor(ctx)
  implicit val rh: AkkaResponseHandler = new AkkaResponseHandler(jh)

  override def database(dbName: String): AkkaDatabaseApi =
    new AkkaDatabaseApi(dbName, compress)

  override def measurement[A: ClassTag](
      dbName: String,
      measurementName: String
    ): AkkaMeasurementApi[A] =
    new AkkaMeasurementApi[A](dbName, measurementName, compress)

  override def ping: Future[ErrorOr[InfluxDBInfo]] = {
    re.get(qb.buildQuery("/ping", Nil), compressed = false)
      .flatMap(rh.pingResult)
  }
} 
Example 7
Source File: AkkaDatabaseApi.scala    From chronicler   with Apache License 2.0 5 votes vote down vote up
package com.github.fsanaulla.chronicler.akka.io

import akka.http.scaladsl.model.{HttpResponse, RequestEntity, Uri}
import akka.stream.scaladsl.Source
import com.github.fsanaulla.chronicler.akka.shared.handlers.{
  AkkaQueryBuilder,
  AkkaRequestExecutor,
  AkkaResponseHandler
}
import com.github.fsanaulla.chronicler.core.alias.{ErrorOr, JPoint}
import com.github.fsanaulla.chronicler.core.api.DatabaseApi
import com.github.fsanaulla.chronicler.core.components.BodyBuilder
import com.github.fsanaulla.chronicler.core.enums.{Epoch, Epochs}
import com.github.fsanaulla.chronicler.core.model.{FunctionK, Functor}

import scala.concurrent.Future

final class AkkaDatabaseApi(
    dbName: String,
    compressed: Boolean
  )(implicit qb: AkkaQueryBuilder,
    bd: BodyBuilder[RequestEntity],
    re: AkkaRequestExecutor,
    rh: AkkaResponseHandler,
    F: Functor[Future],
    FK: FunctionK[Future, Future])
  extends DatabaseApi[Future, Future, HttpResponse, Uri, RequestEntity](dbName, compressed) {

  
  def readChunkedJson(
      query: String,
      epoch: Epoch = Epochs.None,
      pretty: Boolean = false,
      chunkSize: Int
    ): Future[Source[ErrorOr[Array[JPoint]], Any]] = {
    val uri = chunkedQuery(dbName, query, epoch, pretty, chunkSize)
    F.map(re.get(uri, compressed))(rh.queryChunkedResultJson)
  }
} 
Example 8
Source File: EntityUtils.scala    From asura   with MIT License 5 votes vote down vote up
package asura.core.http

import java.net.URLEncoder

import akka.http.scaladsl.model.{ContentType, ContentTypes, HttpEntity, RequestEntity}
import akka.util.ByteString
import asura.common.util.{LogUtils, StringUtils}
import asura.core.es.model.{HttpCaseRequest, KeyValueObject}
import asura.core.http.UriUtils.UTF8
import asura.core.runtime.RuntimeContext
import asura.core.util.JacksonSupport
import com.fasterxml.jackson.core.`type`.TypeReference
import com.typesafe.scalalogging.Logger

object EntityUtils {

  val logger = Logger("EntityUtils")

  def toEntity(cs: HttpCaseRequest, context: RuntimeContext): RequestEntity = {
    val request = cs.request
    var contentType: ContentType = ContentTypes.`text/plain(UTF-8)`
    var byteString: ByteString = ByteString.empty
    if (StringUtils.isNotEmpty(request.contentType) && null != request.body && request.body.nonEmpty) {
      request.contentType match {
        case HttpContentTypes.JSON =>
          contentType = ContentTypes.`application/json`
          val body = request.body.find(_.contentType == HttpContentTypes.JSON)
          if (body.nonEmpty) {
            byteString = ByteString(context.renderBodyAsString(body.get.data))
          }
        case HttpContentTypes.X_WWW_FORM_URLENCODED =>
          contentType = ContentTypes.`application/x-www-form-urlencoded`
          val body = request.body.find(_.contentType == HttpContentTypes.X_WWW_FORM_URLENCODED)
          if (body.nonEmpty) {
            var bodyStr: String = null
            try {
              val sb = StringBuilder.newBuilder
              val params = JacksonSupport.parse(body.get.data, new TypeReference[Seq[KeyValueObject]]() {})
              for (pair <- params if (pair.enabled && StringUtils.isNotEmpty(pair.key))) {
                val rendered = context.renderBodyAsString(pair.value)
                sb.append(pair.key).append("=").append(URLEncoder.encode(rendered, UTF8)).append("&")
              }
              if (sb.nonEmpty) {
                sb.deleteCharAt(sb.length - 1)
              }
              bodyStr = sb.toString
            } catch {
              case t: Throwable =>
                val errLog = LogUtils.stackTraceToString(t)
                logger.warn(errLog)
                bodyStr = errLog
            }
            byteString = ByteString(bodyStr)
          }
        case HttpContentTypes.TEXT_PLAIN =>
          contentType = ContentTypes.`text/plain(UTF-8)`
          val body = request.body.find(_.contentType == HttpContentTypes.TEXT_PLAIN)
          if (body.nonEmpty) {
            byteString = ByteString(context.renderBodyAsString(body.get.data))
          }
        case _ =>
      }
    }
    HttpEntity(contentType, byteString)
  }
} 
Example 9
Source File: ExampleApp.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpcirce

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{ HttpRequest, RequestEntity }
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.Source

import scala.io.StdIn
import scala.concurrent.duration._

object ExampleApp {

  private final case class Foo(bar: String)

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()

    Http().bindAndHandle(route, "127.0.0.1", 8000)

    StdIn.readLine("Hit ENTER to exit")
    system.terminate()
  }

  private def route(implicit sys: ActorSystem) = {
    import Directives._
    import FailFastCirceSupport._
    import io.circe.generic.auto._

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~ pathPrefix("stream") {
      post {
        entity(as[SourceOf[Foo]]) { fooSource: SourceOf[Foo] =>
          import sys._

          Marshal(Source.single(Foo("a"))).to[RequestEntity]

          complete(fooSource.throttle(1, 2.seconds))
        }
      } ~ get {
        pathEndOrSingleSlash {
          complete(
            Source(0 to 5)
              .throttle(1, 1.seconds)
              .map(i => Foo(s"bar-$i"))
          )
        } ~ pathPrefix("remote") {
          onSuccess(Http().singleRequest(HttpRequest(uri = "http://localhost:8000/stream"))) {
            response => complete(Unmarshal(response).to[SourceOf[Foo]])
          }
        }
      }
    }
  }
} 
Example 10
Source File: ExampleApp.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpavro4s

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{ HttpRequest, RequestEntity }
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.Source
import com.sksamuel.avro4s.{ FromRecord, SchemaFor, ToRecord }

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.io.StdIn

object ExampleApp {

  final object Foo {
    implicit val schemaFor  = SchemaFor[Foo]
    implicit val toRecord   = ToRecord[Foo]
    implicit val fromRecord = FromRecord[Foo]
  }
  final case class Foo(bar: String)

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()

    Http().bindAndHandle(route, "127.0.0.1", 8000)

    StdIn.readLine("Hit ENTER to exit")
    Await.ready(system.terminate(), Duration.Inf)
  }

  def route(implicit sys: ActorSystem) = {
    import AvroSupport._
    import Directives._

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~ pathPrefix("stream") {
      post {
        entity(as[SourceOf[Foo]]) { fooSource: SourceOf[Foo] =>
          import sys._

          Marshal(Source.single(Foo("a"))).to[RequestEntity]

          complete(fooSource.throttle(1, 2.seconds))
        }
      } ~ get {
        pathEndOrSingleSlash {
          complete(
            Source(0 to 5)
              .throttle(1, 1.seconds)
              .map(i => Foo(s"bar-$i"))
          )
        } ~ pathPrefix("remote") {
          onSuccess(Http().singleRequest(HttpRequest(uri = "http://localhost:8000/stream"))) {
            response => complete(Unmarshal(response).to[SourceOf[Foo]])
          }
        }
      }
    }
  }
} 
Example 11
Source File: ExampleApp.scala    From akka-http-json   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.akkahttpargonaut

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{ HttpRequest, RequestEntity }
import akka.http.scaladsl.server.Directives
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.scaladsl.Source
import argonaut.Argonaut.casecodec1
import argonaut.CodecJson

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.io.StdIn

object ExampleApp {

  final object Foo {
    implicit val fooCodec: CodecJson[Foo] =
      casecodec1(Foo.apply, Foo.unapply)("bar")
  }
  final case class Foo(bar: String)

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()

    Http().bindAndHandle(route, "127.0.0.1", 8000)

    StdIn.readLine("Hit ENTER to exit")
    Await.ready(system.terminate(), Duration.Inf)
  }

  def route(implicit sys: ActorSystem) = {
    import ArgonautSupport._
    import Directives._

    pathSingleSlash {
      post {
        entity(as[Foo]) { foo =>
          complete {
            foo
          }
        }
      }
    } ~ pathPrefix("stream") {
      post {
        entity(as[SourceOf[Foo]]) { fooSource: SourceOf[Foo] =>
          import sys._

          Marshal(Source.single(Foo("a"))).to[RequestEntity]

          complete(fooSource.throttle(1, 2.seconds))
        }
      } ~ get {
        pathEndOrSingleSlash {
          complete(
            Source(0 to 5)
              .throttle(1, 1.seconds)
              .map(i => Foo(s"bar-$i"))
          )
        } ~ pathPrefix("remote") {
          onSuccess(Http().singleRequest(HttpRequest(uri = "http://localhost:8000/stream"))) {
            response => complete(Unmarshal(response).to[SourceOf[Foo]])
          }
        }
      }
    }
  }
} 
Example 12
Source File: ModelServiceSpec.scala    From full-scala-stack   with Apache License 2.0 5 votes vote down vote up
package api

import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.{ContentType, ContentTypes, HttpEntity, HttpResponse, MessageEntity, RequestEntity}
import akka.http.scaladsl.testkit.ScalatestRouteTest
import dao.{CRUDOperations, MockRepository, Repository}
import de.heikoseeberger.akkahttpupickle.UpickleSupport
import mail.{CourierPostman, Postman}
import model.{SampleModelObject, SimpleSearch}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import routes.{ModelRoutes, SampleModelObjectRoute}
import upickle.default._
import util.ModelPickler
import zio.{IO, ZIO}
import zioslick.RepositoryException

import scala.concurrent.ExecutionContext


class ModelServiceSpec
  extends AnyWordSpec
    with Matchers
    with ScalatestRouteTest
    with ZIODirectives
  with UpickleSupport
    with ModelPickler
 {

  val objects = Seq(
    SampleModelObject(0, "Zero"),
    SampleModelObject(1, "One"),
    SampleModelObject(2, "Two"),
    SampleModelObject(3, "Three"),
    SampleModelObject(4, "Four"),
  )

  val service = new SampleModelObjectRoute  with MockRepository with CourierPostman with Config {
    override def repository: Repository.Service = new Repository.Service {
      override val sampleModelObjectOps: CRUDOperations[SampleModelObject, Int, SimpleSearch, Any] = new MockOps {
        override def search(search: Option[SimpleSearch])(
          implicit session: Any
        ): IO[RepositoryException, Seq[SampleModelObject]] = ZIO.succeed(objects)
        override def get(pk: Int)(implicit session: Any): IO[RepositoryException, Option[SampleModelObject]] =
          ZIO.succeed(objects.headOption)

      }
    }
  }

  //TODO test your route here, we would probably not have a test like the one below in reality, since it's super simple.
  "The Service" should  {
    "return one objects on a get" in {
      Get("/sampleModelObject/1") ~> service.crudRoute.route("") ~> check {
        val res = responseAs[Seq[SampleModelObject]].headOption

        println(res)
        res shouldEqual objects.headOption
      }
    }
    "return some objects on a search" in {
      Post("/sampleModelObject/search", HttpEntity(ContentTypes.`application/json`, write(SimpleSearch()))) ~> service.crudRoute.route("") ~> check {
        val str = responseAs[ujson.Value]
        val res = responseAs[Seq[SampleModelObject]]

        println(res)
        res shouldEqual objects
      }
    }
  }
}