diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0ab108f..370d112 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,9 +9,9 @@ name: Continuous Integration on: pull_request: - branches: ['*'] + branches: ['**'] push: - branches: ['*'] + branches: ['**'] tags: [v*] env: @@ -33,7 +33,7 @@ jobs: fetch-depth: 0 - name: Setup Java and Scala - uses: olafurpg/setup-scala@v10 + uses: olafurpg/setup-scala@v12 with: java-version: ${{ matrix.java }} @@ -50,10 +50,10 @@ jobs: key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} - name: Check that workflows are up to date - run: sbt ++${{ matrix.scala }} githubWorkflowCheck + run: sbt --client '++${{ matrix.scala }}; githubWorkflowCheck' - name: Build project - run: sbt ++${{ matrix.scala }} test + run: sbt --client '++${{ matrix.scala }}; test' - name: Compress target directories run: tar cf targets.tar modules/s3/target target modules/sqs-refined/target modules/sqs/target modules/s3-testing/target modules/core/target project/target @@ -81,7 +81,7 @@ jobs: fetch-depth: 0 - name: Setup Java and Scala - uses: olafurpg/setup-scala@v10 + uses: olafurpg/setup-scala@v12 with: java-version: ${{ matrix.java }} @@ -122,4 +122,4 @@ jobs: PGP_SECRET: ${{ secrets.PGP_SECRET }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - run: sbt ++${{ matrix.scala }} ci-release \ No newline at end of file + run: sbt --client '++${{ matrix.scala }}; ci-release' \ No newline at end of file diff --git a/README.md b/README.md index f3df500..84c925a 100644 --- a/README.md +++ b/README.md @@ -46,17 +46,15 @@ Each one adds enhancements on top of the other, and the base libraries feature b For example, here is how you create an S3 and SQS client: ```scala -import cats.effect.{Blocker, IO} +import cats.effect.{IO, Resource} import com.rewardsnetwork.pureaws.s3.PureS3Client import com.rewardsnetwork.pureaws.sqs.PureSqsClient import software.amazon.awssdk.regions.Region -Blocker[IO].flatMap { blocker => //Everything needs a Blocker - val region = Region.US_EAST_1 +val region = Region.US_EAST_1 - val pureS3clientResource = PureS3Client.async[IO](blocker, region) - val pureSQSclientResource = PureSqsClient.async[IO](blocker, region) -} +val pureS3clientResource: Resource[IO, PureS3Client[IO]] = PureS3Client.async[IO](region) +val pureSQSclientResource: Resource[IO, PureSqsClient[IO]] = PureSqsClient.async[IO](region) ``` The "Pure" clients for each library have Sync/Async variants, based on the underlying AWS client. @@ -79,7 +77,7 @@ For modularity and separation of concerns, we've separated out the client types ```scala import com.rewardsnetwork.pureaws.SimpleS3Client -val s3ClientResource: Resource[IO, SimpleS3Client[IO]] = Blocker[IO].flatMap(SimpleS3Client.async[IO](_, region)) +val s3ClientResource: Resource[IO, SimpleS3Client[IO]] = SimpleS3Client.async[IO](region) s3ClientResource.use { client => ///Access each of the clients within here @@ -95,7 +93,7 @@ Perform basic operations on S3 buckets and objects, available at `SimpleS3Client import com.rewardsnetwork.pureaws.{S3BucketOps, S3ObjectOps} import software.amazon.awssdk.services.s3.model.BucketLocationConstraint -val pureClient: Resource[IO, PureS3Client[IO]] = Blocker[IO].flatMap(PureS3Client.async[IO](_, region)) +val pureClient: Resource[IO, PureS3Client[IO]] = PureS3Client.async[IO](region) val bucketAndObjectOps = pureClient.map(p => S3BucketOps(p) -> S3ObjectOps(p)) bucketAndObjectOps.use { case (bucketOps, objectOps) => @@ -122,7 +120,7 @@ Write S3 objects using S3 (multipart not currently supported), available at `Sim ```scala import com.rewardsnetwork.pureaws.S3Sink -val sinkResource: Resource[IO, S3Sink[IO]] = Blocker[IO].flatMap(S3Sink.async[IO](_, region)) +val sinkResource: Resource[IO, S3Sink[IO]] = S3Sink.async[IO](_, region) sinkResource.use { sink => Stream("hello", "world", "and all who inhabit it") @@ -139,7 +137,7 @@ Stream S3 objects from S3 as bytes, available at `SimpleS3Client#source` or by i ```scala import com.rewardsnetwork.pureaws.S3Source -val sourceResource: Resource[IO, S3Source[IO]] = Blocker[IO].flatMap(S3Source.async[IO](_, region)) +val sourceResource: Resource[IO, S3Source[IO]] = S3Source.async[IO](region) Stream.resource(sourceResource).flatMap { source => //Stream bytes from an object @@ -169,7 +167,7 @@ The preferred way to use `pureaws-sqs` is to pull in the Simple client with an A ```scala import com.rewardsnetwork.pureaws.sqs.SimpleSqsClient -val client: Resource[IO, SimpleSqsClient[IO]] = SimpleSqsClient.async[IO](blocker, region) +val client: Resource[IO, SimpleSqsClient[IO]] = SimpleSqsClient.async[IO](region) client.use { c => c.streamMessages("url-to-my-queue", maxMessages = 10).take(3).compile.drain.as(ExitCode.Success) } diff --git a/build.sbt b/build.sbt index 36fefe8..bd6228a 100644 --- a/build.sbt +++ b/build.sbt @@ -1,15 +1,14 @@ //Core deps -val amazonV = "2.16.67" +val amazonV = "2.17.11" val catsV = "2.6.1" -val catsEffectV = "2.5.1" -val fs2V = "2.5.6" +val catsEffectV = "3.2.1" +val fs2V = "3.0.6" val log4catsV = "1.2.0" val refinedV = "0.9.25" -val monixV = "3.4.0" -val collectionCompatV = "2.4.4" +val collectionCompatV = "2.5.0" val catsCore = "org.typelevel" %% "cats-core" % catsV -val catsEffect = "org.typelevel" %% "cats-effect" % catsEffectV +val catsEffect = "org.typelevel" %% "cats-effect-std" % catsEffectV val fs2Core = "co.fs2" %% "fs2-core" % fs2V val fs2Io = "co.fs2" %% "fs2-io" % fs2V val fs2ReactiveStreams = "co.fs2" %% "fs2-reactive-streams" % fs2V @@ -17,7 +16,6 @@ val awsSdkCore = "software.amazon.awssdk" % "sdk-core" % amazonV val awsSQS = "software.amazon.awssdk" % "sqs" % amazonV val awsS3 = "software.amazon.awssdk" % "s3" % amazonV val refined = "eu.timepit" %% "refined" % refinedV -val monixCatnap = "io.monix" %% "monix-catnap" % monixV val collectionCompat = "org.scala-lang.modules" %% "scala-collection-compat" % collectionCompatV @@ -107,7 +105,6 @@ lazy val sqs = (project in file("modules/sqs")) libraryDependencies ++= Seq( //Core deps awsSQS, - monixCatnap, //Test deps catsEffectLaws ) @@ -132,7 +129,6 @@ lazy val s3 = (project in file("modules/s3")) //Core deps awsS3, fs2Io, - monixCatnap, //Test deps catsEffectLaws ) diff --git a/modules/core/src/main/scala/com/rewardsnetwork/pureaws/Fs2AsyncResponseTransformer.scala b/modules/core/src/main/scala/com/rewardsnetwork/pureaws/Fs2AsyncResponseTransformer.scala index c0277ea..9fc1698 100644 --- a/modules/core/src/main/scala/com/rewardsnetwork/pureaws/Fs2AsyncResponseTransformer.scala +++ b/modules/core/src/main/scala/com/rewardsnetwork/pureaws/Fs2AsyncResponseTransformer.scala @@ -3,10 +3,9 @@ package com.rewardsnetwork.pureaws import java.nio.ByteBuffer import java.util.concurrent.CompletableFuture -import fs2.Stream +import cats.effect.kernel.Async +import fs2.{Chunk, Stream} import software.amazon.awssdk.core.async.{AsyncResponseTransformer, SdkPublisher} -import fs2.Chunk -import cats.effect.ConcurrentEffect /** An implementation of the `AsyncResponseTransformer` interface, but using FS2 Stream */ trait Fs2AsyncResponseTransformer[F[_], A] extends AsyncResponseTransformer[A, (A, Stream[F, Byte])] { @@ -22,7 +21,7 @@ trait Fs2AsyncResponseTransformer[F[_], A] extends AsyncResponseTransformer[A, ( object Fs2AsyncResponseTransformer { /** Creates an `Fs2AsyncResponseTransformer` that returns your response object as well as a stream of bytes. */ - def apply[F[_]: ConcurrentEffect, A]: Fs2AsyncResponseTransformer[F, A] = + def apply[F[_]: Async, A]: Fs2AsyncResponseTransformer[F, A] = new Fs2AsyncResponseTransformer[F, A] { private val cf: CompletableFuture[Stream[F, Byte]] = new CompletableFuture[Stream[F, Byte]]() diff --git a/modules/core/src/test/scala/com/rewardsnetwork/pureaws/Fs2AsyncResponseTransformerSpec.scala b/modules/core/src/test/scala/com/rewardsnetwork/pureaws/Fs2AsyncResponseTransformerSpec.scala index 0f9bd53..273b334 100644 --- a/modules/core/src/test/scala/com/rewardsnetwork/pureaws/Fs2AsyncResponseTransformerSpec.scala +++ b/modules/core/src/test/scala/com/rewardsnetwork/pureaws/Fs2AsyncResponseTransformerSpec.scala @@ -1,18 +1,18 @@ package com.rewardsnetwork.pureaws +import java.nio.ByteBuffer + import cats.effect.IO import fs2.interop.reactivestreams._ import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers import software.amazon.awssdk.core.internal.async.SdkPublishers -import scala.concurrent.ExecutionContext.global -import java.nio.ByteBuffer import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks +import cats.effect.unsafe.IORuntime class Fs2AsyncResponseTransformerSpec extends AnyFreeSpec with Matchers with ScalaCheckPropertyChecks { - implicit val cs = IO.contextShift(global) - implicit val timer = IO.timer(global) + implicit val iort = IORuntime.global "Fs2AsyncResponseTransformer" - { "should provide the stream of bytes to the user" in { @@ -21,17 +21,28 @@ class Fs2AsyncResponseTransformerSpec extends AnyFreeSpec with Matchers with Sca val exampleStrByteBuf = ByteBuffer.wrap(exampleStrBytes) val transformer = Fs2AsyncResponseTransformer[IO, String] val fs2publisher = fs2.Stream.emit[IO, ByteBuffer](exampleStrByteBuf).toUnicastPublisher - val sdkPublisher = SdkPublishers.envelopeWrappedPublisher(fs2publisher, "", "") - val cf = transformer.prepare() - //Use the transformer the way the SDK would - transformer.onResponse(exampleStr) - transformer.onStream(sdkPublisher) + val program = fs2publisher.use { p => + val sdkPublisher = SdkPublishers.envelopeWrappedPublisher(p, "", "") + val cf = transformer.prepare() + + //Use the transformer the way the SDK would + transformer.onResponse(exampleStr) + transformer.onStream(sdkPublisher) + + //Get and test results + val (str, byteStream) = cf.get() + str shouldBe exampleStr + byteStream.compile + .to(Array) + .flatMap(bytes => + IO { + bytes shouldBe exampleStrBytes + } + ) + } - //Get and test results - val (str, byteStream) = cf.get() - str shouldBe exampleStr - byteStream.compile.to(Array).unsafeRunSync() shouldBe exampleStrBytes + program.unsafeRunSync() } } } diff --git a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/S3TestingBackend.scala b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/S3TestingBackend.scala index ce5e6c5..950e59c 100644 --- a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/S3TestingBackend.scala +++ b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/S3TestingBackend.scala @@ -4,8 +4,8 @@ import java.time.Instant import cats.data.OptionT import cats.effect.Sync -import cats.effect.concurrent.Ref -import cats.implicits._ +import cats.effect.kernel.Ref +import cats.syntax.all._ import internal.newInstant import S3TestingBackend._ diff --git a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3BucketOps.scala b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3BucketOps.scala index b99e5ad..4325ed2 100644 --- a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3BucketOps.scala +++ b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3BucketOps.scala @@ -1,7 +1,7 @@ package com.rewardsnetwork.pureaws.s3.testing import cats._ -import cats.implicits._ +import cats.syntax.all._ import com.rewardsnetwork.pureaws.s3.{S3BucketPermission, S3BucketOps} import software.amazon.awssdk.services.s3.model._ import com.rewardsnetwork.pureaws.s3.S3BucketInfo diff --git a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3ObjectOps.scala b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3ObjectOps.scala index c36973d..c174ed7 100644 --- a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3ObjectOps.scala +++ b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3ObjectOps.scala @@ -3,7 +3,7 @@ package com.rewardsnetwork.pureaws.s3.testing import java.time.Instant import cats._ -import cats.implicits._ +import cats.syntax.all._ import com.rewardsnetwork.pureaws.s3._ import fs2.Stream import software.amazon.awssdk.services.s3.model.RequestPayer diff --git a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3Sink.scala b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3Sink.scala index 74506e9..47930a0 100644 --- a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3Sink.scala +++ b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3Sink.scala @@ -1,7 +1,7 @@ package com.rewardsnetwork.pureaws.s3.testing import cats.effect.Sync -import cats.implicits._ +import cats.syntax.all._ import com.rewardsnetwork.pureaws.s3.S3Sink import fs2.{Pipe, Stream} diff --git a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3Source.scala b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3Source.scala index 00cece4..5bd5071 100644 --- a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3Source.scala +++ b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3Source.scala @@ -2,7 +2,7 @@ package com.rewardsnetwork.pureaws.s3.testing import cats.Applicative import cats.effect.Sync -import cats.implicits._ +import cats.syntax.all._ import com.rewardsnetwork.pureaws.s3.S3Source import fs2.Stream diff --git a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestSimpleS3Client.scala b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestSimpleS3Client.scala index 083be85..393e499 100644 --- a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestSimpleS3Client.scala +++ b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/TestSimpleS3Client.scala @@ -1,7 +1,7 @@ package com.rewardsnetwork.pureaws.s3.testing import cats.effect._ -import cats.implicits._ +import cats.syntax.all._ /** All available test helpers for S3 at once. */ sealed trait TestSimpleS3Client[F[_]] { diff --git a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/internal.scala b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/internal.scala index 3ad3a7d..ec1472f 100644 --- a/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/internal.scala +++ b/modules/s3-testing/src/main/scala/com/rewardsnetwork/pureaws/s3/testing/internal.scala @@ -1,7 +1,8 @@ package com.rewardsnetwork.pureaws.s3.testing import java.time.Instant -import cats.effect.Sync + +import cats.effect.kernel.Sync object internal { def newInstant[F[_]: Sync]: F[Instant] = Sync[F].delay(Instant.now()) diff --git a/modules/s3-testing/src/test/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3ObjectOpsSpec.scala b/modules/s3-testing/src/test/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3ObjectOpsSpec.scala index 8d5f754..1edf7b3 100644 --- a/modules/s3-testing/src/test/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3ObjectOpsSpec.scala +++ b/modules/s3-testing/src/test/scala/com/rewardsnetwork/pureaws/s3/testing/TestS3ObjectOpsSpec.scala @@ -1,17 +1,19 @@ package com.rewardsnetwork.pureaws.s3.testing +import java.time.Instant + +import cats.Traverse +import cats.effect.unsafe.IORuntime import cats.effect.IO import cats.syntax.all._ import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import org.scalacheck.Gen -import com.rewardsnetwork.pureaws.s3.S3ObjectInfo -import java.time.Instant -import com.rewardsnetwork.pureaws.s3.S3ObjectListing -import cats.Traverse +import com.rewardsnetwork.pureaws.s3.{S3ObjectInfo, S3ObjectListing} class TestS3ObjectOpsSpec extends AnyFreeSpec with Matchers with ScalaCheckPropertyChecks { + implicit val iort = IORuntime.global "TestS3ObjectOps" - { "listObjectsPaginated" - { diff --git a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/PureS3Client.scala b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/PureS3Client.scala index d9e3e64..1741797 100644 --- a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/PureS3Client.scala +++ b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/PureS3Client.scala @@ -4,10 +4,9 @@ import java.io.InputStream import java.nio.ByteBuffer import java.util.concurrent.CompletableFuture -import cats.effect._ +import cats.effect.kernel.{Async, Sync, Resource} import com.rewardsnetwork.pureaws.Fs2AsyncResponseTransformer import fs2.Stream -import monix.catnap.syntax._ import software.amazon.awssdk.core.ResponseBytes import software.amazon.awssdk.core.async.{AsyncRequestBody, AsyncResponseTransformer} import software.amazon.awssdk.core.sync.RequestBody @@ -123,13 +122,12 @@ object PureS3Client { /** Builds a PureS3Client from an AWS SDK `S3Client`. * - * @param blocker A Cats Effect `Blocker` for handling potentially blocking operations. * @param client A synchronous `S3Client` directly from the AWS SDK. * @return A shiny new `PureS3Client` with a synchronous backend. */ - def apply[F[_]: Sync: ContextShift](blocker: Blocker, client: S3Client) = + def apply[F[_]: Sync](client: S3Client) = new PureS3Client[F] { - private def block[A](f: => A): F[A] = blocker.blockOn(Sync[F].delay(f)) + private def block[A](f: => A): F[A] = Sync[F].blocking(f) def abortMultipartUpload(r: AbortMultipartUploadRequest): F[AbortMultipartUploadResponse] = { block(client.abortMultipartUpload(r)) @@ -149,7 +147,7 @@ object PureS3Client { def getObjectStream(r: GetObjectRequest): Stream[F, Byte] = { val res: F[InputStream] = block(client.getObject(r)) - fs2.io.readInputStream(res, 4096, blocker, closeAfterUse = true) + fs2.io.readInputStream(res, 4096, closeAfterUse = true) } def getObjectBytes(r: GetObjectRequest): F[ResponseBytes[GetObjectResponse]] = { @@ -187,9 +185,9 @@ object PureS3Client { * @param client An asynchronous `S3AsyncClient` directly from the AWS SDK. * @return A shiny new `PureS3Client` with an asynchronous backend. */ - def apply[F[_]: ConcurrentEffect](client: S3AsyncClient) = + def apply[F[_]: Async](client: S3AsyncClient) = new PureS3Client[F] { - private def lift[A](f: => CompletableFuture[A]): F[A] = Sync[F].delay(f).futureLift + private def lift[A](f: => CompletableFuture[A]): F[A] = Async[F].fromCompletableFuture(Sync[F].delay(f)) def abortMultipartUpload(r: AbortMultipartUploadRequest): F[AbortMultipartUploadResponse] = { lift(client.abortMultipartUpload(r)) @@ -246,45 +244,35 @@ object PureS3Client { /** Creates a `PureS3Client` using a synchronous backend with default settings. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `Resource` containing a `PureS3Client` using a synchronous backend. */ - def sync[F[_]: Sync: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, PureS3Client[F]] = - S3ClientBackend.sync[F](blocker, awsRegion)().map(apply[F](blocker, _)) + def sync[F[_]: Sync](awsRegion: Region): Resource[F, PureS3Client[F]] = + S3ClientBackend.sync[F](awsRegion)().map(apply[F](_)) /** Creates a `PureS3Client` using a synchronous backend with default settings. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `Resource` containing a `PureS3Client` using a synchronous backend. */ - def syncIn[F[_]: Sync: ContextShift, G[_]: Sync: ContextShift]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, PureS3Client[G]] = - S3ClientBackend.sync[F](blocker, awsRegion)().map(apply[G](blocker, _)) + def syncIn[F[_]: Sync, G[_]: Sync](awsRegion: Region): Resource[F, PureS3Client[G]] = + S3ClientBackend.sync[F](awsRegion)().map(apply[G](_)) /** Creates a `PureS3Client` using an asynchronous backend with default settings. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `Resource` containing a `PureS3Client` using an asynchronous backend. */ - def async[F[_]: ConcurrentEffect: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, PureS3Client[F]] = - S3ClientBackend.async[F](blocker, awsRegion)().map(apply[F]) + def async[F[_]: Async](awsRegion: Region): Resource[F, PureS3Client[F]] = + S3ClientBackend.async[F](awsRegion)().map(apply[F]) /** Creates a `PureS3Client` using an asynchronous backend with default settings. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `Resource` containing a `PureS3Client` using an asynchronous backend. */ - def asyncIn[F[_]: Sync: ContextShift, G[_]: ConcurrentEffect]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, PureS3Client[G]] = - S3ClientBackend.async[F](blocker, awsRegion)().map(apply[G]) + def asyncIn[F[_]: Sync, G[_]: Async](awsRegion: Region): Resource[F, PureS3Client[G]] = + S3ClientBackend.async[F](awsRegion)().map(apply[G]) } diff --git a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3BucketOps.scala b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3BucketOps.scala index 44d074a..a7a8506 100644 --- a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3BucketOps.scala +++ b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3BucketOps.scala @@ -1,8 +1,8 @@ package com.rewardsnetwork.pureaws.s3 import cats.Functor -import cats.effect._ -import cats.implicits._ +import cats.effect.kernel._ +import cats.syntax.all._ import com.rewardsnetwork.pureaws.s3.S3BucketPermission._ import software.amazon.awssdk.regions.Region import software.amazon.awssdk.services.s3.model._ @@ -83,45 +83,35 @@ object S3BucketOps { /** Constructs an `S3BucketOps` using an underlying synchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3BucketOps` instance using a synchronous backend. */ - def sync[F[_]: Sync: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, S3BucketOps[F]] = - PureS3Client.sync[F](blocker, awsRegion).map(apply[F]) + def sync[F[_]: Sync](awsRegion: Region): Resource[F, S3BucketOps[F]] = + PureS3Client.sync[F](awsRegion).map(apply[F]) /** Constructs an `S3BucketOps` using an underlying synchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3BucketOps` instance using a synchronous backend. */ - def syncIn[F[_]: Sync: ContextShift, G[_]: Sync: ContextShift]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, S3BucketOps[G]] = - PureS3Client.syncIn[F, G](blocker, awsRegion).map(apply[G]) + def syncIn[F[_]: Sync, G[_]: Sync](awsRegion: Region): Resource[F, S3BucketOps[G]] = + PureS3Client.syncIn[F, G](awsRegion).map(apply[G]) /** Constructs an `S3BucketOps` using an underlying asynchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3BucketOps` instance using an asynchronous backend. */ - def async[F[_]: ConcurrentEffect: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, S3BucketOps[F]] = - PureS3Client.async[F](blocker, awsRegion).map(apply[F]) + def async[F[_]: Async](awsRegion: Region): Resource[F, S3BucketOps[F]] = + PureS3Client.async[F](awsRegion).map(apply[F]) /** Constructs an `S3BucketOps` using an underlying asynchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3BucketOps` instance using an asynchronous backend. */ - def asyncIn[F[_]: Sync: ContextShift, G[_]: ConcurrentEffect]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, S3BucketOps[G]] = - PureS3Client.asyncIn[F, G](blocker, awsRegion).map(apply[G]) + def asyncIn[F[_]: Sync, G[_]: Async](awsRegion: Region): Resource[F, S3BucketOps[G]] = + PureS3Client.asyncIn[F, G](awsRegion).map(apply[G]) } diff --git a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ClientBackend.scala b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ClientBackend.scala index f22f3be..8affa2d 100644 --- a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ClientBackend.scala +++ b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ClientBackend.scala @@ -1,6 +1,6 @@ package com.rewardsnetwork.pureaws.s3 -import cats.effect._ +import cats.effect.kernel._ import software.amazon.awssdk.regions.Region import software.amazon.awssdk.services.s3.{S3Client, S3ClientBuilder, S3AsyncClient, S3AsyncClientBuilder} @@ -13,15 +13,14 @@ object S3ClientBackend { * You can configure your client before it is created using the `configure` function parameter * if you want to set anything other than your region. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you will be operating in. * @param configure A function to configure your client before it is built and returned to you. * @return A configured `S3Client` as a `Resource` that will close itself after use. */ - def sync[F[_]: Sync: ContextShift](blocker: Blocker, awsRegion: Region)( - configure: S3ClientBuilder => S3ClientBuilder = identity - ): Resource[F, S3Client] = - Resource.fromAutoCloseableBlocking(blocker)(Sync[F].delay { + def sync[F[_]: Sync]( + awsRegion: Region + )(configure: S3ClientBuilder => S3ClientBuilder = identity): Resource[F, S3Client] = + Resource.fromAutoCloseable(Sync[F].delay { configure(S3Client.builder().region(awsRegion)).build() }) @@ -31,15 +30,14 @@ object S3ClientBackend { * You can configure your client before it is created using the `configure` function parameter * if you want to set anything other than your region. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you will be operating in. * @param configure A function to configure your client before it is built and returned to you. * @return A configured `S3AsyncClient` as a `Resource` that will close itself after use. */ - def async[F[_]: Sync: ContextShift](blocker: Blocker, awsRegion: Region)( - configure: S3AsyncClientBuilder => S3AsyncClientBuilder = identity - ): Resource[F, S3AsyncClient] = - Resource.fromAutoCloseableBlocking(blocker)(Sync[F].delay { + def async[F[_]: Sync]( + awsRegion: Region + )(configure: S3AsyncClientBuilder => S3AsyncClientBuilder = identity): Resource[F, S3AsyncClient] = + Resource.fromAutoCloseable(Sync[F].delay { configure(S3AsyncClient.builder().region(awsRegion)).build() }) } diff --git a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ObjectOps.scala b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ObjectOps.scala index d9c43e9..4a5058e 100644 --- a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ObjectOps.scala +++ b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ObjectOps.scala @@ -1,7 +1,7 @@ package com.rewardsnetwork.pureaws.s3 import cats.Monad -import cats.effect._ +import cats.effect.kernel._ import cats.syntax.all._ import fs2.Stream import software.amazon.awssdk.regions.Region @@ -87,7 +87,8 @@ object S3ObjectOps { def copyObject(oldBucket: String, oldKey: String, newBucket: String, newKey: String): F[Unit] = { val req = CopyObjectRequest .builder() - .copySource(s"$oldBucket/$oldKey") + .sourceBucket(oldBucket) + .sourceKey(oldKey) .destinationBucket(newBucket) .destinationKey(newKey) .build() @@ -155,45 +156,35 @@ object S3ObjectOps { /** Constructs an `S3ObjectOps` using an underlying synchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3ObjectOps` instance using a synchronous backend. */ - def sync[F[_]: Sync: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, S3ObjectOps[F]] = - PureS3Client.sync[F](blocker, awsRegion).map(apply[F]) + def sync[F[_]: Sync](awsRegion: Region): Resource[F, S3ObjectOps[F]] = + PureS3Client.sync[F](awsRegion).map(apply[F]) /** Constructs an `S3ObjectOps` using an underlying synchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3ObjectOps` instance using a synchronous backend. */ - def syncIn[F[_]: Sync: ContextShift, G[_]: Sync: ContextShift]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, S3ObjectOps[G]] = - PureS3Client.syncIn[F, G](blocker, awsRegion).map(apply[G]) + def syncIn[F[_]: Sync, G[_]: Sync](awsRegion: Region): Resource[F, S3ObjectOps[G]] = + PureS3Client.syncIn[F, G](awsRegion).map(apply[G]) /** Constructs an `S3ObjectOps` using an underlying asynchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3ObjectOps` instance using an asynchronous backend. */ - def async[F[_]: ConcurrentEffect: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, S3ObjectOps[F]] = - PureS3Client.async[F](blocker, awsRegion).map(apply[F]) + def async[F[_]: Async](awsRegion: Region): Resource[F, S3ObjectOps[F]] = + PureS3Client.async[F](awsRegion).map(apply[F]) /** Constructs an `S3ObjectOps` using an underlying asynchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3ObjectOps` instance using an asynchronous backend. */ - def asyncIn[F[_]: Sync: ContextShift, G[_]: ConcurrentEffect]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, S3ObjectOps[G]] = - PureS3Client.asyncIn[F, G](blocker, awsRegion).map(apply[G]) + def asyncIn[F[_]: Sync, G[_]: Async](awsRegion: Region): Resource[F, S3ObjectOps[G]] = + PureS3Client.asyncIn[F, G](awsRegion).map(apply[G]) } diff --git a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ObjectOwner.scala b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ObjectOwner.scala index d4a85b4..5224832 100644 --- a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ObjectOwner.scala +++ b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3ObjectOwner.scala @@ -10,6 +10,7 @@ import software.amazon.awssdk.services.s3.model.Owner final case class S3ObjectOwner(ownerDisplayName: String, ownerId: String) object S3ObjectOwner { + /** Turn an `s3.model.Owner` into an `S3ObjectOwner` given owner of the object. * * @param owner The `s3.model.Owner` you are turning into an `S3ObjectOwner`. diff --git a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3Sink.scala b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3Sink.scala index 5375c41..a5e97e7 100644 --- a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3Sink.scala +++ b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3Sink.scala @@ -3,8 +3,8 @@ package com.rewardsnetwork.pureaws.s3 import java.nio.ByteBuffer import cats.ApplicativeError -import cats.effect._ -import cats.implicits._ +import cats.effect.kernel._ +import cats.syntax.all._ import com.rewardsnetwork.pureaws.utils.md5String import fs2.{Pipe, Stream} import software.amazon.awssdk.regions.Region @@ -156,45 +156,35 @@ object S3Sink { /** Constructs an `S3Sink` using an underlying synchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3Sink` instance using a synchronous backend. */ - def sync[F[_]: Sync: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, S3Sink[F]] = - PureS3Client.sync[F](blocker, awsRegion).map(apply[F]) + def sync[F[_]: Sync](awsRegion: Region): Resource[F, S3Sink[F]] = + PureS3Client.sync[F](awsRegion).map(apply[F]) /** Constructs an `S3Sink` using an underlying synchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3Sink` instance using a synchronous backend. */ - def syncIn[F[_]: Sync: ContextShift, G[_]: Sync: ContextShift]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, S3Sink[G]] = - PureS3Client.syncIn[F, G](blocker, awsRegion).map(apply[G]) + def syncIn[F[_]: Sync, G[_]: Sync](awsRegion: Region): Resource[F, S3Sink[G]] = + PureS3Client.syncIn[F, G](awsRegion).map(apply[G]) /** Constructs an `S3Sink` using an underlying asynchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3Sink` instance using an asynchronous backend. */ - def async[F[_]: ConcurrentEffect: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, S3Sink[F]] = - PureS3Client.async[F](blocker, awsRegion).map(apply[F]) + def async[F[_]: Async](awsRegion: Region): Resource[F, S3Sink[F]] = + PureS3Client.async[F](awsRegion).map(apply[F]) /** Constructs an `S3Sink` using an underlying asynchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3Sink` instance using an asynchronous backend. */ - def asyncIn[F[_]: Sync: ContextShift, G[_]: ConcurrentEffect]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, S3Sink[G]] = - PureS3Client.asyncIn[F, G](blocker, awsRegion).map(apply[G]) + def asyncIn[F[_]: Sync, G[_]: Async](awsRegion: Region): Resource[F, S3Sink[G]] = + PureS3Client.asyncIn[F, G](awsRegion).map(apply[G]) } diff --git a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3Source.scala b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3Source.scala index 7927078..7b6e723 100644 --- a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3Source.scala +++ b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/S3Source.scala @@ -1,8 +1,8 @@ package com.rewardsnetwork.pureaws.s3 import cats.Applicative -import cats.implicits._ import cats.effect._ +import cats.syntax.all._ import fs2.Stream import software.amazon.awssdk.regions.Region import software.amazon.awssdk.services.s3.model.GetObjectRequest @@ -72,45 +72,35 @@ object S3Source { /** Constructs an `S3Source` using an underlying synchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3Source` instance using a synchronous backend. */ - def sync[F[_]: Sync: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, S3Source[F]] = - PureS3Client.sync[F](blocker, awsRegion).map(apply[F]) + def sync[F[_]: Sync](awsRegion: Region): Resource[F, S3Source[F]] = + PureS3Client.sync[F](awsRegion).map(apply[F]) /** Constructs an `S3Source` using an underlying synchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3Source` instance using a synchronous backend. */ - def syncIn[F[_]: Sync: ContextShift, G[_]: Sync: ContextShift]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, S3Source[G]] = - PureS3Client.syncIn[F, G](blocker, awsRegion).map(apply[G]) + def syncIn[F[_]: Sync, G[_]: Sync](awsRegion: Region): Resource[F, S3Source[G]] = + PureS3Client.syncIn[F, G](awsRegion).map(apply[G]) /** Constructs an `S3Source` using an underlying asynchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3Source` instance using an asynchronous backend. */ - def async[F[_]: ConcurrentEffect: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, S3Source[F]] = - PureS3Client.async[F](blocker, awsRegion).map(apply[F]) + def async[F[_]: Async](awsRegion: Region): Resource[F, S3Source[F]] = + PureS3Client.async[F](awsRegion).map(apply[F]) /** Constructs an `S3Source` using an underlying asynchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `S3Source` instance using an asynchronous backend. */ - def asyncIn[F[_]: Sync: ContextShift, G[_]: ConcurrentEffect]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, S3Source[G]] = - PureS3Client.asyncIn[F, G](blocker, awsRegion).map(apply[G]) + def asyncIn[F[_]: Sync, G[_]: Async](awsRegion: Region): Resource[F, S3Source[G]] = + PureS3Client.asyncIn[F, G](awsRegion).map(apply[G]) } diff --git a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/SimpleS3Client.scala b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/SimpleS3Client.scala index d60dbe4..37b878e 100644 --- a/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/SimpleS3Client.scala +++ b/modules/s3/src/main/scala/com/rewardsnetwork/pureaws/s3/SimpleS3Client.scala @@ -1,6 +1,6 @@ package com.rewardsnetwork.pureaws.s3 -import cats.effect._ +import cats.effect.kernel._ import cats.MonadError import software.amazon.awssdk.regions.Region @@ -26,45 +26,35 @@ object SimpleS3Client { /** Constructs a `SimpleS3Client` using an underlying synchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `SimpleS3Client` instance using a synchronous backend. */ - def sync[F[_]: Sync: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, SimpleS3Client[F]] = - PureS3Client.sync[F](blocker, awsRegion).map(apply[F]) + def sync[F[_]: Sync](awsRegion: Region): Resource[F, SimpleS3Client[F]] = + PureS3Client.sync[F](awsRegion).map(apply[F]) /** Constructs a `SimpleS3Client` using an underlying synchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `SimpleS3Client` instance using a synchronous backend. */ - def syncIn[F[_]: Sync: ContextShift, G[_]: Sync: ContextShift]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, SimpleS3Client[G]] = - PureS3Client.syncIn[F, G](blocker, awsRegion).map(apply[G]) + def syncIn[F[_]: Sync, G[_]: Sync](awsRegion: Region): Resource[F, SimpleS3Client[G]] = + PureS3Client.syncIn[F, G](awsRegion).map(apply[G]) /** Constructs a `SimpleS3Client` using an underlying asynchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `SimpleS3Client` instance using an asynchronous backend. */ - def async[F[_]: ConcurrentEffect: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, SimpleS3Client[F]] = - PureS3Client.async[F](blocker, awsRegion).map(apply[F]) + def async[F[_]: Async](awsRegion: Region): Resource[F, SimpleS3Client[F]] = + PureS3Client.async[F](awsRegion).map(apply[F]) /** Constructs a `SimpleS3Client` using an underlying asynchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `SimpleS3Client` instance using an asynchronous backend. */ - def asyncIn[F[_]: Sync: ContextShift, G[_]: ConcurrentEffect]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, SimpleS3Client[G]] = - PureS3Client.asyncIn[F, G](blocker, awsRegion).map(apply[G]) + def asyncIn[F[_]: Sync, G[_]: Async](awsRegion: Region): Resource[F, SimpleS3Client[G]] = + PureS3Client.asyncIn[F, G](awsRegion).map(apply[G]) } diff --git a/modules/sqs-refined/src/main/scala/com/rewardsnetwork/pureaws/sqs/refined/RefinedSqsClient.scala b/modules/sqs-refined/src/main/scala/com/rewardsnetwork/pureaws/sqs/refined/RefinedSqsClient.scala index ec18127..560d15a 100644 --- a/modules/sqs-refined/src/main/scala/com/rewardsnetwork/pureaws/sqs/refined/RefinedSqsClient.scala +++ b/modules/sqs-refined/src/main/scala/com/rewardsnetwork/pureaws/sqs/refined/RefinedSqsClient.scala @@ -117,19 +117,17 @@ object RefinedSqsClient { /** Constructs a `RefinedSqsClient` using an underlying synchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `RefinedSqsClient` instance using a synchronous backend. */ - def sync[F[_]: Sync: ContextShift](blocker: Blocker, region: Region) = - PureSqsClient.sync[F](blocker, region).map(apply[F]) + def sync[F[_]: Sync](region: Region) = + PureSqsClient.sync[F](region).map(apply[F]) /** Constructs a `RefinedSqsClient` using an underlying asynchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `RefinedSqsClient` instance using an asynchronous backend. */ - def async[F[_]: Async: ContextShift](blocker: Blocker, region: Region) = - PureSqsClient.async[F](blocker, region).map(apply[F]) + def async[F[_]: Async](region: Region) = + PureSqsClient.async[F](region).map(apply[F]) } diff --git a/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/PureSqsClient.scala b/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/PureSqsClient.scala index 7d7036d..2f9fd4f 100644 --- a/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/PureSqsClient.scala +++ b/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/PureSqsClient.scala @@ -4,7 +4,6 @@ import java.util.concurrent.CompletableFuture import cats.effect._ import fs2.Stream -import monix.catnap.syntax._ import software.amazon.awssdk.regions.Region import software.amazon.awssdk.services.sqs.{SqsClient, SqsAsyncClient} import software.amazon.awssdk.services.sqs.model._ @@ -48,8 +47,8 @@ object PureSqsClient { /** Creates a new PureSqsClient given an existing `SqsClient`. * Note that you will have to close the client yourself when you are finished. */ - def apply[F[_]: Sync: ContextShift](blocker: Blocker, client: SqsClient) = new PureSqsClient[F] { - private def block[A](f: => A): F[A] = blocker.blockOn(Sync[F].delay(f)) + def apply[F[_]: Sync](client: SqsClient) = new PureSqsClient[F] { + private def block[A](f: => A): F[A] = Sync[F].blocking(f) def addPermission(r: AddPermissionRequest): F[AddPermissionResponse] = block { client.addPermission(r) @@ -98,7 +97,7 @@ object PureSqsClient { * Note that you will have to close the client yourself when you are finished. */ def apply[F[_]: Async](client: SqsAsyncClient) = new PureSqsClient[F] { - private def lift[A](f: => CompletableFuture[A]): F[A] = Sync[F].delay(f).futureLift + private def lift[A](f: => CompletableFuture[A]): F[A] = Async[F].fromCompletableFuture(Sync[F].delay(f)) def addPermission(r: AddPermissionRequest): F[AddPermissionResponse] = lift { client.addPermission(r) } @@ -138,45 +137,35 @@ object PureSqsClient { /** Creates a `PureSqsClient` using a synchronous backend with default settings. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `Resource` containing a `PureSqsClient` using a synchronous backend. */ - def sync[F[_]: Sync: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, PureSqsClient[F]] = - SqsClientBackend.sync[F](blocker, awsRegion)().map(apply[F](blocker, _)) + def sync[F[_]: Sync](awsRegion: Region): Resource[F, PureSqsClient[F]] = + SqsClientBackend.sync[F](awsRegion)().map(apply[F](_)) /** Creates a `PureSqsClient` using a synchronous backend with default settings. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `Resource` containing a `PureSqsClient` using a synchronous backend. */ - def syncIn[F[_]: Sync: ContextShift, G[_]: Sync: ContextShift]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, PureSqsClient[G]] = - SqsClientBackend.sync[F](blocker, awsRegion)().map(apply[G](blocker, _)) + def syncIn[F[_]: Sync, G[_]: Sync](awsRegion: Region): Resource[F, PureSqsClient[G]] = + SqsClientBackend.sync[F](awsRegion)().map(apply[G](_)) /** Creates a `PureSqsClient` using an asynchronous backend with default settings. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `Resource` containing a `PureSqsClient` using an asynchronous backend. */ - def async[F[_]: Async: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, PureSqsClient[F]] = - SqsClientBackend.async[F](blocker, awsRegion)().map(apply[F]) + def async[F[_]: Async](awsRegion: Region): Resource[F, PureSqsClient[F]] = + SqsClientBackend.async[F](awsRegion)().map(apply[F]) /** Creates a `PureSqsClient` using an asynchronous backend with default settings. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `Resource` containing a `PureSqsClient` using an asynchronous backend. */ - def asyncIn[F[_]: Sync: ContextShift, G[_]: Async]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, PureSqsClient[G]] = - SqsClientBackend.async[F](blocker, awsRegion)().map(apply[G]) + def asyncIn[F[_]: Sync, G[_]: Async](awsRegion: Region): Resource[F, PureSqsClient[G]] = + SqsClientBackend.async[F](awsRegion)().map(apply[G]) } diff --git a/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SimpleSqsClient.scala b/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SimpleSqsClient.scala index 641d5ee..9df4e42 100644 --- a/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SimpleSqsClient.scala +++ b/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SimpleSqsClient.scala @@ -1,6 +1,6 @@ package com.rewardsnetwork.pureaws.sqs -import cats.implicits._ +import cats.syntax.all._ import cats.effect._ import fs2.Stream import software.amazon.awssdk.regions.Region @@ -74,7 +74,9 @@ object SimpleSqsClient { client .receiveMessageStream(reqWithMaybeAttrs) - .flatMap[F, Message](res => Stream.fromIterator[F](res.messages.iterator.asScala)) + .flatMap[F, Message](res => + Stream.fromIterator[F](res.messages.iterator.asScala, 1024) + ) //TODO: make the chunk size configurable } def apply[F[_]: Sync](client: PureSqsClient[F]) = @@ -142,45 +144,35 @@ object SimpleSqsClient { /** Constructs a `SimpleSqsClient` using an underlying synchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `SimpleSqsClient` instance using a synchronous backend. */ - def sync[F[_]: Sync: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, SimpleSqsClient[F]] = - PureSqsClient.sync[F](blocker, awsRegion).map(apply[F]) + def sync[F[_]: Sync](awsRegion: Region): Resource[F, SimpleSqsClient[F]] = + PureSqsClient.sync[F](awsRegion).map(apply[F]) /** Constructs a `SimpleSqsClient` using an underlying synchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return An `SimpleSqsClient` instance using a synchronous backend. */ - def syncIn[F[_]: Sync: ContextShift, G[_]: Sync: ContextShift]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, SimpleSqsClient[G]] = - PureSqsClient.syncIn[F, G](blocker, awsRegion).map(apply[G]) + def syncIn[F[_]: Sync, G[_]: Sync](awsRegion: Region): Resource[F, SimpleSqsClient[G]] = + PureSqsClient.syncIn[F, G](awsRegion).map(apply[G]) /** Constructs a `SimpleSqsClient` using an underlying asynchronous client backend. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `SimpleSqsClient` instance using an asynchronous backend. */ - def async[F[_]: Async: ContextShift](blocker: Blocker, awsRegion: Region): Resource[F, SimpleSqsClient[F]] = - PureSqsClient.async[F](blocker, awsRegion).map(apply[F]) + def async[F[_]: Async](awsRegion: Region): Resource[F, SimpleSqsClient[F]] = + PureSqsClient.async[F](awsRegion).map(apply[F]) /** Constructs a `SimpleSqsClient` using an underlying asynchronous client backend. * This variant allows for creating the client with a different effect type than the `Resource` it is provided in. * - * @param blocker A Cats Effect `Blocker`. * @param awsRegion The AWS region you are operating in. * @return A `SimpleSqsClient` instance using an asynchronous backend. */ - def asyncIn[F[_]: Sync: ContextShift, G[_]: Async]( - blocker: Blocker, - awsRegion: Region - ): Resource[F, SimpleSqsClient[G]] = - PureSqsClient.asyncIn[F, G](blocker, awsRegion).map(apply[G]) + def asyncIn[F[_]: Sync, G[_]: Async](awsRegion: Region): Resource[F, SimpleSqsClient[G]] = + PureSqsClient.asyncIn[F, G](awsRegion).map(apply[G]) } diff --git a/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SqsClientBackend.scala b/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SqsClientBackend.scala index 392525a..6fe8493 100644 --- a/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SqsClientBackend.scala +++ b/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SqsClientBackend.scala @@ -10,20 +10,20 @@ object SqsClientBackend { /** Builds a raw AWS `SqsClient` (synchronous). * Prefer to use `PureSqsClient` instead, where possible. */ - def sync[F[_]: Sync: ContextShift](blocker: Blocker, region: Region)( + def sync[F[_]: Sync](region: Region)( configure: SqsClientBuilder => SqsClientBuilder = identity ) = - Resource.fromAutoCloseableBlocking(blocker)(Sync[F].delay { + Resource.fromAutoCloseable(Sync[F].blocking { configure(SqsClient.builder.region(region)).build }) /** Builds a raw AWS `SqsAsyncClient`. * Prefer to use `PureSqsClient` instead, where possible. */ - def async[F[_]: Sync: ContextShift](blocker: Blocker, region: Region)( + def async[F[_]: Sync](region: Region)( configure: SqsAsyncClientBuilder => SqsAsyncClientBuilder = identity ) = - Resource.fromAutoCloseableBlocking(blocker)(Sync[F].delay { + Resource.fromAutoCloseable(Sync[F].blocking { configure(SqsAsyncClient.builder.region(region)).build }) } diff --git a/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SqsMessage.scala b/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SqsMessage.scala index 4c7282d..d15d110 100644 --- a/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SqsMessage.scala +++ b/modules/sqs/src/main/scala/com/rewardsnetwork/pureaws/sqs/SqsMessage.scala @@ -1,8 +1,8 @@ package com.rewardsnetwork.pureaws.sqs import cats._ -import cats.implicits._ -import cats.effect.{Concurrent, Timer} +import cats.syntax.all._ +import cats.effect.Temporal import fs2.Stream import scala.concurrent.duration.FiniteDuration @@ -27,14 +27,14 @@ trait BaseSqsMessage[F[_], T] { */ def autoDeleteAndRenew(renewEvery: FiniteDuration, visibilityTimeoutSeconds: T)( shouldDelete: F[Boolean] - )(implicit F: Concurrent[F], timer: Timer[F]): F[Unit] = { + )(implicit F: Temporal[F]): F[Unit] = { autoDeleteAndRenewStream(renewEvery, visibilityTimeoutSeconds)(shouldDelete).compile.drain } /** Like `autoDeleteAndRenew` except it returns an FS2 `Stream` */ def autoDeleteAndRenewStream(renewEvery: FiniteDuration, visibilityTimeoutSeconds: T)( shouldDelete: F[Boolean] - )(implicit F: Concurrent[F], timer: Timer[F]): Stream[F, Unit] = { + )(implicit F: Temporal[F]): Stream[F, Unit] = { val renew = fs2.Stream.awakeEvery[F](renewEvery).evalTap { _ => receiptHandle.changeVisibility(visibilityTimeoutSeconds) } diff --git a/project/build.properties b/project/build.properties index 41aaafe..bb5389d 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.5.2 \ No newline at end of file +sbt.version=1.5.5 \ No newline at end of file diff --git a/project/plugins.sbt b/project/plugins.sbt index 8691ac9..f487ad9 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.18") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2") +addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.20") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.3") addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.7") -addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.10.1") +addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.12.0")