Skip to content

Commit

Permalink
feat: update client codegen with endpoint plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewFossAWS committed Mar 1, 2024
1 parent 44dfb12 commit 3ce6864
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import software.amazon.smithy.aws.traits.auth.SigV4Trait
import software.amazon.smithy.codegen.core.Symbol
import software.amazon.smithy.model.knowledge.ServiceIndex
import software.amazon.smithy.swift.codegen.AuthSchemeResolverGenerator
import software.amazon.smithy.swift.codegen.ClientRuntimeTypes
import software.amazon.smithy.swift.codegen.SwiftWriter
import software.amazon.smithy.swift.codegen.config.ConfigProperty
import software.amazon.smithy.swift.codegen.config.DefaultProvider
import software.amazon.smithy.swift.codegen.integration.ClientProperty
import software.amazon.smithy.swift.codegen.integration.HttpProtocolServiceClient
import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator
import software.amazon.smithy.swift.codegen.integration.ServiceConfig
import software.amazon.smithy.swift.codegen.model.toOptional
import software.amazon.smithy.swift.codegen.utils.toUpperCamelCase

class AWSHttpProtocolServiceClient(
Expand All @@ -37,149 +39,24 @@ class AWSHttpProtocolServiceClient(
}
}

override fun renderClientConfig(serviceSymbol: Symbol) {

val clientConfigurationProtocols =
ctx.integrations
.flatMap { it.clientConfigurations(ctx) }
.mapNotNull { it.swiftProtocolName?.name }
.joinToString(" & ")

writer.openBlock(
"public class \$LConfiguration: \$L {", "}",
serviceConfig.clientName.toUpperCamelCase(),
clientConfigurationProtocols
) {
val properties: List<ConfigProperty> = ctx.integrations
.flatMap { it.clientConfigurations(ctx).flatMap { it.properties } }

renderConfigClassVariables(properties)

renderConfigInitializer(properties, isPrivate = true)

renderAsynchronousConfigInitializer(properties)

renderSynchronousConfigInitializer(properties)

renderEmptyAsynchronousConfigInitializer(properties)

renderRegionConfigInitializer(properties)

renderPartitionID()
}
writer.write("")
}

/**
* Declare class variables in client configuration class
*/
override fun renderConfigClassVariables(properties: List<ConfigProperty>) {
properties
.forEach {
when (it.name) {
"awsCredentialIdentityResolver" -> {
writer.write("public var \$L: any \$L", it.name, it.type)
writer.write("")
}
else -> {
writer.write("public var \$L: \$L", it.name, it.type)
writer.write("")
}
override fun overrideConfigProperties(properties: List<ConfigProperty>): List<ConfigProperty> {
return properties.map {
when (it.name) {
"authSchemeResolver" -> {
ConfigProperty("authSchemeResolver", ClientRuntimeTypes.Auth.AuthSchemeResolver, authSchemeResolverDefaultProvider)
}
}
writer.write("")
}

private fun renderPrivateConfigInitializer(properties: List<ConfigProperty>) {
writer.openBlock(
"private init(\$L) {",
"}",
properties.joinToString(", ") {
when (it.name) {
"awsCredentialIdentityResolver" -> {
"_ ${it.name}: any ${it.type}"
}
else -> {
"_ ${it.name}: ${it.type}"
}
"authSchemes" -> {
ConfigProperty("authSchemes", ClientRuntimeTypes.Auth.AuthSchemes.toOptional(), authSchemesDefaultProvider)
}
}
) {
properties.forEach {
writer.write("self.\$L = \$L", it.name, it.name)
else -> it
}
}
writer.write("")
}

override fun renderSynchronousConfigInitializer(properties: List<ConfigProperty>) {
writer.openBlock(
"public convenience init(\$L) throws {", "}",
properties.joinToString(", ") {
when (it.name) {
"awsCredentialIdentityResolver" -> {
"${it.name}: (any ${it.type})? = nil"
}
else -> {
"${it.name}: ${it.toOptionalType()} = nil"
}
}
}
) {
writer.writeInline(
"self.init(\$L)",
properties.joinToString(", ") {
when (it.name) {
"authSchemeResolver" -> {
authSchemeResolverDefaultProvider.render("authSchemeResolver")
}
"authSchemes" -> {
authSchemesDefaultProvider.render("authSchemes")
}
else -> {
if (it.default?.isAsync == true) {
it.name
} else {
it.default?.render(it.name) ?: it.name
}
}
}
}
)
}
writer.write("")
}

override fun renderAsynchronousConfigInitializer(properties: List<ConfigProperty>) {
writer.openBlock(
"public convenience init(\$L) async throws {", "}",
properties.joinToString(", ") {
when (it.name) {
"awsCredentialIdentityResolver" -> {
"${it.name}: (any ${it.type})? = nil"
}
else -> {
"${it.name}: ${it.toOptionalType()} = nil"
}
}
}
) {
writer.writeInline(
"self.init(\$L)",
properties.joinToString(", ") {
when (it.name) {
"authSchemeResolver" -> {
authSchemeResolverDefaultProvider.render("authSchemeResolver")
}
"authSchemes" -> {
authSchemesDefaultProvider.render("authSchemes")
}
else -> { it.default?.render() ?: it.name }
}
}
)
}
writer.write("")
override fun renderCustomConfigInitializer(properties: List<ConfigProperty>) {
renderEmptyAsynchronousConfigInitializer(properties)
renderRegionConfigInitializer(properties)
renderPartitionID()
}

/**
Expand All @@ -197,12 +74,6 @@ class AWSHttpProtocolServiceClient(
"awsCredentialIdentityResolver" -> {
"try AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver()"
}
"authSchemeResolver" -> {
authSchemeResolverDefaultProvider.value
}
"authSchemes" -> {
authSchemesDefaultProvider.value
}
else -> {
it.default?.render() ?: "nil"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,34 @@ import software.amazon.smithy.swift.codegen.SwiftTypes
import software.amazon.smithy.swift.codegen.config.ClientConfiguration
import software.amazon.smithy.swift.codegen.config.ClientConfiguration.Companion.runtimeSymbol
import software.amazon.smithy.swift.codegen.config.ConfigProperty
import software.amazon.smithy.swift.codegen.model.toNullable
import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator
import software.amazon.smithy.swift.codegen.model.toGeneric
import software.amazon.smithy.swift.codegen.model.toOptional

class AWSDefaultClientConfiguration : ClientConfiguration {
override val swiftProtocolName: Symbol
get() = runtimeSymbol("AWSDefaultClientConfiguration", AWSSwiftDependency.AWS_CLIENT_RUNTIME)

override val properties: Set<ConfigProperty>
get() = setOf(
ConfigProperty("useFIPS", SwiftTypes.Bool.toNullable()),
ConfigProperty("useDualStack", SwiftTypes.Bool.toNullable()),
ConfigProperty("appID", SwiftTypes.String.toNullable(), "AWSClientConfigDefaultsProvider.appID()", true),
ConfigProperty("awsCredentialIdentityResolver", AWSClientRuntimeTypes.Core.AWSCredentialIdentityResolver, "AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(awsCredentialIdentityResolver)", true),
ConfigProperty("awsRetryMode", AWSClientRuntimeTypes.Core.AWSRetryMode, "AWSClientConfigDefaultsProvider.retryMode()", true),
)
override fun getProperties(ctx: ProtocolGenerator.GenerationContext): Set<ConfigProperty> = setOf(
ConfigProperty("useFIPS", SwiftTypes.Bool.toOptional()),
ConfigProperty("useDualStack", SwiftTypes.Bool.toOptional()),
ConfigProperty(
"appID",
SwiftTypes.String.toOptional(),
"AWSClientConfigDefaultsProvider.appID()",
true
),
ConfigProperty(
"awsCredentialIdentityResolver",
AWSClientRuntimeTypes.Core.AWSCredentialIdentityResolver.toGeneric(),
"AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(awsCredentialIdentityResolver)",
true
),
ConfigProperty(
"awsRetryMode",
AWSClientRuntimeTypes.Core.AWSRetryMode,
"AWSClientConfigDefaultsProvider.retryMode()",
true
),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,20 @@ import software.amazon.smithy.swift.codegen.config.ClientConfiguration
import software.amazon.smithy.swift.codegen.config.ConfigProperty
import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator
import software.amazon.smithy.swift.codegen.model.getTrait
import software.amazon.smithy.swift.codegen.model.toNullable
import software.amazon.smithy.swift.codegen.model.toOptional
import software.amazon.smithy.swift.codegen.utils.toLowerCamelCase

class AWSEndpointClientConfiguration(val ctx: ProtocolGenerator.GenerationContext) : ClientConfiguration {
override val swiftProtocolName: Symbol?
get() = null

override val properties: Set<ConfigProperty>
get() {
val properties: MutableSet<ConfigProperty> = mutableSetOf()
val clientContextParams = ctx.service.getTrait<ClientContextParamsTrait>()
clientContextParams?.parameters?.forEach {
properties.add(ConfigProperty(it.key.toLowerCamelCase(), it.value.type.toSwiftType().toNullable()))
}
properties.add(ConfigProperty(ENDPOINT_RESOLVER, AWSServiceTypes.EndpointResolver, "DefaultEndpointResolver()", true))
return properties
override fun getProperties(ctx: ProtocolGenerator.GenerationContext): Set<ConfigProperty> {
val properties: MutableSet<ConfigProperty> = mutableSetOf()
val clientContextParams = ctx.service.getTrait<ClientContextParamsTrait>()
clientContextParams?.parameters?.forEach {
properties.add(ConfigProperty(it.key.toLowerCamelCase(), it.value.type.toSwiftType().toOptional()))
}
properties.add(ConfigProperty(ENDPOINT_RESOLVER, AWSServiceTypes.EndpointResolver, "DefaultEndpointResolver()", true))
return properties
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,27 @@ import software.amazon.smithy.swift.codegen.SwiftTypes
import software.amazon.smithy.swift.codegen.config.ClientConfiguration
import software.amazon.smithy.swift.codegen.config.ClientConfiguration.Companion.runtimeSymbol
import software.amazon.smithy.swift.codegen.config.ConfigProperty
import software.amazon.smithy.swift.codegen.model.toNullable
import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator
import software.amazon.smithy.swift.codegen.model.toOptional

class AWSRegionClientConfiguration : ClientConfiguration {
override val swiftProtocolName: Symbol
get() = runtimeSymbol("AWSRegionClientConfiguration", AWSSwiftDependency.AWS_CLIENT_RUNTIME)

override val properties: Set<ConfigProperty>
get() = setOf(
ConfigProperty("region", SwiftTypes.String.toNullable(), "AWSClientConfigDefaultsProvider.region(region)", true, true),
ConfigProperty("signingRegion", SwiftTypes.String.toNullable(), "AWSClientConfigDefaultsProvider.region(region)", true, true)
override fun getProperties(ctx: ProtocolGenerator.GenerationContext): Set<ConfigProperty> = setOf(
ConfigProperty(
"region",
SwiftTypes.String.toOptional(),
"AWSClientConfigDefaultsProvider.region(region)",
true,
true
),
ConfigProperty(
"signingRegion",
SwiftTypes.String.toOptional(),
"AWSClientConfigDefaultsProvider.region(region)",
true,
true
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ class EndpointPlugin(private val serviceConfig: ServiceConfig) : Plugin {
dependency(AWSSwiftDependency.AWS_CLIENT_RUNTIME)
}

override val isDefault: Boolean
get() = false

override fun render(writer: SwiftWriter) {
writer.openBlock("public class EndpointPlugin: Plugin {", "}") {
writer.write("private var endpointResolver: \$L", AWSServiceTypes.EndpointResolver)
writer.openBlock("public init(endpointResolver: \$L) {", "}", AWSServiceTypes.EndpointResolver) {
writer.write("self.endpointResolver = endpointResolver")
}
writer.openBlock("public convenience init() throws {", "}") {
writer.write("self.init(endpointResolver: try \$L())", AWSServiceTypes.DefaultEndpointResolver)
}
writer.openBlock("public func configureClient(clientConfiguration: ClientRuntime.ClientConfiguration) throws {", "}") {
writer.openBlock("if var config = clientConfiguration as? ${serviceConfig.typeName} {", "}") {
writer.write("config.endpointResolver = self.endpointResolver")
Expand Down

0 comments on commit 3ce6864

Please sign in to comment.