Skip to content

Commit 0eec889

Browse files
AnthonyGrodagrodowski
and
agrodowski
authored
Adding pekko-http support (#305)
* Migrate from akka-http to pekko-http * Removed redundant pekko module * Revert removal of akka-http support * Add scala 3 support for pekko-http * Remove CrossVersion where not necessary * Introduce opaque types in http4s-stir and pekko-http modules tests --------- Co-authored-by: agrodowski <[email protected]>
1 parent e8257d6 commit 0eec889

File tree

25 files changed

+1080
-55
lines changed

25 files changed

+1080
-55
lines changed

benchmarks/src/main/scala/pl/iterators/kebs_benchmarks/SprayJsonFormatBenchmark.scala

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import java.time.format.DateTimeFormatter
44
import java.time.{LocalDate, LocalTime}
55
import java.util.concurrent.TimeUnit
66

7-
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
8-
import akka.http.scaladsl.marshalling.ToResponseMarshallable
9-
import akka.http.scaladsl.model.StatusCodes._
10-
import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
11-
import akka.http.scaladsl.server.Directives._
12-
import akka.http.scaladsl.testkit.ScalatestRouteTest
7+
import org.apache.pekko.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
8+
import org.apache.pekko.http.scaladsl.marshalling.ToResponseMarshallable
9+
import org.apache.pekko.http.scaladsl.model.StatusCodes._
10+
import org.apache.pekko.http.scaladsl.model.{ContentTypes, HttpEntity}
11+
import org.apache.pekko.http.scaladsl.server.Directives._
12+
import org.apache.pekko.http.scaladsl.testkit.ScalatestRouteTest
1313
import org.openjdk.jmh.annotations._
1414
import org.scalatest.{FunSpec, Matchers}
1515
import pl.iterators.kebs.json.KebsSpray

build.sbt

+43-4
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,21 @@ val akkaHttpTestkit = "com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVer
145145
def akkaHttpInExamples = {
146146
val akkaHttpSprayJson = "com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion
147147
Seq(akkaStream.cross(CrossVersion.for3Use2_13),
148-
akkaHttp.cross(CrossVersion.for3Use2_13),
149-
akkaHttpSprayJson.cross(CrossVersion.for3Use2_13))
148+
akkaHttp.cross(CrossVersion.for3Use2_13),
149+
akkaHttpSprayJson.cross(CrossVersion.for3Use2_13))
150+
}
151+
152+
val pekkoVersion = "1.0.1"
153+
val pekkoHttpVersion = "1.0.0"
154+
val pekkoHttpJsonV = "2.0.0"
155+
val pekkoStream = "org.apache.pekko" %% "pekko-stream" % pekkoVersion
156+
val pekkoStreamTestkit = "org.apache.pekko" %% "pekko-stream-testkit" % pekkoVersion
157+
val pekkoHttp = "org.apache.pekko" %% "pekko-http" % pekkoHttpVersion
158+
val pekkoHttpTestkit = "org.apache.pekko" %% "pekko-http-testkit" % pekkoHttpVersion
159+
160+
def pekkoHttpInExamples = {
161+
val pekkoHttpSprayJson = "org.apache.pekko" %% "pekko-http-spray-json" % pekkoHttpVersion
162+
Seq(pekkoStream, pekkoHttp, pekkoHttpSprayJson)
150163
}
151164

152165
val http4sVersion = "0.23.23"
@@ -158,6 +171,8 @@ val http4sStirTestkit = "pl.iterators" %% "http4s-stir-testkit" % http4sStirVers
158171

159172
def akkaHttpInBenchmarks = akkaHttpInExamples :+ (akkaHttpTestkit).cross(CrossVersion.for3Use2_13)
160173

174+
def pekkoHttpInBenchmarks = pekkoHttpInExamples :+ pekkoHttpTestkit
175+
161176
lazy val commonSettings = baseSettings ++ Seq(
162177
scalacOptions ++=
163178
(if (scalaVersion.value.startsWith("3"))
@@ -214,6 +229,16 @@ lazy val akkaHttpSettings = commonSettings ++ Seq(
214229
scalacOptions ++= paradiseFlag(scalaVersion.value)
215230
)
216231

232+
lazy val pekkoHttpSettings = commonSettings ++ Seq(
233+
libraryDependencies += pekkoHttp,
234+
libraryDependencies += pekkoStream,
235+
libraryDependencies += pekkoStreamTestkit % "test",
236+
libraryDependencies += pekkoHttpTestkit % "test",
237+
libraryDependencies += optionalEnumeratum,
238+
libraryDependencies ++= paradisePlugin(scalaVersion.value),
239+
scalacOptions ++= paradiseFlag(scalaVersion.value)
240+
)
241+
217242
lazy val http4sSettings = commonSettings ++ Seq(
218243
libraryDependencies += http4s,
219244
libraryDependencies += optionalEnumeratum,
@@ -253,13 +278,14 @@ lazy val examplesSettings = commonSettings ++ Seq(
253278
libraryDependencies += slickPg.cross(CrossVersion.for3Use2_13),
254279
libraryDependencies += circeParser,
255280
libraryDependencies ++= enumeratumInExamples,
256-
libraryDependencies ++= akkaHttpInExamples,
281+
libraryDependencies ++= pekkoHttpInExamples,
257282
libraryDependencies ++= paradisePlugin(scalaVersion.value),
258283
scalacOptions ++= paradiseFlag(scalaVersion.value)
259284
)
260285

261286
lazy val benchmarkSettings = commonSettings ++ Seq(
262287
libraryDependencies += scalaTest.value,
288+
libraryDependencies ++= pekkoHttpInBenchmarks,
263289
libraryDependencies += enumeratum,
264290
libraryDependencies ++= akkaHttpInBenchmarks
265291
)
@@ -389,6 +415,18 @@ lazy val akkaHttpSupport = project
389415
crossScalaVersions := supportedScalaVersions
390416
)
391417

418+
lazy val pekkoHttpSupport = project
419+
.in(file("pekko-http"))
420+
.dependsOn(core.jvm, instances % "test -> test", tagged.jvm % "test -> test", taggedMeta % "test -> test")
421+
.settings(pekkoHttpSettings: _*)
422+
.settings(publishSettings: _*)
423+
.settings(
424+
name := "pekko-http",
425+
description := "Automatic generation of pekko-http deserializers for 1-element case classes",
426+
moduleName := "kebs-pekko-http",
427+
crossScalaVersions := supportedScalaVersions
428+
)
429+
392430
lazy val http4sSupport = project
393431
.in(file("http4s"))
394432
.dependsOn(core.jvm, instances, opaque.jvm % "test -> test", tagged.jvm % "test -> test", taggedMeta % "test -> test")
@@ -491,7 +529,7 @@ lazy val taggedMeta = project
491529

492530
lazy val examples = project
493531
.in(file("examples"))
494-
.dependsOn(slickSupport, sprayJsonSupport, playJsonSupport, akkaHttpSupport, taggedMeta, circeSupport, instances)
532+
.dependsOn(slickSupport, sprayJsonSupport, playJsonSupport, pekkoHttpSupport, taggedMeta, circeSupport, instances)
495533
.settings(examplesSettings: _*)
496534
.settings(noPublishSettings: _*)
497535
.settings(disableScala(List("3")))
@@ -542,6 +580,7 @@ lazy val kebs = project
542580
jsonschemaSupport,
543581
scalacheckSupport,
544582
akkaHttpSupport,
583+
pekkoHttpSupport,
545584
http4sSupport,
546585
http4sStirSupport,
547586
taggedMeta,

examples/src/main/scala/pl/iterators/kebs_examples/CirceExample.scala

+11-11
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ package pl.iterators.kebs_examples
33
import java.net.URL
44
import java.util.UUID
55

6-
import akka.http.scaladsl.marshalling.{ToResponseMarshallable, _}
7-
import akka.http.scaladsl.model.MediaTypes.`application/json`
8-
import akka.http.scaladsl.model.StatusCodes._
9-
import akka.http.scaladsl.model.{ContentType, ContentTypeRange, HttpEntity, MediaType}
10-
import akka.http.scaladsl.server.Directives._
11-
import akka.http.scaladsl.server.Route
12-
import akka.http.scaladsl.unmarshalling._
13-
import akka.util.ByteString
6+
import org.apache.pekko.http.scaladsl.marshalling.{ToResponseMarshallable, _}
7+
import org.apache.pekko.http.scaladsl.model.MediaTypes.`application/json`
8+
import org.apache.pekko.http.scaladsl.model.StatusCodes._
9+
import org.apache.pekko.http.scaladsl.model.{ContentType, ContentTypeRange, HttpEntity, MediaType}
10+
import org.apache.pekko.http.scaladsl.server.Directives._
11+
import org.apache.pekko.http.scaladsl.server.Route
12+
import org.apache.pekko.http.scaladsl.unmarshalling._
13+
import org.apache.pekko.util.ByteString
1414
import cats.data.NonEmptyList
1515
import io.circe.jawn.parseByteBuffer
1616
import io.circe._
@@ -27,7 +27,7 @@ object CirceExample {
2727
}
2828

2929
object BeforeKebs {
30-
object ThingProtocol extends CirceProtocol with CirceAkkaHttpSupport {
30+
object ThingProtocol extends CirceProtocol with CircePekkoHttpSupport {
3131
import io.circe._
3232
import io.circe.generic.semiauto._
3333
implicit val thingCreateRequestEncoder: Encoder[ThingCreateRequest] = deriveEncoder
@@ -62,7 +62,7 @@ object CirceExample {
6262
}
6363

6464
object AfterKebs {
65-
object ThingProtocol extends KebsCirce with CirceProtocol with CirceAkkaHttpSupport
65+
object ThingProtocol extends KebsCirce with CirceProtocol with CircePekkoHttpSupport
6666
import ThingProtocol._
6767

6868
class ThingRouter(thingsService: ThingsService)(implicit ec: ExecutionContext) {
@@ -105,7 +105,7 @@ object CirceExample {
105105
}
106106
}
107107

108-
trait CirceAkkaHttpSupport {
108+
trait CircePekkoHttpSupport {
109109

110110
implicit def jsonUnmarshaller[T](implicit reader: Decoder[T]): FromEntityUnmarshaller[T] =
111111
jsonUnmarshaller

examples/src/main/scala/pl/iterators/kebs_examples/EnumSprayJsonFormat.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ package pl.iterators.kebs_examples
33
import java.net.URL
44
import java.util.UUID
55

6-
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
7-
import akka.http.scaladsl.marshalling.ToResponseMarshallable
8-
import akka.http.scaladsl.model.StatusCodes._
9-
import akka.http.scaladsl.server.Directives._
6+
import org.apache.pekko.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
7+
import org.apache.pekko.http.scaladsl.marshalling.ToResponseMarshallable
8+
import org.apache.pekko.http.scaladsl.model.StatusCodes._
9+
import org.apache.pekko.http.scaladsl.server.Directives._
1010
import enumeratum.{Enum, EnumEntry}
1111
import pl.iterators.kebs.json.{KebsEnumFormats, KebsSpray}
1212
import spray.json.{DefaultJsonProtocol, JsString, JsValue, JsonFormat, JsonReader, JsonWriter, deserializationError}

examples/src/main/scala/pl/iterators/kebs_examples/AkkaHttpUnmarshallers.scala examples/src/main/scala/pl/iterators/kebs_examples/PekkoHttpUnmarshallers.scala

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package pl.iterators.kebs_examples
22

3-
import akka.http.scaladsl.model.StatusCodes
4-
import akka.http.scaladsl.server.Directives._
5-
import akka.http.scaladsl.unmarshalling.{FromStringUnmarshaller, Unmarshaller}
6-
import akka.http.scaladsl.util.FastFuture
3+
import org.apache.pekko.http.scaladsl.model.StatusCodes
4+
import org.apache.pekko.http.scaladsl.server.Directives._
5+
import org.apache.pekko.http.scaladsl.unmarshalling.{FromStringUnmarshaller, Unmarshaller}
6+
import org.apache.pekko.http.scaladsl.util.FastFuture
77
import enumeratum.values._
88
import enumeratum.{Enum, EnumEntry}
99

10-
object AkkaHttpUnmarshallers {
10+
object PekkoHttpUnmarshallers {
1111
sealed abstract class Column(val value: Int) extends IntEnumEntry
1212
object Column extends IntEnum[Column] {
1313
case object Name extends Column(1)

examples/src/main/scala/pl/iterators/kebs_examples/SprayJsonFormat.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package pl.iterators.kebs_examples
22

3-
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
4-
import akka.http.scaladsl.marshalling.ToResponseMarshallable
5-
import akka.http.scaladsl.model.StatusCodes._
6-
import akka.http.scaladsl.server.Directives._
3+
import org.apache.pekko.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
4+
import org.apache.pekko.http.scaladsl.marshalling.ToResponseMarshallable
5+
import org.apache.pekko.http.scaladsl.model.StatusCodes._
6+
import org.apache.pekko.http.scaladsl.server.Directives._
77
import pl.iterators.kebs.instances.net.URIString
88
import pl.iterators.kebs.instances.util.UUIDString
99
import pl.iterators.kebs.json.KebsSpray

examples/src/main/scala/pl/iterators/kebs_examples/SprayJsonWithAkkaHttpExample.scala examples/src/main/scala/pl/iterators/kebs_examples/SprayJsonWithPekkoHttpExample.scala

+12-12
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,25 @@ import java.io.IOException
44
import java.time.format.DateTimeFormatter
55
import java.time.{LocalDate, LocalTime}
66

7-
import akka.actor.ActorSystem
8-
import akka.event.LoggingAdapter
9-
import akka.http.scaladsl.Http
10-
import akka.http.scaladsl.client.RequestBuilding
11-
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
12-
import akka.http.scaladsl.model.StatusCodes._
13-
import akka.http.scaladsl.model.Uri.Query
14-
import akka.http.scaladsl.model._
15-
import akka.http.scaladsl.model.headers.RawHeader
16-
import akka.http.scaladsl.unmarshalling.Unmarshal
17-
import akka.stream.Materializer
7+
import org.apache.pekko.actor.ActorSystem
8+
import org.apache.pekko.event.LoggingAdapter
9+
import org.apache.pekko.http.scaladsl.Http
10+
import org.apache.pekko.http.scaladsl.client.RequestBuilding
11+
import org.apache.pekko.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
12+
import org.apache.pekko.http.scaladsl.model.StatusCodes._
13+
import org.apache.pekko.http.scaladsl.model.Uri.Query
14+
import org.apache.pekko.http.scaladsl.model._
15+
import org.apache.pekko.http.scaladsl.model.headers.RawHeader
16+
import org.apache.pekko.http.scaladsl.unmarshalling.Unmarshal
17+
import org.apache.pekko.stream.Materializer
1818
import pl.iterators.kebs.json.KebsSpray
1919
import spray.json._
2020

2121
import scala.concurrent.duration._
2222
import scala.concurrent.{ExecutionContext, Future}
2323
import scala.util.Try
2424

25-
object SprayJsonWithAkkaHttpExample {
25+
object SprayJsonWithPekkoHttpExample {
2626
trait Protocol extends DefaultJsonProtocol with SprayJsonSupport with KebsSpray {
2727
implicit val localTimeFormat = new JsonFormat[LocalTime] {
2828
override def write(obj: LocalTime): JsValue = JsString(formatter.format(obj))

http4s-stir/src/test/scala-3/pl/iterators/kebs/Http4sStirTagsDomain.scala

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
package pl.iterators.kebs
22

3+
import pl.iterators.kebs.opaque.Opaque
4+
35
import java.net.URI
46
import java.util.UUID
57
import pl.iterators.kebs.enums.ValueEnum
68

79
object Domain {
8-
case class TestTaggedUri(uri: URI)
9-
case class TestId(id: UUID)
10-
case class Id(id: Long)
10+
opaque type TestTaggedUri = URI
11+
object TestTaggedUri extends Opaque[TestTaggedUri, URI]
12+
opaque type TestId = UUID
13+
object TestId extends Opaque[TestId, UUID]
14+
opaque type Id = Long
15+
object Id extends Opaque[Id, Long]
1116
case class I(i: Int)
1217
case class S(s: String)
1318
case class P[A](a: A)

http4s-stir/src/test/scala-3/pl/iterators/kebs/matchers/Http4sStirMatchersTests.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class Http4sStirMatchersTests
2323
with DayOfWeekInt
2424
with InstantEpochMilliLong
2525
with URIString {
26-
implicit def runtime: cats.effect.unsafe.IORuntime = cats.effect.unsafe.IORuntime.global
26+
implicit def runtime: cats.effect.unsafe.IORuntime = cats.effect.unsafe.IORuntime.global
2727

2828
test("No CaseClass1Rep implicits derived") {
2929
import pl.iterators.kebs.macros.CaseClass1Rep
@@ -77,7 +77,7 @@ class Http4sStirMatchersTests
7777
complete(id.toString)
7878
}
7979
Get("/test/ce7a7cf1-8c00-49a9-a963-9fd119dd0642") ~> testRoute ~> check {
80-
responseAs[String] shouldEqual "TestTaggedUri(ce7a7cf1-8c00-49a9-a963-9fd119dd0642)"
80+
responseAs[String] shouldEqual "ce7a7cf1-8c00-49a9-a963-9fd119dd0642"
8181
}
8282
}
8383
}

http4s-stir/src/test/scala-3/pl/iterators/kebs/unmarshallers/Http4sStirUnmarshallersTests.scala

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class Http4sStirUnmarshallersTests
2424
with URIString
2525
with YearMonthString
2626
with DayOfWeekInt {
27-
implicit def runtime: cats.effect.unsafe.IORuntime = cats.effect.unsafe.IORuntime.global
27+
implicit def runtime: cats.effect.unsafe.IORuntime = cats.effect.unsafe.IORuntime.global
2828

2929
test("No CaseClass1Rep implicits derived") {
3030
import pl.iterators.kebs.macros.CaseClass1Rep
@@ -167,7 +167,7 @@ class Http4sStirUnmarshallersTests
167167
}
168168

169169
Get("/test_tagged?tagged=123456") ~> route ~> check {
170-
responseAs[String] shouldBe "Id(123456)"
170+
responseAs[String] shouldBe "123456"
171171
}
172172
}
173173

@@ -180,7 +180,7 @@ class Http4sStirUnmarshallersTests
180180
}
181181

182182
Get("/test_tagged?tagged=ce7a7cf1-8c00-49a9-a963-9fd119dd0642") ~> route ~> check {
183-
responseAs[String] shouldBe "TestId(ce7a7cf1-8c00-49a9-a963-9fd119dd0642)"
183+
responseAs[String] shouldBe "ce7a7cf1-8c00-49a9-a963-9fd119dd0642"
184184
}
185185
}
186186

@@ -193,7 +193,7 @@ class Http4sStirUnmarshallersTests
193193
}
194194

195195
Get("/test_tagged?tagged=www.test.pl") ~> route ~> check {
196-
responseAs[String] shouldBe "TestTaggedUri(www.test.pl)"
196+
responseAs[String] shouldBe "www.test.pl"
197197
}
198198
}
199199
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package pl.iterators.kebs.matchers
2+
3+
import org.apache.pekko.http.scaladsl.server.{PathMatcher1, PathMatchers}
4+
import enumeratum.{Enum, EnumEntry}
5+
import pl.iterators.kebs.instances.InstanceConverter
6+
import pl.iterators.kebs.macros.CaseClass1Rep
7+
8+
import scala.language.implicitConversions
9+
10+
trait KebsMatchers extends PathMatchers {
11+
12+
implicit class SegmentIsomorphism[U](segment: PathMatcher1[U]) {
13+
def as[T](implicit rep: CaseClass1Rep[T, U]): PathMatcher1[T] = segment.map(rep.apply)
14+
}
15+
16+
implicit class SegmentConversion[Source](segment: PathMatcher1[Source]) {
17+
def to[Type](implicit ico: InstanceConverter[Type, Source]): PathMatcher1[Type] = segment.map(ico.decode)
18+
}
19+
20+
object EnumSegment {
21+
def as[T <: EnumEntry: Enum]: PathMatcher1[T] = {
22+
val enumCompanion = implicitly[Enum[T]]
23+
Segment.map(enumCompanion.withNameInsensitive)
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)