Skip to content

Commit 8d49037

Browse files
author
luigi
committed
content type and accept type
1 parent 0eb095f commit 8d49037

File tree

4 files changed

+70
-9
lines changed

4 files changed

+70
-9
lines changed

codegen/smithy-aws-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/aws/protocols/RestJson1.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class RestJson1 : JsonHttpBindingProtocolGenerator() {
4040
writer: KotlinWriter,
4141
) {
4242
super.renderSerializeHttpBody(ctx, op, writer)
43+
if (ctx.settings.build.generateServiceProject) return
4344

4445
val resolver = getProtocolHttpBindingResolver(ctx.model, ctx.service)
4546
if (!resolver.hasHttpBody(op)) return

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,9 @@ object RuntimeTypes {
558558
val HttpHeaders = symbol("HttpHeaders")
559559
val Cbor = symbol("Cbor", "ContentType.Application")
560560
val Json = symbol("Json", "ContentType.Application")
561+
val Any = symbol("Any", "ContentType.Application")
562+
val OctetStream = symbol("OctetStream", "ContentType.Application")
563+
val PlainText = symbol("Plain", "ContentType.Text")
561564
}
562565

563566
object KtorServerLogging : RuntimeTypePackage(KotlinDependency.KTOR_SERVER_LOGGING) {

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/service/KtorStubGenerator.kt

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,6 @@ internal class KtorStubGenerator(
208208

209209
// Writes `Routing.kt` that maps Smithy operations → Ktor routes.
210210
override fun renderRouting() {
211-
val contentType = ContentType.fromServiceShape(serviceShape)
212-
213211
delegator.useFileWriter("Routing.kt", ctx.settings.pkg.name) { writer ->
214212

215213
operations.forEach { shape ->
@@ -241,15 +239,27 @@ internal class KtorStubGenerator(
241239
"OPTIONS" -> RuntimeTypes.KtorServerRouting.options
242240
else -> error("Unsupported http trait ${httpTrait.method}")
243241
}
244-
242+
val contentType = ContentType.fromServiceShape(ctx, serviceShape, shape)
245243
val contentTypeGuard = when (contentType) {
246244
ContentType.CBOR -> "cbor()"
247245
ContentType.JSON -> "json()"
246+
ContentType.PLAIN_TEXT -> "text()"
247+
ContentType.BINARY -> "binary()"
248+
ContentType.MEDIA_TYPE -> "any()"
249+
}
250+
251+
val acceptTypeGuard = when (contentType) {
252+
ContentType.CBOR -> "cbor()"
253+
ContentType.JSON,
254+
ContentType.PLAIN_TEXT,
255+
ContentType.BINARY,
256+
ContentType.MEDIA_TYPE,
257+
-> "json()"
248258
}
249259

250260
withBlock("#T (#S) {", "}", RuntimeTypes.KtorServerRouting.route, uri) {
251261
write("#T(#T) { $contentTypeGuard }", RuntimeTypes.KtorServerCore.install, ServiceTypes(pkgName).contentTypeGuard)
252-
write("#T(#T) { $contentTypeGuard }", RuntimeTypes.KtorServerCore.install, ServiceTypes(pkgName).acceptTypeGuard)
262+
write("#T(#T) { $acceptTypeGuard }", RuntimeTypes.KtorServerCore.install, ServiceTypes(pkgName).acceptTypeGuard)
253263
withBlock(
254264
"#W",
255265
"}",
@@ -400,7 +410,11 @@ internal class KtorStubGenerator(
400410
RuntimeTypes.KtorServerHttp.HttpStatusCode,
401411
)
402412
}
403-
ContentType.JSON -> w.withBlock(
413+
ContentType.JSON,
414+
ContentType.PLAIN_TEXT,
415+
ContentType.BINARY,
416+
ContentType.MEDIA_TYPE,
417+
-> w.withBlock(
404418
"#T.#T(",
405419
")",
406420
RuntimeTypes.KtorServerCore.applicationCall,
@@ -535,13 +549,25 @@ internal class KtorStubGenerator(
535549
writer.withBlock("public class ContentTypeGuardConfig {", "}") {
536550
write("public var allow: List<#T> = emptyList()", RuntimeTypes.KtorServerHttp.ContentType)
537551
write("")
552+
withBlock("public fun any(): Unit {", "}") {
553+
write("allow = listOf(#T)", RuntimeTypes.KtorServerHttp.Any)
554+
}
555+
write("")
538556
withBlock("public fun json(): Unit {", "}") {
539557
write("allow = listOf(#T)", RuntimeTypes.KtorServerHttp.Json)
540558
}
541559
write("")
542560
withBlock("public fun cbor(): Unit {", "}") {
543561
write("allow = listOf(#T)", RuntimeTypes.KtorServerHttp.Cbor)
544562
}
563+
write("")
564+
withBlock("public fun text(): Unit {", "}") {
565+
write("allow = listOf(#T)", RuntimeTypes.KtorServerHttp.PlainText)
566+
}
567+
write("")
568+
withBlock("public fun binary(): Unit {", "}") {
569+
write("allow = listOf(#T)", RuntimeTypes.KtorServerHttp.OctetStream)
570+
}
545571
}
546572
.write("")
547573

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/service/ServiceStubConfigurations.kt

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@ import software.amazon.smithy.aws.traits.protocols.RestJson1Trait
44
import software.amazon.smithy.build.FileManifest
55
import software.amazon.smithy.kotlin.codegen.core.GenerationContext
66
import software.amazon.smithy.kotlin.codegen.core.KotlinDelegator
7+
import software.amazon.smithy.model.shapes.OperationShape
78
import software.amazon.smithy.model.shapes.ServiceShape
9+
import software.amazon.smithy.model.shapes.ShapeType
10+
import software.amazon.smithy.model.traits.HttpPayloadTrait
11+
import software.amazon.smithy.model.traits.MediaTypeTrait
812
import software.amazon.smithy.protocol.traits.Rpcv2CborTrait
913

1014
enum class ContentType(val value: String) {
1115
CBOR("CBOR"),
1216
JSON("JSON"),
17+
PLAIN_TEXT("PLAIN_TEXT"),
18+
BINARY("BINARY"),
19+
MEDIA_TYPE("MEDIA_TYPE"),
1320
;
1421

1522
override fun toString(): String = value
@@ -20,10 +27,34 @@ enum class ContentType(val value: String) {
2027
.firstOrNull { it.name.equals(value.uppercase(), ignoreCase = true) }
2128
?: throw IllegalArgumentException("$value is not a validContentType value, expected one of ${ContentType.entries}")
2229

23-
fun fromServiceShape(shape: ServiceShape): ContentType = when {
24-
shape.hasTrait(Rpcv2CborTrait.ID) -> CBOR
25-
shape.hasTrait(RestJson1Trait.ID) -> JSON
26-
else -> throw IllegalArgumentException("service shape does not a valid protocol")
30+
fun fromServiceShape(ctx: GenerationContext, shape: ServiceShape, operation: OperationShape): ContentType {
31+
return when {
32+
shape.hasTrait(Rpcv2CborTrait.ID) -> CBOR
33+
shape.hasTrait(RestJson1Trait.ID) -> {
34+
println(shape.allMembers)
35+
val inputShape = ctx.model.expectShape(operation.input.get())
36+
for (memberShape in inputShape.allMembers.values) {
37+
println("------------------------------")
38+
println(memberShape)
39+
if (!memberShape.hasTrait(HttpPayloadTrait.ID)) continue
40+
val memberType = ctx.model.expectShape(memberShape.target).type
41+
println(memberType)
42+
when (memberType) {
43+
ShapeType.STRING -> return PLAIN_TEXT
44+
ShapeType.DOCUMENT,
45+
ShapeType.STRUCTURE,
46+
ShapeType.UNION,
47+
-> return JSON
48+
else -> {
49+
if (memberShape.hasTrait(MediaTypeTrait.ID)) return MEDIA_TYPE
50+
}
51+
}
52+
}
53+
return JSON
54+
}
55+
56+
else -> throw IllegalArgumentException("service shape does not a valid protocol")
57+
}
2758
}
2859
}
2960
}

0 commit comments

Comments
 (0)