org.http4s.Method Scala Examples
The following examples show how to use org.http4s.Method.
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: HealthCheckRoutes.scala From http4s-poc-api with MIT License | 5 votes |
package server import cats.effect.Sync import log.effect.LogWriter import model.DomainModel._ import org.http4s.dsl.Http4sDsl import org.http4s.{EntityEncoder, HttpRoutes, Method} import cats.syntax.flatMap._ sealed abstract class HealthCheckRoutes[F[_]: Sync]( implicit responseEncoder: EntityEncoder[F, ServiceSignature] ) extends Http4sDsl[F] { def make(log: LogWriter[F]): HttpRoutes[F] = HttpRoutes.of[F] { case Method.GET -> Root => log.debug(s"Serving HealthCheck request") >> Ok(serviceSignature) } private val serviceSignature = ServiceSignature( name = BuildInfo.name, version = BuildInfo.version, scalaVersion = BuildInfo.scalaVersion, scalaOrganization = BuildInfo.scalaOrganization, buildTime = BuildInfo.buildTime ) } object HealthCheckRoutes { def apply[F[_]: Sync: EntityEncoder[*[_], ServiceSignature]]: HealthCheckRoutes[F] = new HealthCheckRoutes[F] {} }
Example 2
Source File: ListBuckets.scala From aws4s with MIT License | 5 votes |
package org.aws4s.s3 import cats.effect.Effect import org.aws4s._ import org.http4s.{EntityDecoder, Method} import cats.implicits._ import fs2.Stream import org.aws4s.core.ExtraEntityDecoderInstances private[s3] case class ListBuckets[F[_]: Effect]( region: Region ) extends S3ServiceCommand[F, ListBucketsSuccess] { override val action: Method = Method.GET override val payload: F[Stream[F, Byte]] = (Stream.empty: Stream[F, Byte]).pure[F] } case class ListBucketsSuccess( buckets: List[BucketName] ) object ListBucketsSuccess { implicit def entityDecoder[F[_]: Effect]: EntityDecoder[F, ListBucketsSuccess] = ExtraEntityDecoderInstances.fromXml { elem => if (elem.label == "ListAllMyBucketsResult") (elem \ "Buckets" \ "Bucket").toList.traverse(BucketName.parse) map { buckets => ListBucketsSuccess(buckets) } else None } }
Example 3
Source File: S3ServiceCommand.scala From aws4s with MIT License | 5 votes |
package org.aws4s.s3 import cats.effect.Effect import cats.implicits._ import fs2._ import org.aws4s.PayloadSigning import org.aws4s.core.{Command, Param, RenderedParam, ServiceName} import org.http4s.headers.Host import org.http4s.{EntityDecoder, Headers, Method, Request, Uri} private[aws4s] abstract class S3ServiceCommand[F[_]: Effect, R: EntityDecoder[F, ?]] extends Command[F, Nothing, R] { override final val serviceName: ServiceName = ServiceName.S3 val action: Method val payload: F[Stream[F, Byte]] override final val payloadSigning: PayloadSigning = PayloadSigning.Signed override final val params: List[Param[Nothing]] = List.empty override final val validator: Command.Validator[Nothing] = _ => None override final val requestGenerator: List[RenderedParam[Nothing]] => F[Request[F]] = { _ => val host = s"s3.${region.name}.amazonaws.com" val uri = Uri.unsafeFromString(s"https://$host/").withPath("/") payload map { p => Request[F](action, uri, headers = Headers(Host(host))).withBodyStream(p) } } }
Example 4
Source File: PutObject.scala From aws4s with MIT License | 5 votes |
package org.aws4s.s3 import cats.effect.Effect import org.aws4s.{PayloadSigning, _} import org.http4s.Method import fs2.Stream private[aws4s] case class PutObject[F[_]: Effect]( region: Region, bucketName: BucketName, objectPath: ObjectPath, obj: F[Stream[F, Byte]], payloadSigning: PayloadSigning ) extends S3ObjectCommand[F, Unit] { override val action: Method = Method.PUT override val payload: F[Stream[F, Byte]] = obj }
Example 5
Source File: S3ObjectCommand.scala From aws4s with MIT License | 5 votes |
package org.aws4s.s3 import cats.effect.Effect import org.aws4s.core.{Command, Param, RenderedParam, ServiceName} import org.http4s.{EntityDecoder, Headers, Method, Request, Uri} import fs2._ import org.http4s.headers.Host import cats.implicits._ private[aws4s] abstract class S3ObjectCommand[F[_]: Effect, R: EntityDecoder[F, ?]] extends Command[F, Nothing, R] { override final val serviceName: ServiceName = ServiceName.S3 val action: Method val bucketName: BucketName val objectPath: ObjectPath val payload: F[Stream[F, Byte]] override final val params: List[Param[Nothing]] = List.empty override final val validator: Command.Validator[Nothing] = _ => None override final val requestGenerator: List[RenderedParam[Nothing]] => F[Request[F]] = { _ => val host = s"${bucketName.value}.s3.${region.name}.amazonaws.com" val uri = Uri.unsafeFromString(s"https://$host/").withPath(objectPath.value) for { pStream <- payload pBytes <- pStream.compile.toVector r <- Request[F](action, uri, headers = Headers(Host(host))).withBody(pBytes.toArray) } yield r } }
Example 6
Source File: DynamoDbCommand.scala From aws4s with MIT License | 5 votes |
package org.aws4s.dynamodb import cats.effect.Effect import io.circe.{Decoder, Json} import org.aws4s.PayloadSigning import org.http4s.headers.{Host, `Content-Type`} import org.http4s.{Header, Headers, MediaType, Method, Request, Uri} import org.http4s.circe._ import cats.implicits._ import org.aws4s.core.ExtraEntityDecoderInstances._ import org.aws4s.core.{Command, CommandPayload, RenderedParam, ServiceName} private[dynamodb] abstract class DynamoDbCommand[F[_]: Effect, R: Decoder] extends Command[F, Json, R] { override def serviceName: ServiceName = ServiceName.DynamoDb override def payloadSigning: PayloadSigning = PayloadSigning.Signed def action: String override final val requestGenerator: List[RenderedParam[Json]] => F[Request[F]] = params => { val host = s"dynamodb.${region.name}.amazonaws.com" val payload: Json = CommandPayload.jsonObject(params) Request[F]( Method.POST, Uri.unsafeFromString(s"https://$host/"), headers = Headers(Header("X-Amz-Target", s"DynamoDB_20120810.$action"), Host(host)) ).withBody(payload).map(_.withContentType(`Content-Type`.apply(MediaType.fromKey(("application", "x-amz-json-1.0"))))) } }
Example 7
Source File: SqsCommand.scala From aws4s with MIT License | 5 votes |
package org.aws4s.sqs import cats.effect.Effect import org.http4s.headers.Host import org.http4s.{EntityDecoder, Headers, Method, Request, UrlForm} import org.aws4s._ import org.aws4s.core.Command.Validator import org.aws4s.core.{Command, RenderedParam, ServiceName} private[sqs] abstract class SqsCommand[F[_]: Effect, R: EntityDecoder[F, ?]] extends Command[F, String, R] { val q: Queue val action: String override final val serviceName: ServiceName = ServiceName.Sqs override final val payloadSigning: PayloadSigning = PayloadSigning.Signed override final val region: Region = q.region override final val validator: Validator[String] = _ => None override final val requestGenerator: List[RenderedParam[String]] => F[Request[F]] = { params => val body = params.map(p => (p.name, p.value)).foldLeft(UrlForm())((form, newPair) => form + newPair) + ("Action" -> action) Request[F](Method.POST, q.uri, headers = Headers(Host(q.host))).withBody[UrlForm](body) } }
Example 8
Source File: KmsCommand.scala From aws4s with MIT License | 5 votes |
package org.aws4s.kms import cats.effect.Effect import cats.implicits._ import io.circe.{Decoder, Json} import org.aws4s.core.ExtraEntityDecoderInstances._ import org.aws4s._ import org.aws4s.core.{Command, CommandPayload, RenderedParam, ServiceName} import org.http4s.circe._ import org.http4s.headers.{Host, `Content-Type`} import org.http4s.{Header, Headers, MediaType, Method, Request, Uri} private[kms] abstract class KmsCommand[F[_]: Effect, R: Decoder] extends Command[F, Json, R] { override def serviceName: ServiceName = ServiceName.Kms override def payloadSigning: PayloadSigning = PayloadSigning.Signed def action: String override final val requestGenerator: List[RenderedParam[Json]] => F[Request[F]] = { params => val host = s"kms.${region.name}.amazonaws.com" val payload: Json = CommandPayload.jsonObject(params) Request[F]( Method.POST, Uri.unsafeFromString(s"https://$host/"), headers = Headers(Header("X-Amz-Target", s"TrentService.$action"), Host(host)) ).withBody(payload).map(_.withContentType(`Content-Type`.apply(MediaType.fromKey(("application", "x-amz-json-1.1"))))) } }
Example 9
Source File: MicrometerHttp4sMetricsOpsModuleTest.scala From scala-server-toolkit with MIT License | 5 votes |
package com.avast.sst.http4s.server.micrometer import java.util.concurrent.TimeUnit import cats.effect.IO import io.micrometer.core.instrument.simple.SimpleMeterRegistry import org.http4s.{Method, Status} import org.scalatest.funsuite.AnyFunSuite class MicrometerHttp4sMetricsOpsModuleTest extends AnyFunSuite { test("http4s MetricsOps for Micrometer") { val registry = new SimpleMeterRegistry() val metricsOps = MicrometerHttp4sMetricsOpsModule.make[IO](registry).unsafeRunSync() metricsOps.increaseActiveRequests(None).unsafeRunSync() metricsOps.recordTotalTime(Method.GET, Status.Ok, 2500, None).unsafeRunSync() assert(registry.get("http.global.active-requests").gauge().value() === 1) assert(registry.get("http.global.total-time").timer().count() === 1) assert(registry.get("http.global.total-time").timer().totalTime(TimeUnit.NANOSECONDS) > 2499) assert(registry.get("http.global.total-time").tags("status", "200").timer().count() === 1) assert(registry.get("http.global.total-time").tags("status-class", "2xx").timer().count() === 1) } }
Example 10
Source File: MicrometerHttp4sMetricsOpsModule.scala From scala-server-toolkit with MIT License | 5 votes |
package com.avast.sst.http4s.server.micrometer import java.util.concurrent.TimeUnit import cats.effect.Effect import cats.effect.concurrent.Ref import cats.syntax.functor._ import io.micrometer.core.instrument.MeterRegistry import org.http4s.metrics.{MetricsOps, TerminationType} import org.http4s.{Method, Status} object MicrometerHttp4sMetricsOpsModule { def make[F[_]: Effect](meterRegistry: MeterRegistry): F[MetricsOps[F]] = { val F = Effect[F] for { activeRequests <- Ref.of[F, Long](0L) } yield new MetricsOps[F] { private val prefix = "http.global" private val failureTime = meterRegistry.timer(s"$prefix.failure-time") meterRegistry.gauge( s"$prefix.active-requests", activeRequests, (_: Ref[F, Long]) => Effect[F].toIO(activeRequests.get).unsafeRunSync().toDouble ) override def increaseActiveRequests(classifier: Option[String]): F[Unit] = activeRequests.update(_ + 1) override def decreaseActiveRequests(classifier: Option[String]): F[Unit] = activeRequests.update(_ - 1) override def recordHeadersTime(method: Method, elapsed: Long, classifier: Option[String]): F[Unit] = { F.delay(meterRegistry.timer(s"$prefix.headers-time", "method", method.name).record(elapsed, TimeUnit.NANOSECONDS)) } override def recordTotalTime(method: Method, status: Status, elapsed: Long, classifier: Option[String]): F[Unit] = { F.delay( meterRegistry .timer(s"$prefix.total-time", "status", s"${status.code}", "status-class", s"${status.code / 100}xx") .record(elapsed, TimeUnit.NANOSECONDS) ) } override def recordAbnormalTermination(elapsed: Long, terminationType: TerminationType, classifier: Option[String]): F[Unit] = { F.delay(failureTime.record(elapsed, TimeUnit.NANOSECONDS)) } } } }
Example 11
Source File: PriceRoutes.scala From http4s-poc-api with MIT License | 5 votes |
package server import cats.effect.Sync import cats.syntax.applicativeError._ import cats.syntax.flatMap._ import cats.syntax.functor._ import cats.syntax.show._ import errors.PriceServiceError import errors.PriceServiceError._ import external.library.syntax.response._ import model.DomainModel._ import org.http4s.dsl.Http4sDsl import org.http4s.{EntityDecoder, EntityEncoder, HttpRoutes, Method, Request, Response} import service.PriceService sealed abstract class PriceRoutes[F[_]: Sync]( implicit requestDecoder: EntityDecoder[F, PricesRequestPayload], responseEncoder: EntityEncoder[F, List[Price]] ) extends Http4sDsl[F] { def make(priceService: PriceService[F]): HttpRoutes[F] = HttpRoutes.of[F] { case req @ Method.POST -> Root => postResponse(req, priceService) handlingFailures priceServiceErrors handleErrorWith unhandledThrowable } private[this] def postResponse(request: Request[F], priceService: PriceService[F]): F[Response[F]] = for { payload <- request.as[PricesRequestPayload] prices <- priceService.prices(payload.userId, payload.productIds) resp <- Ok(prices) } yield resp private[this] def priceServiceErrors: PriceServiceError => F[Response[F]] = { case UserErr(r) => FailedDependency(r) case PreferenceErr(r) => FailedDependency(r) case ProductErr(r) => FailedDependency(r) case ProductPriceErr(r) => FailedDependency(r) case CacheLookupError(r) => FailedDependency(r) case CacheStoreError(r) => FailedDependency(r) case InvalidShippingCountry(r) => BadRequest(r) } private[this] def unhandledThrowable: Throwable => F[Response[F]] = { th => import external.library.instances.throwable._ InternalServerError(th.show) } } object PriceRoutes { def apply[ F[_]: Sync: EntityDecoder[*[_], PricesRequestPayload]: EntityEncoder[*[_], List[Price]] ]: PriceRoutes[F] = new PriceRoutes[F] {} }
Example 12
Source File: Http4sRpcTransport.scala From iotchain with MIT License | 5 votes |
package jbok.network.rpc.http import cats.effect.ConcurrentEffect import jbok.network.rpc.{RpcRequest, RpcResponse, RpcTransport} import org.http4s.client.blaze.BlazeClientBuilder import org.http4s.{EntityDecoder, EntityEncoder, Method, Request, Uri} import scala.concurrent.ExecutionContext final class Http4sRpcTransport[F[_], P]( baseUri: Uri )(implicit F: ConcurrentEffect[F], entityEncoder: EntityEncoder[F, P], entityDecoder: EntityDecoder[F, RpcResponse[P]]) extends RpcTransport[F, P] { override def fetch(request: RpcRequest[P]): F[RpcResponse[P]] = { val uri = request.path.foldLeft(baseUri)(_ / _) val req = Request[F](Method.POST, uri = uri).withEntity(request.payload) BlazeClientBuilder[F](ExecutionContext.global).resource.use { client => client.fetchAs[RpcResponse[P]](req) } } }
Example 13
Source File: AdserverHttpClientBuilder.scala From scala-openrtb with Apache License 2.0 | 5 votes |
package com.powerspace.openrtb.examples.rtb.http4s.adserver import com.google.openrtb.{BidRequest, BidResponse} import com.powerspace.openrtb.examples.rtb.http4s.common.ExampleSerdeModule import com.powerspace.openrtb.json.SerdeModule import io.circe.{Decoder, Encoder} import monix.eval.Task import org.http4s.Uri.{Authority, RegName, Scheme} import org.http4s.client.Client import org.http4s.{EntityDecoder, EntityEncoder, Method, Request, Uri} object AdserverHttpClientBuilder { import org.http4s.circe._ val serdeModule: SerdeModule = ExampleSerdeModule implicit val bidRequestEncoder: Encoder[BidRequest] = serdeModule.bidRequestEncoder implicit val bidRequestEntityEncoder: EntityEncoder[Task, BidRequest] = jsonEncoderOf[Task, BidRequest] implicit val bidResponseDecoder: Decoder[BidResponse] = serdeModule.bidResponseDecoder implicit val bidResponseEntityDecoder: EntityDecoder[Task, BidResponse] = jsonOf[Task, BidResponse] def bid(client: Client[Task], bidRequest: BidRequest): Task[Option[BidResponse]] = { val url = Uri( scheme = Some(Scheme.http), authority = Some(Authority(host = RegName("localhost"), port = Some(9000))), path = "/bid" ) val httpRequest = Request[Task]( method = Method.POST, uri = url ).withEntity[BidRequest](bidRequest) client.expectOption[BidResponse](httpRequest) } }
Example 14
Source File: DefaultMetricsOps.scala From datadog4s with MIT License | 5 votes |
package com.avast.datadog4s.extension.http4s.impl import java.time.Duration import cats.effect.Sync import cats.effect.concurrent.Ref import cats.syntax.flatMap._ import com.avast.datadog4s.api.MetricFactory import com.avast.datadog4s.api.tag.Tagger import com.avast.datadog4s.extension.http4s.DatadogMetricsOps.ClassifierTags import com.avast.datadog4s.extension.http4s._ import com.github.ghik.silencer.silent import org.http4s.metrics.{ MetricsOps, TerminationType } import org.http4s.{ Method, Status } private[http4s] class DefaultMetricsOps[F[_]]( metricFactory: MetricFactory[F], classifierTags: ClassifierTags, activeConnectionsRef: Ref[F, ActiveConnections] )(implicit F: Sync[F] ) extends MetricsOps[F] { private[this] val methodTagger = Tagger.make[Method]("method") @deprecated("please use terminationTypeTagger - this will be removed in next release 0.8.0", "0.6.3") private[this] val typeTagger = Tagger.make[TerminationType]("type") private[this] val terminationTypeTagger = Tagger.make[TerminationType]("termination_type") private[this] val statusCodeTagger = Tagger.make[Status]("status_code") private[this] val statusBucketTagger = Tagger.make[String]("status_bucket") private[this] val activeRequests = metricFactory.gauge.long("active_requests") override def increaseActiveRequests(classifier: Option[String]): F[Unit] = modifyActiveRequests(classifier, 0, 1) override def decreaseActiveRequests(classifier: Option[String]): F[Unit] = // if we try to decrement non existing classifier, make sure it's zero modifyActiveRequests(classifier, 1, -1) private def modifyActiveRequests(classifier: Option[String], default: Int, delta: Int): F[Unit] = activeConnectionsRef.modify { activeConnections => val current = activeConnections.getOrElse(classifier, default) val next = current + delta val nextActiveConnections = activeConnections.updated(classifier, next) val action = activeRequests.set( next.toLong, classifier.toList.flatMap(classifierTags): _* ) (nextActiveConnections, action) }.flatten private[this] val headersTime = metricFactory.timer("headers_time") override def recordHeadersTime(method: Method, elapsed: Long, classifier: Option[String]): F[Unit] = headersTime .record( Duration.ofNanos(elapsed), methodTagger.tag(method) :: classifier.toList.flatMap(classifierTags): _* ) private[this] val requestCount = metricFactory.count("requests_count") private[this] val requestLatency = metricFactory.timer("requests_latency") override def recordTotalTime(method: Method, status: Status, elapsed: Long, classifier: Option[String]): F[Unit] = { val tags = methodTagger.tag(method) :: statusBucketTagger.tag(s"${status.code / 100}xx") :: statusCodeTagger.tag(status) :: classifier.toList.flatMap(classifierTags) requestCount.inc(tags: _*) >> requestLatency.record(Duration.ofNanos(elapsed), tags: _*) } private[this] val abnormalCount = metricFactory.count("abnormal_count") private[this] val abnormalLatency = metricFactory.timer("abnormal_latency") override def recordAbnormalTermination( elapsed: Long, terminationType: TerminationType, classifier: Option[String] ): F[Unit] = { val terminationTpe = terminationTypeTagger.tag(terminationType) @silent("deprecated") val tpe = typeTagger.tag(terminationType) val tags = tpe :: terminationTpe :: classifier.toList.flatMap(classifierTags) abnormalCount.inc(tags: _*) >> abnormalLatency.record(Duration.ofNanos(elapsed), tags: _*) } }
Example 15
Source File: InfluxClient.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.cli.clients import cats.effect.{Sync, Timer} import cats.implicits._ import ch.epfl.bluebrain.nexus.cli._ import ch.epfl.bluebrain.nexus.cli.config.influx.InfluxConfig import ch.epfl.bluebrain.nexus.cli.config.{AppConfig, EnvConfig} import io.circe.Json import org.http4s.client.Client import org.http4s.{Method, Request, UrlForm} trait InfluxClient[F[_]] { final def apply[F[_]: Sync: Timer]( client: Client[F], config: AppConfig, console: Console[F] ): InfluxClient[F] = { implicit val c: Console[F] = console new LiveInfluxDbClient[F](client, config.influx, config.env) } }
Example 16
Source File: TestClient.scala From franklin with Apache License 2.0 | 5 votes |
package com.azavea.franklin.api import cats.effect.Resource import cats.effect.Sync import cats.implicits._ import com.azavea.franklin.api.services.{CollectionItemsService, CollectionsService} import com.azavea.stac4s.{StacCollection, StacItem} import eu.timepit.refined.auto._ import io.circe.syntax._ import org.http4s.circe.CirceEntityDecoder._ import org.http4s.circe.CirceEntityEncoder._ import org.http4s.implicits._ import org.http4s.{Method, Request, Uri} import java.net.URLEncoder import java.nio.charset.StandardCharsets class TestClient[F[_]: Sync]( collectionsService: CollectionsService[F], collectionItemsService: CollectionItemsService[F] ) { private def createCollection(collection: StacCollection): F[StacCollection] = collectionsService.routes.orNotFound.run( Request( method = Method.POST, uri = Uri.unsafeFromString("/collections") ).withEntity(collection.asJson) ) flatMap { _.as[StacCollection] } private def deleteCollection(collection: StacCollection): F[Unit] = { val encodedCollectionId = URLEncoder.encode(collection.id, StandardCharsets.UTF_8.toString) collectionsService.routes.orNotFound .run( Request( method = Method.DELETE, uri = Uri.unsafeFromString(s"/collections/$encodedCollectionId") ) ) .void } private def createItemInCollection(collection: StacCollection, item: StacItem): F[StacItem] = { val encodedCollectionId = URLEncoder.encode(collection.id, StandardCharsets.UTF_8.toString) collectionItemsService.routes.orNotFound.run( Request( method = Method.POST, uri = Uri.unsafeFromString(s"/collections/$encodedCollectionId/items") ).withEntity(item) ) flatMap { _.as[StacItem] } } private def deleteItemInCollection(collection: StacCollection, item: StacItem): F[Unit] = { val encodedCollectionId = URLEncoder.encode(collection.id, StandardCharsets.UTF_8.toString) val encodedItemId = URLEncoder.encode(item.id, StandardCharsets.UTF_8.toString) collectionItemsService.routes.orNotFound .run( Request( method = Method.DELETE, uri = Uri.unsafeFromString(s"/collections/$encodedCollectionId/items/$encodedItemId") ) ) .void } def getItemResource(collection: StacCollection, item: StacItem): Resource[F, StacItem] = Resource.make(createItemInCollection(collection, item.copy(collection = Some(collection.id))))( item => deleteItemInCollection(collection, item) ) def getCollectionResource(collection: StacCollection): Resource[F, StacCollection] = Resource.make(createCollection(collection))(collection => deleteCollection(collection)) def getCollectionItemResource( item: StacItem, collection: StacCollection ): Resource[F, (StacItem, StacCollection)] = (getItemResource(collection, item), getCollectionResource(collection)).tupled }
Example 17
Source File: CollectionsServiceSpec.scala From franklin with Apache License 2.0 | 5 votes |
package com.azavea.franklin.api.services import cats.data.OptionT import cats.effect.IO import cats.implicits._ import com.azavea.franklin.Generators import com.azavea.franklin.api.{TestClient, TestServices} import com.azavea.franklin.database.TestDatabaseSpec import com.azavea.franklin.datamodel.CollectionsResponse import com.azavea.stac4s.StacCollection import com.azavea.stac4s.testing._ import org.http4s.circe.CirceEntityDecoder._ import org.http4s.{Method, Request, Uri} import org.specs2.{ScalaCheck, Specification} import java.net.URLEncoder import java.nio.charset.StandardCharsets class CollectionsServiceSpec extends Specification with ScalaCheck with TestDatabaseSpec with Generators { def is = s2""" This specification verifies that the collections service can run without crashing The collections service should: - create and delete collections $createDeleteCollectionExpectation - list collections $listCollectionsExpectation - get collections by id $getCollectionsExpectation """ val testServices: TestServices[IO] = new TestServices[IO](transactor) val testClient: TestClient[IO] = new TestClient[IO](testServices.collectionsService, testServices.collectionItemsService) def listCollectionsExpectation = prop { (stacCollectionA: StacCollection, stacCollectionB: StacCollection) => { val listIO = ( testClient.getCollectionResource(stacCollectionA), testClient.getCollectionResource(stacCollectionB) ).tupled use { _ => val request = Request[IO](method = Method.GET, Uri.unsafeFromString(s"/collections")) (for { resp <- testServices.collectionsService.routes.run(request) decoded <- OptionT.liftF { resp.as[CollectionsResponse] } } yield decoded).value } val result = listIO.unsafeRunSync.get.collections map { _.id } (result must contain(stacCollectionA.id)) and (result must contain(stacCollectionB.id)) } } def getCollectionsExpectation = prop { (stacCollection: StacCollection) => val fetchIO = testClient.getCollectionResource(stacCollection) use { collection => val encodedId = URLEncoder.encode(collection.id, StandardCharsets.UTF_8.toString) val request = Request[IO](method = Method.GET, Uri.unsafeFromString(s"/collections/$encodedId")) (for { resp <- testServices.collectionsService.routes.run(request) decoded <- OptionT.liftF { resp.as[StacCollection] } } yield (decoded, collection)).value } val (fetched, inserted) = fetchIO.unsafeRunSync.get fetched must beTypedEqualTo(inserted) } // since creation / deletion is a part of the collection resource, and accurate creation is checked // in getCollectionsExpectation, this test just makes sure that if other tests are failing, it's // not because create/delete are broken def createDeleteCollectionExpectation = prop { (stacCollection: StacCollection) => (testClient .getCollectionResource(stacCollection) use { _ => IO.unit }).unsafeRunSync must beTypedEqualTo( () ) } }
Example 18
Source File: JoexClient.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.joexapi.client import scala.concurrent.ExecutionContext import cats.effect._ import cats.implicits._ import docspell.common.syntax.all._ import docspell.common.{Ident, LenientUri} import docspell.joexapi.model.BasicResult import org.http4s.circe.CirceEntityDecoder._ import org.http4s.client.Client import org.http4s.client.blaze.BlazeClientBuilder import org.http4s.{Method, Request, Uri} import org.log4s.getLogger trait JoexClient[F[_]] { def notifyJoex(base: LenientUri): F[Unit] def notifyJoexIgnoreErrors(base: LenientUri): F[Unit] def cancelJob(base: LenientUri, job: Ident): F[BasicResult] } object JoexClient { private[this] val logger = getLogger def apply[F[_]: Sync](client: Client[F]): JoexClient[F] = new JoexClient[F] { def notifyJoex(base: LenientUri): F[Unit] = { val notifyUrl = base / "api" / "v1" / "notify" val req = Request[F](Method.POST, uri(notifyUrl)) logger.fdebug(s"Notify joex at ${notifyUrl.asString}") *> client.expect[String](req).map(_ => ()) } def notifyJoexIgnoreErrors(base: LenientUri): F[Unit] = notifyJoex(base).attempt.map { case Right(()) => () case Left(ex) => logger.warn( s"Notifying Joex instance '${base.asString}' failed: ${ex.getMessage}" ) () } def cancelJob(base: LenientUri, job: Ident): F[BasicResult] = { val cancelUrl = base / "api" / "v1" / "job" / job.id / "cancel" val req = Request[F](Method.POST, uri(cancelUrl)) client.expect[BasicResult](req) } private def uri(u: LenientUri): Uri = Uri.unsafeFromString(u.asString) } def resource[F[_]: ConcurrentEffect](ec: ExecutionContext): Resource[F, JoexClient[F]] = BlazeClientBuilder[F](ec).resource.map(apply[F]) }
Example 19
Source File: HttpExistenceClient.scala From scala-steward with Apache License 2.0 | 5 votes |
package org.scalasteward.core.util import cats.effect.{Async, Resource} import cats.implicits._ import com.github.benmanes.caffeine.cache.Caffeine import io.chrisdavenport.log4cats.Logger import org.http4s.client.Client import org.http4s.{Method, Request, Status, Uri} import org.scalasteward.core.application.Config import scalacache.CatsEffect.modes._ import scalacache.caffeine.CaffeineCache import scalacache.{Async => _, _} final class HttpExistenceClient[F[_]](statusCache: Cache[Status])(implicit client: Client[F], logger: Logger[F], mode: Mode[F], F: MonadThrowable[F] ) { def exists(uri: Uri): F[Boolean] = status(uri).map(_ === Status.Ok).handleErrorWith { throwable => logger.debug(throwable)(s"Failed to check if $uri exists").as(false) } private def status(uri: Uri): F[Status] = statusCache.cachingForMemoizeF(uri.renderString)(None) { client.status(Request[F](method = Method.HEAD, uri = uri)) } } object HttpExistenceClient { def create[F[_]](implicit config: Config, client: Client[F], logger: Logger[F], F: Async[F] ): Resource[F, HttpExistenceClient[F]] = { val buildCache = F.delay { CaffeineCache( Caffeine .newBuilder() .maximumSize(16384L) .expireAfterWrite(config.cacheTtl.length, config.cacheTtl.unit) .build[String, Entry[Status]]() ) } Resource.make(buildCache)(_.close().void).map(new HttpExistenceClient[F](_)) } }
Example 20
Source File: ServerSpec.scala From Learn-Scala-Programming with MIT License | 5 votes |
import ch14.{Config, Server} import cats.effect.IO import cats.implicits._ import io.circe.Json import io.circe.literal._ import org.http4s.circe._ import org.http4s.client.blaze.Http1Client import org.http4s.{Method, Request, Status, Uri} import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpec} import org.http4s.server.{Server => Http4sServer} class ServerSpec extends WordSpec with Matchers with BeforeAndAfterAll { private lazy val client = Http1Client[IO]().unsafeRunSync() private lazy val configIO = Config.load("test.conf") private lazy val config = configIO.unsafeRunSync() private lazy val rootUrl = s"http://${config.server.host}:${config.server.port}" private val server: Option[Http4sServer[IO]] = (for { builder <- Server.createServer(configIO) } yield builder.start.unsafeRunSync()).compile.last.unsafeRunSync() override def afterAll(): Unit = { client.shutdown.unsafeRunSync() server.foreach(_.shutdown.unsafeRunSync()) } "The server" should { "get an empty inventory" in { val json = client.expect[Json](s"$rootUrl/inventory").unsafeRunSync() json shouldBe json"""{}""" } "create articles" in { val eggs = Request[IO](method = Method.POST, uri = Uri.unsafeFromString(s"$rootUrl/articles/eggs")) client.status(eggs).unsafeRunSync() shouldBe Status.NoContent val chocolate = Request[IO](method = Method.POST, uri = Uri.unsafeFromString(s"$rootUrl/articles/chocolate")) client.status(chocolate).unsafeRunSync() shouldBe Status.NoContent val json = client.expect[Json](s"$rootUrl/inventory").unsafeRunSync() json shouldBe json"""{"eggs" : 0,"chocolate" : 0}""" } "update inventory" in { val restock = Request[IO](method = Method.POST, uri = Uri.unsafeFromString(s"$rootUrl/restock")).withBody(json"""{ "inventory" : { "eggs": 10, "chocolate": 20 }}""") client.expect[Json](restock).unsafeRunSync() shouldBe json"""{ "eggs" : 10, "chocolate" : 20 }""" client.expect[Json](restock).unsafeRunSync() shouldBe json"""{ "eggs" : 20, "chocolate" : 40 }""" } "deliver purchase if there is enough inventory" in { val purchase = Request[IO](method = Method.POST, uri = Uri.unsafeFromString(s"$rootUrl/purchase")).withBody(json"""{ "order" : { "eggs": 5, "chocolate": 5 }}""") client.expect[Json](purchase).unsafeRunSync() shouldBe json"""{ "eggs" : 5, "chocolate" : 5 }""" } "not deliver purchase if there is not enough inventory" in { val purchase = Request[IO](method = Method.POST, uri = Uri.unsafeFromString(s"$rootUrl/purchase")).withBody(json"""{ "order" : { "eggs": 5, "chocolate": 45 }}""") client.expect[Json](purchase).unsafeRunSync() shouldBe json"""{ "eggs" : 0, "chocolate" : 0 }""" } } }
Example 21
Source File: Github.scala From sonar-scala with GNU Lesser General Public License v3.0 | 5 votes |
package com.mwz.sonar.scala package pr package github import cats.effect.Sync import cats.syntax.flatMap._ import com.mwz.sonar.scala.pr.github.Codec._ import io.circe.generic.auto._ import mouse.boolean._ import org.http4s.client.Client import org.http4s.{Header, Headers, Method, Request, Uri} trait Github[F[_]] { def authenticatedUser: F[User] def pullRequest: F[PullRequest] def comments: F[List[Comment]] def createComment(comment: NewComment): F[Unit] def files: F[List[File]] def createStatus(sha: String, status: NewStatus): F[Unit] } object Github { def apply[F[_]: Sync](client: Client[F], pr: GlobalConfig.PullRequest): Github[F] = new Github[F] { val auth: Header = Header("Authorization", s"token ${pr.github.oauth}") val userUri: Uri = pr.github.apiuri / "user" val prUri: Uri = (pr.github.apiuri / "repos").addPath(pr.github.repository) / "pulls" / pr.prNumber val commentsUri: Uri = prUri / "comments" val filesUri: Uri = prUri / "files" def newStatusUri(sha: String): Uri = (pr.github.apiuri / "repos").addPath(pr.github.repository) / "statuses" / sha def request(uri: Uri): Request[F] = { Request[F]( uri = uri, headers = Headers.of(auth) ) } def authenticatedUser: F[User] = client.expect[User](request(userUri)) def pullRequest: F[PullRequest] = client.expect[PullRequest](request(prUri)) def comments: F[List[Comment]] = client.expect[List[Comment]](request(commentsUri)) def createComment(comment: NewComment): F[Unit] = { val request: F[Request[F]] = Sync[F].pure( Request(Method.POST, commentsUri, headers = Headers.of(auth)) .withEntity(comment) ) pr.dryRun.fold(Sync[F].unit, client.expect[Comment](request) >> Sync[F].unit) } def files: F[List[File]] = client.expect[List[File]](request(filesUri)) def createStatus(sha: String, status: NewStatus): F[Unit] = { val request: F[Request[F]] = Sync[F].pure( Request(Method.POST, newStatusUri(sha), headers = Headers.of(auth)) .withEntity(status) ) pr.dryRun.fold(Sync[F].unit, client.expect[Status](request) >> Sync[F].unit) } } }
Example 22
Source File: MavenCentralClient.scala From zorechka-bot with MIT License | 5 votes |
package com.wix.zorechka.clients import com.wix.zorechka.Dep import org.http4s.{EntityDecoder, Header, Headers, Method, Request, Uri} import zio.{Task, ZIO} import zio.interop.catz._ import io.circe.generic.auto._ import org.http4s.circe.jsonOf import org.http4s.client.Client trait MavenCentralClient { val client: MavenCentralClient.Service } object MavenCentralClient { trait Service { def allVersions(dep: Dep): Task[List[Dep]] } trait Live extends MavenCentralClient { protected val httpClient: Client[Task] val client = new MavenCentralClient.Service { case class Response(response: InnerResponse) case class InnerResponse(docs: Seq[Document]) case class Document(v: String) implicit val decoder: EntityDecoder[Task, Response] = jsonOf[Task, Response] override def allVersions(dep: Dep): Task[List[Dep]] = { ZIO.accessM { client => val uri = Uri .unsafeFromString("http://search.maven.org/solrsearch/select") .withQueryParam("rows", "10") .withQueryParam("core", "gav") .withQueryParam("q", s""" g:"${dep.groupId}" AND a:"${dep.artifactId}" """) println(s"Maven search: ${uri.renderString}") val request = Request[Task](Method.GET, uri, headers = Headers.of(Header("Accept", "application/json"))) httpClient.fetch(request)(response => response.as[Response]).map { _.response.docs.map(_.v).map(v => Dep(dep.groupId, dep.artifactId, v)).toList } } } } } }