Skip to content

Commit 2285ff8

Browse files
committed
rename setting and update changelogs
1 parent fb1ef54 commit 2285ff8

File tree

7 files changed

+85
-39
lines changed

7 files changed

+85
-39
lines changed

.changelog/1760625617.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
applies_to:
3+
- client
4+
- aws-sdk-rust
5+
authors:
6+
- rcoh
7+
references: ["smithy-rs#4352", "smithy-rs#4353"]
8+
breaking: false
9+
new_feature: false
10+
bug_fix: true
11+
---
12+
Update clients to allow `initial-response` events to be accepted on event streams, even when know modeled initial response exists.
13+
14+
This is required for spec compliance, backwards compatibility, and compatibility with non-smithy-rs based servers that
15+
MAY unconditionally send `initial-response` messages.

.changelog/1760625769.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
applies_to:
3+
- server
4+
authors:
5+
- rcoh
6+
references: ["smithy-rs#4352", "smithy-rs#4345"]
7+
breaking: false
8+
new_feature: true
9+
bug_fix: true
10+
---
11+
Update smithy-rs servers to support sending `initial-response` events over event streams.
12+
13+
Prior to this change, event streams that had initial responses were unsupported. This change also adds a new codegen setting, `alwaysSendEventStreamInitialResponse`.
14+
15+
When this setting is set to `true`, the generated server will unconditionally send `initial-response` objects, even when empty. This is required for compatibility with smithy-java as well as a few other clients.
16+
17+
This setting defaults to false currently because smithy-rs based clients do not currently support this behavior.
18+
19+
```json
20+
"codegen": {
21+
"alwaysSendEventStreamInitialResponse": true // default false
22+
}
23+
```

codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/CodegenIntegrationTest.kt

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -49,38 +49,39 @@ data class IntegrationTestParams(
4949
sealed class AdditionalSettings {
5050
abstract fun toObjectNode(): ObjectNode
5151

52-
abstract class CoreAdditionalSettings protected constructor(val settings: List<AdditionalSettings>) : AdditionalSettings() {
53-
override fun toObjectNode(): ObjectNode {
54-
val merged =
55-
settings.map { it.toObjectNode() }
56-
.reduce { acc, next -> acc.merge(next) }
57-
58-
return ObjectNode.builder()
59-
.withMember("codegen", merged)
60-
.build()
61-
}
52+
abstract class CoreAdditionalSettings protected constructor(val settings: List<AdditionalSettings>) :
53+
AdditionalSettings() {
54+
override fun toObjectNode(): ObjectNode {
55+
val merged =
56+
settings.map { it.toObjectNode() }
57+
.reduce { acc, next -> acc.merge(next) }
58+
59+
return ObjectNode.builder()
60+
.withMember("codegen", merged)
61+
.build()
62+
}
6263

63-
abstract class Builder<T : CoreAdditionalSettings> : AdditionalSettings() {
64-
protected val settings = mutableListOf<AdditionalSettings>()
64+
abstract class Builder<T : CoreAdditionalSettings> : AdditionalSettings() {
65+
protected val settings = mutableListOf<AdditionalSettings>()
6566

66-
fun generateCodegenComments(debugMode: Boolean = true): Builder<T> {
67-
settings.add(GenerateCodegenComments(debugMode))
68-
return this
69-
}
67+
fun generateCodegenComments(debugMode: Boolean = true): Builder<T> {
68+
settings.add(GenerateCodegenComments(debugMode))
69+
return this
70+
}
7071

71-
abstract fun build(): T
72+
abstract fun build(): T
7273

73-
override fun toObjectNode(): ObjectNode = build().toObjectNode()
74-
}
74+
override fun toObjectNode(): ObjectNode = build().toObjectNode()
75+
}
7576

76-
// Core settings that are common to both Servers and Clients should be defined here.
77-
data class GenerateCodegenComments(val debugMode: Boolean) : AdditionalSettings() {
78-
override fun toObjectNode(): ObjectNode =
79-
ObjectNode.builder()
80-
.withMember("debugMode", debugMode)
81-
.build()
77+
// Core settings that are common to both Servers and Clients should be defined here.
78+
data class GenerateCodegenComments(val debugMode: Boolean) : AdditionalSettings() {
79+
override fun toObjectNode(): ObjectNode =
80+
ObjectNode.builder()
81+
.withMember("debugMode", debugMode)
82+
.build()
83+
}
8284
}
83-
}
8485
}
8586

8687
class ClientAdditionalSettings private constructor(settings: List<AdditionalSettings>) :
@@ -109,8 +110,8 @@ class ServerAdditionalSettings private constructor(settings: List<AdditionalSett
109110
return this
110111
}
111112

112-
fun sendEventStreamInitialResponse(enabled: Boolean = true): Builder {
113-
settings.add(SendEventStreamInitialResponse(enabled))
113+
fun alwaysSendEventStreamInitialResponse(enabled: Boolean = true): Builder {
114+
settings.add(AlwaysSendEventStreamInitialResponse(enabled))
114115
return this
115116
}
116117

@@ -131,10 +132,10 @@ class ServerAdditionalSettings private constructor(settings: List<AdditionalSett
131132
.build()
132133
}
133134

134-
private data class SendEventStreamInitialResponse(val enabled: Boolean) : AdditionalSettings() {
135+
private data class AlwaysSendEventStreamInitialResponse(val enabled: Boolean) : AdditionalSettings() {
135136
override fun toObjectNode(): ObjectNode =
136137
ObjectNode.builder()
137-
.withMember("sendEventStreamInitialResponse", enabled)
138+
.withMember("alwaysSendEventStreamInitialResponse", enabled)
138139
.build()
139140
}
140141

@@ -167,7 +168,11 @@ fun codegenIntegrationTest(
167168
invokePlugin(ctx)
168169
ctx.fileManifest.printGeneratedFiles()
169170
val logger = Logger.getLogger("CodegenIntegrationTest")
170-
val out = params.command?.invoke(testDir) ?: (params.cargoCommand ?: "cargo test --lib --tests").runCommand(testDir, environment = environment)
171+
val out =
172+
params.command?.invoke(testDir) ?: (params.cargoCommand ?: "cargo test --lib --tests").runCommand(
173+
testDir,
174+
environment = environment,
175+
)
171176
logger.fine(out.toString())
172177
return testDir
173178
}

codegen-server-test/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ val allCodegenTests = "../codegen-core/common-test-models".let { commonModels ->
5656
"smithy.protocoltests.rpcv2Cbor#RpcV2CborService",
5757
"rpcv2Cbor_extras",
5858
imports = listOf("$commonModels/rpcv2Cbor-extras.smithy"),
59-
extraConfig = """, "codegen": { "sendEventStreamInitialResponse": true } """,
59+
extraConfig = """, "codegen": { "alwaysSendEventStreamInitialResponse": true } """,
6060
),
6161
CodegenTest(
6262
"smithy.protocoltests.rpcv2Cbor#RpcV2CborService",
6363
"rpcv2Cbor_extras_no_initial_response",
6464
imports = listOf("$commonModels/rpcv2Cbor-extras.smithy"),
6565
// This is the default behavior
66-
// extraConfig = """, "codegen": { "sendEventStreamInitialResponse": false } """,
66+
// extraConfig = """, "codegen": { "alwaysSendEventStreamInitialResponse": false } """,
6767
),
6868
CodegenTest(
6969
"com.amazonaws.constraints#ConstraintsService",

codegen-server-test/integration-tests/eventstreams/tests/structured_eventstream_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ async fn test_streaming_operation_with_initial_data_missing() {
375375
);
376376
}
377377

378-
/// Test that when sendEventStreamInitialResponse is disabled, no initial-response is sent
378+
/// Test that when alwaysSendEventStreamInitialResponse is disabled, no initial-response is sent
379379
#[tokio::test]
380380
async fn test_server_no_initial_response_when_disabled() {
381381
use rpcv2cbor_extras_no_initial_response::output;

codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRustSettings.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ data class ServerCodegenConfig(
9797
*/
9898
val experimentalCustomValidationExceptionWithReasonPleaseDoNotUse: String? = defaultExperimentalCustomValidationExceptionWithReasonPleaseDoNotUse,
9999
val addValidationExceptionToConstrainedOperations: Boolean = DEFAULT_ADD_VALIDATION_EXCEPTION_TO_CONSTRAINED_OPERATIONS,
100-
val sendEventStreamInitialResponse: Boolean = DEFAULT_SEND_EVENT_STREAM_INITIAL_RESPONSE,
100+
val alwaysSendEventStreamInitialResponse: Boolean = DEFAULT_SEND_EVENT_STREAM_INITIAL_RESPONSE,
101101
) : CoreCodegenConfig(
102102
formatTimeoutSeconds, debugMode,
103103
) {
@@ -120,7 +120,10 @@ data class ServerCodegenConfig(
120120
.getBooleanMemberOrDefault("publicConstrainedTypes", DEFAULT_PUBLIC_CONSTRAINED_TYPES),
121121
ignoreUnsupportedConstraints =
122122
node.get()
123-
.getBooleanMemberOrDefault("ignoreUnsupportedConstraints", DEFAULT_IGNORE_UNSUPPORTED_CONSTRAINTS),
123+
.getBooleanMemberOrDefault(
124+
"ignoreUnsupportedConstraints",
125+
DEFAULT_IGNORE_UNSUPPORTED_CONSTRAINTS,
126+
),
124127
experimentalCustomValidationExceptionWithReasonPleaseDoNotUse =
125128
node.get().getStringMemberOrDefault(
126129
"experimentalCustomValidationExceptionWithReasonPleaseDoNotUse",
@@ -131,9 +134,9 @@ data class ServerCodegenConfig(
131134
"addValidationExceptionToConstrainedOperations",
132135
DEFAULT_ADD_VALIDATION_EXCEPTION_TO_CONSTRAINED_OPERATIONS,
133136
),
134-
sendEventStreamInitialResponse =
137+
alwaysSendEventStreamInitialResponse =
135138
node.get().getBooleanMemberOrDefault(
136-
"sendEventStreamInitialResponse",
139+
"alwaysSendEventStreamInitialResponse",
137140
DEFAULT_SEND_EVENT_STREAM_INITIAL_RESPONSE,
138141
),
139142
)

codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/protocols/ServerHttpBoundProtocolGenerator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1484,7 +1484,7 @@ private fun eventStreamWithInitialResponse(
14841484
protocol: ServerProtocol,
14851485
params: EventStreamBodyParams,
14861486
): Writable {
1487-
return if (codegenContext.settings.codegenConfig.sendEventStreamInitialResponse) {
1487+
return if (codegenContext.settings.codegenConfig.alwaysSendEventStreamInitialResponse) {
14881488
val initialResponseGenerator =
14891489
params.eventStreamMarshallerGenerator.renderInitialResponseGenerator(params.payloadContentType)
14901490

0 commit comments

Comments
 (0)