Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Thank you!
# 0.18.33

* codegen: Fix an issue in which using UUIDs as trait or default values would prevent code generation in [#1685](https://github.com/disneystreaming/smithy4s/pull/1685)
* general: Update dependencies across the board in [#1686](https://github.com/disneystreaming/smithy4s/pull/1686)

# 0.18.32

Expand Down
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -1078,8 +1078,8 @@ lazy val `aws-sandbox` = projectMatrix
"-Wconf:cat=deprecation:silent"
),
smithy4sDependencies ++= Seq(
"com.disneystreaming.smithy" % "aws-cloudwatch-spec" % "2023.02.10",
"com.disneystreaming.smithy" % "aws-ec2-spec" % "2023.02.10"
"com.disneystreaming.smithy" % "aws-cloudwatch-spec" % "2025.04.08",
"com.disneystreaming.smithy" % "aws-ec2-spec" % "2025.04.08"
),
libraryDependencies ++= Seq(
Dependencies.Http4s.emberClient.value,
Expand Down
7 changes: 5 additions & 2 deletions modules/aws-http4s/src/smithy4s/aws/AwsClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import smithy4s.schema.OperationSchema
import smithy4s.http4s.kernel._
import smithy4s.interopcats._
import smithy4s.http.HttpMethod
import fs2.hashing.Hashing

// scalafmt: { maxColumn = 120 }
object AwsClient {
Expand Down Expand Up @@ -65,7 +66,7 @@ object AwsClient {
val service: smithy4s.Service[Alg]
) {

private def compiler[F[_]: Async: Compression](
private def compiler[F[_]: Async: Compression: Hashing](
awsEnv: AwsEnvironment[F]
): service.FunctorEndpointCompiler[F] = {

Expand Down Expand Up @@ -138,8 +139,10 @@ object AwsClient {

def build[F[_]: Async: Compression](
awsEnv: AwsEnvironment[F]
): service.Impl[F] =
): service.Impl[F] = {
implicit val hashingF: Hashing[F] = Hashing.forSync[F]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't bother passing it from the outside and doing a deprecation on this build signature, but I'm open to suggestions

service.impl(compiler[F](awsEnv))
}

// TODO : uncomment below when we start supporting streaming.

Expand Down
14 changes: 11 additions & 3 deletions modules/aws-http4s/src/smithy4s/aws/internals/Md5CheckSum.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ import org.http4s.client.Client
import org.typelevel.ci.CIString
import smithy4s.Endpoint
import smithy4s.Service
import fs2.hashing.Hashing
import fs2.hashing.HashAlgorithm

private[aws] object Md5CheckSum {

def middleware[F[_]: Sync]: Endpoint.Middleware[Client[F]] =
def middleware[F[_]: Sync: Hashing]: Endpoint.Middleware[Client[F]] =
new Endpoint.Middleware[Client[F]] {
def prepare[Alg[_[_, _, _, _, _]]](service: Service[Alg])(
endpoint: service.Endpoint[_, _, _, _, _]
Expand All @@ -40,9 +42,15 @@ private[aws] object Md5CheckSum {
} else client
}

private def reqWithChecksum[F[_]: Sync](client: Client[F]): Client[F] = {
private def reqWithChecksum[F[_]: Sync: Hashing](
client: Client[F]
): Client[F] = {
val md5HeaderPipe: Pipe[F, Byte, String] =
fs2.hash.md5[F] andThen fs2.text.base64.encode[F]
_.through(Hashing[F].hash(HashAlgorithm.MD5))
.map(_.bytes)
.unchunks
.through(fs2.text.base64.encode[F])

Client { request =>
val withChecksum =
for {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,20 @@ object AwsComplianceSuite extends ProtocolComplianceSuite {
"AwsJson10ClientPopulatesNestedDefaultsWhenMissingInResponseBody",
"AwsJson10ClientErrorCorrectsWhenServerFailsToSerializeRequiredValues",
"RestJsonHttpPayloadWithUnsetUnion",
"RestXmlHttpPayloadWithUnsetUnion"
"RestXmlHttpPayloadWithUnsetUnion",

// TODO same as above, added between 1.49 and 1.56. Mostly default-related
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on a good note, the FieldFilter functionality might help us fix these more quickly.

"NullAndEmptyHeaders",
"HttpPrefixEmptyHeaders",
"HttpEmptyPrefixHeadersRequestClient",
"RestJsonClientPopulatesNestedDefaultsWhenMissingInResponseBody",
"RestJsonClientPopulatesNestedDefaultValuesWhenMissing",
"RestJsonClientPopulatesDefaultsValuesWhenMissingInResponse",
"RestJsonClientPopulatesDefaultValuesInInput",
"RestJsonNullAndEmptyHeaders",
"RestJsonHttpPrefixEmptyHeaders",
"RestJsonHttpEmptyPrefixHeadersRequestClient",
"AwsJson10ClientErrorCorrectsWithDefaultValuesWhenServerFailsToSerializeRequiredValues"
)
(complianceTest: ComplianceTest[IO]) =>
if (disallowed.exists(complianceTest.show.contains(_))) ShouldRun.No
Expand Down
2 changes: 1 addition & 1 deletion modules/aws-sandbox/src/smithy4s/sandbox/aws/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ object Main extends IOApp.Simple {
listAll[String, ec2.DescribeInstanceStatusResult, ec2.InstanceStatus](
listF = maybeNextToken =>
ec2Client.describeInstanceStatus(
maxResults = 100,
maxResults = Some(100),
nextToken = maybeNextToken
),
accessResults = _.instanceStatuses.toList.flatten,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,11 +353,18 @@
}
},
"400": {
"description": "FallbackError 400 response",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consequence of disneystreaming/alloy#204 , I suppose

"description": "400 Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FallbackErrorResponseContent"
"oneOf": [
{
"$ref": "#/components/schemas/FallbackErrorResponseContent"
},
{
"$ref": "#/components/schemas/FallbackError2ResponseContent"
}
]
}
}
}
Expand Down Expand Up @@ -575,6 +582,17 @@
"minLength": 2
}
},
"FallbackError2ResponseContent": {
"type": "object",
"properties": {
"error": {
"type": "string"
}
},
"required": [
"error"
]
},
"FallbackErrorResponseContent": {
"type": "object",
"properties": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,93 +248,93 @@ object PizzaAdminServiceOperation {
def $ordinal: Int

object project {
def genericClientError: Option[GenericClientError] = GetMenuError.GenericClientErrorCase.alt.project.lift(self).map(_.genericClientError)
def fallbackError2: Option[FallbackError2] = GetMenuError.FallbackError2Case.alt.project.lift(self).map(_.fallbackError2)
def fallbackError: Option[FallbackError] = GetMenuError.FallbackErrorCase.alt.project.lift(self).map(_.fallbackError)
def notFoundError: Option[NotFoundError] = GetMenuError.NotFoundErrorCase.alt.project.lift(self).map(_.notFoundError)
def fallbackError: Option[FallbackError] = GetMenuError.FallbackErrorCase.alt.project.lift(self).map(_.fallbackError)
def fallbackError2: Option[FallbackError2] = GetMenuError.FallbackError2Case.alt.project.lift(self).map(_.fallbackError2)
def genericClientError: Option[GenericClientError] = GetMenuError.GenericClientErrorCase.alt.project.lift(self).map(_.genericClientError)
}
Comment on lines 250 to 255
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure which change triggered this reordering. smithy-lang/smithy#2513 looks related, but it's in the IDL serializer, and resource-specific. I checked the changelog for "sort" and "order" and "properties" but nothing else stood out.

still, this is the order as in the spec.


def accept[A](visitor: GetMenuError.Visitor[A]): A = this match {
case value: GetMenuError.GenericClientErrorCase => visitor.genericClientError(value.genericClientError)
case value: GetMenuError.FallbackError2Case => visitor.fallbackError2(value.fallbackError2)
case value: GetMenuError.FallbackErrorCase => visitor.fallbackError(value.fallbackError)
case value: GetMenuError.NotFoundErrorCase => visitor.notFoundError(value.notFoundError)
case value: GetMenuError.FallbackErrorCase => visitor.fallbackError(value.fallbackError)
case value: GetMenuError.FallbackError2Case => visitor.fallbackError2(value.fallbackError2)
case value: GetMenuError.GenericClientErrorCase => visitor.genericClientError(value.genericClientError)
}
}
object GetMenuError extends ErrorSchema.Companion[GetMenuError] {

def genericClientError(genericClientError: GenericClientError): GetMenuError = GenericClientErrorCase(genericClientError)
def fallbackError2(fallbackError2: FallbackError2): GetMenuError = FallbackError2Case(fallbackError2)
def fallbackError(fallbackError: FallbackError): GetMenuError = FallbackErrorCase(fallbackError)
def notFoundError(notFoundError: NotFoundError): GetMenuError = NotFoundErrorCase(notFoundError)
def fallbackError(fallbackError: FallbackError): GetMenuError = FallbackErrorCase(fallbackError)
def fallbackError2(fallbackError2: FallbackError2): GetMenuError = FallbackError2Case(fallbackError2)
def genericClientError(genericClientError: GenericClientError): GetMenuError = GenericClientErrorCase(genericClientError)

val id: ShapeId = ShapeId("smithy4s.example", "GetMenuError")

val hints: Hints = Hints.empty

final case class GenericClientErrorCase(genericClientError: GenericClientError) extends GetMenuError { final def $ordinal: Int = 0 }
final case class FallbackError2Case(fallbackError2: FallbackError2) extends GetMenuError { final def $ordinal: Int = 1 }
final case class FallbackErrorCase(fallbackError: FallbackError) extends GetMenuError { final def $ordinal: Int = 2 }
final case class NotFoundErrorCase(notFoundError: NotFoundError) extends GetMenuError { final def $ordinal: Int = 3 }
final case class NotFoundErrorCase(notFoundError: NotFoundError) extends GetMenuError { final def $ordinal: Int = 0 }
final case class FallbackErrorCase(fallbackError: FallbackError) extends GetMenuError { final def $ordinal: Int = 1 }
final case class FallbackError2Case(fallbackError2: FallbackError2) extends GetMenuError { final def $ordinal: Int = 2 }
final case class GenericClientErrorCase(genericClientError: GenericClientError) extends GetMenuError { final def $ordinal: Int = 3 }

object GenericClientErrorCase {
val hints: Hints = Hints.empty
val schema: Schema[GetMenuError.GenericClientErrorCase] = bijection(GenericClientError.schema.addHints(hints), GetMenuError.GenericClientErrorCase(_), _.genericClientError)
val alt = schema.oneOf[GetMenuError]("GenericClientError")
}
object FallbackError2Case {
object NotFoundErrorCase {
val hints: Hints = Hints.empty
val schema: Schema[GetMenuError.FallbackError2Case] = bijection(FallbackError2.schema.addHints(hints), GetMenuError.FallbackError2Case(_), _.fallbackError2)
val alt = schema.oneOf[GetMenuError]("FallbackError2")
val schema: Schema[GetMenuError.NotFoundErrorCase] = bijection(NotFoundError.schema.addHints(hints), GetMenuError.NotFoundErrorCase(_), _.notFoundError)
val alt = schema.oneOf[GetMenuError]("NotFoundError")
}
object FallbackErrorCase {
val hints: Hints = Hints.empty
val schema: Schema[GetMenuError.FallbackErrorCase] = bijection(FallbackError.schema.addHints(hints), GetMenuError.FallbackErrorCase(_), _.fallbackError)
val alt = schema.oneOf[GetMenuError]("FallbackError")
}
object NotFoundErrorCase {
object FallbackError2Case {
val hints: Hints = Hints.empty
val schema: Schema[GetMenuError.NotFoundErrorCase] = bijection(NotFoundError.schema.addHints(hints), GetMenuError.NotFoundErrorCase(_), _.notFoundError)
val alt = schema.oneOf[GetMenuError]("NotFoundError")
val schema: Schema[GetMenuError.FallbackError2Case] = bijection(FallbackError2.schema.addHints(hints), GetMenuError.FallbackError2Case(_), _.fallbackError2)
val alt = schema.oneOf[GetMenuError]("FallbackError2")
}
object GenericClientErrorCase {
val hints: Hints = Hints.empty
val schema: Schema[GetMenuError.GenericClientErrorCase] = bijection(GenericClientError.schema.addHints(hints), GetMenuError.GenericClientErrorCase(_), _.genericClientError)
val alt = schema.oneOf[GetMenuError]("GenericClientError")
}

trait Visitor[A] {
def genericClientError(value: GenericClientError): A
def fallbackError2(value: FallbackError2): A
def fallbackError(value: FallbackError): A
def notFoundError(value: NotFoundError): A
def fallbackError(value: FallbackError): A
def fallbackError2(value: FallbackError2): A
def genericClientError(value: GenericClientError): A
}

object Visitor {
trait Default[A] extends Visitor[A] {
def default: A
def genericClientError(value: GenericClientError): A = default
def fallbackError2(value: FallbackError2): A = default
def fallbackError(value: FallbackError): A = default
def notFoundError(value: NotFoundError): A = default
def fallbackError(value: FallbackError): A = default
def fallbackError2(value: FallbackError2): A = default
def genericClientError(value: GenericClientError): A = default
}
}

implicit val schema: Schema[GetMenuError] = union(
GetMenuError.GenericClientErrorCase.alt,
GetMenuError.FallbackError2Case.alt,
GetMenuError.FallbackErrorCase.alt,
GetMenuError.NotFoundErrorCase.alt,
GetMenuError.FallbackErrorCase.alt,
GetMenuError.FallbackError2Case.alt,
GetMenuError.GenericClientErrorCase.alt,
){
_.$ordinal
}
def liftError(throwable: Throwable): Option[GetMenuError] = throwable match {
case e: GenericClientError => Some(GetMenuError.GenericClientErrorCase(e))
case e: FallbackError2 => Some(GetMenuError.FallbackError2Case(e))
case e: FallbackError => Some(GetMenuError.FallbackErrorCase(e))
case e: NotFoundError => Some(GetMenuError.NotFoundErrorCase(e))
case e: FallbackError => Some(GetMenuError.FallbackErrorCase(e))
case e: FallbackError2 => Some(GetMenuError.FallbackError2Case(e))
case e: GenericClientError => Some(GetMenuError.GenericClientErrorCase(e))
case _ => None
}
def unliftError(e: GetMenuError): Throwable = e match {
case GetMenuError.GenericClientErrorCase(e) => e
case GetMenuError.FallbackError2Case(e) => e
case GetMenuError.FallbackErrorCase(e) => e
case GetMenuError.NotFoundErrorCase(e) => e
case GetMenuError.FallbackErrorCase(e) => e
case GetMenuError.FallbackError2Case(e) => e
case GetMenuError.GenericClientErrorCase(e) => e
}
}
final case class Version() extends PizzaAdminServiceOperation[Unit, Nothing, VersionOutput, Nothing, Nothing] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ object RoundTripData extends ShapeTag.Companion[RoundTripData] {
private def make(label: String, header: Option[String], query: Option[String], body: Option[String]): RoundTripData = RoundTripData(label, header, query, body)

implicit val schema: Schema[RoundTripData] = struct(
string.required[RoundTripData]("label", _.label).addHints(smithy.api.HttpLabel()),
string.required[RoundTripData]("label", _.label).addHints(smithy.api.HttpLabel(), smithy.api.Suppress(List("HttpBindingTraitIgnored.Input"))),
string.optional[RoundTripData]("header", _.header).addHints(smithy.api.HttpHeader("HEADER")),
string.optional[RoundTripData]("query", _.query).addHints(smithy.api.HttpQuery("query")),
string.optional[RoundTripData]("query", _.query).addHints(smithy.api.HttpQuery("query"), smithy.api.Suppress(List("HttpBindingTraitIgnored.Input"))),
string.optional[RoundTripData]("body", _.body),
)(make).withId(id).addHints(hints)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
],
"maven" : {
"dependencies" : [
"com.disneystreaming.alloy:alloy-core:0.3.13",
"com.disneystreaming.alloy:alloy-core:0.3.17",
"com.disneystreaming.smithy4s:smithy4s-protocol:${SMITHY4S_VERSION}"
],
"repositories" : [
Expand Down
1 change: 1 addition & 0 deletions modules/docs/markdown/03-protocols/03-aws/01-aws.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ In `build.sbt`

```scala
libraryDependencies ++= Seq(
// or smithy4s-aws-kernel if you want the minimal compilable unit
"com.disneystreaming.smithy4s" %% "smithy4s-aws-http4s" % smithy4sVersion.value
)
// The `AWS` object contains a list of references to artifacts that contain specifications to AWS services.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class Smithy4sModuleSpec extends munit.FunSuite {
override def millSourcePath = resourcePath / "service"
}
val ev =
testKit.staticTestEvaluator(foo)(FullName(s"codegen-wildcards-compiles"))
testKit.staticTestEvaluator(foo)(FullName("codegen-wildcards-compiles"))

compileWorks(foo, ev)

Expand Down
29 changes: 0 additions & 29 deletions modules/tests/src-ce2/Compat.scala

This file was deleted.

24 changes: 0 additions & 24 deletions modules/tests/src-ce2/UUIDGen.scala

This file was deleted.

Loading
Loading