Skip to content

Commit 2d595cd

Browse files
committed
Handle required parameters for certain builders
1 parent 40340f1 commit 2d595cd

File tree

1,039 files changed

+4479
-4407
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,039 files changed

+4479
-4407
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ object ExampleApp extends App {
9191

9292
CfnApplicationV2(
9393
internalResourceId = "Runtime",
94+
serviceExecutionRole = "arn:example-role",
95+
runtimeEnvironment = "FLINK-1_13",
9496
tags = Some(
9597
List(
9698
CfnTag(key = Some("env"), value = Some(env)),
@@ -117,9 +119,7 @@ object ExampleApp extends App {
117119
)
118120
)
119121
)
120-
),
121-
serviceExecutionRole = Some("arn:example-role"),
122-
runtimeEnvironment = Some("FLINK-1_13")
122+
)
123123
)
124124
}
125125
}

build.sbt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ lazy val awsCdkScala = project
155155
opensearchservice,
156156
opsworks,
157157
opsworkscm,
158+
panorama,
158159
pinpoint,
159160
pinpointemail,
160161
pipelines,
@@ -164,6 +165,7 @@ lazy val awsCdkScala = project
164165
rds,
165166
redshift,
166167
regioninfo,
168+
rekognition,
167169
resourcegroups,
168170
robomaker,
169171
route53,
@@ -195,6 +197,7 @@ lazy val awsCdkScala = project
195197
transfer,
196198
waf,
197199
wafv2,
200+
wisdom,
198201
workspaces,
199202
xray
200203
)
@@ -1024,6 +1027,12 @@ lazy val opsworkscm = project
10241027
.withCdk()
10251028
.enablePublishing()
10261029

1030+
lazy val panorama = project
1031+
.in(file("modules/panorama"))
1032+
.dependsOn(core)
1033+
.withCdk()
1034+
.enablePublishing()
1035+
10271036
lazy val pinpoint = project
10281037
.in(file("modules/pinpoint"))
10291038
.dependsOn(core)
@@ -1078,6 +1087,12 @@ lazy val regioninfo = project
10781087
.withCdk()
10791088
.enablePublishing()
10801089

1090+
lazy val rekognition = project
1091+
.in(file("modules/rekognition"))
1092+
.dependsOn(core)
1093+
.withCdk()
1094+
.enablePublishing()
1095+
10811096
lazy val resourcegroups = project
10821097
.in(file("modules/resourcegroups"))
10831098
.dependsOn(core)
@@ -1264,6 +1279,12 @@ lazy val wafv2 = project
12641279
.withCdk()
12651280
.enablePublishing()
12661281

1282+
lazy val wisdom = project
1283+
.in(file("modules/wisdom"))
1284+
.dependsOn(core)
1285+
.withCdk()
1286+
.enablePublishing()
1287+
12671288
lazy val workspaces = project
12681289
.in(file("modules/workspaces"))
12691290
.dependsOn(core)

codegen/src/main/scala/io/burkard/cdk/codegen/CdkBuilder.scala

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import java.lang.reflect.{Method, Modifier}
44
import java.nio.file.{Path, Paths}
55

66
import scala.annotation.nowarn
7+
import scala.util.Try
8+
9+
import com.google.common.base.CaseFormat
710

811
import io.burkard.cdk.codegen.CdkBuilder.ConstructorType
912

@@ -15,8 +18,26 @@ final case class CdkBuilder private[codegen](
1518
constructorType: CdkBuilder.ConstructorType,
1619
underlying: Class[_]
1720
) {
21+
// The required field names of the underlying builder props.
22+
private[codegen] lazy val requiredFieldNames: Set[String] =
23+
(for {
24+
// The `props` field is a builder for all required & optional properties.
25+
propsBuilder <- Try(underlying.getDeclaredField("props")).map(_.getType)
26+
27+
// The `build` method returns an instance of the props itself, which needs to be inspected.
28+
props <- Try(propsBuilder.getDeclaredMethod("build")).map(_.getReturnType)
29+
30+
// Dig into `props` for all non-static `get` methods without a default implementation.
31+
requiredFields = props.getDeclaredMethods.toList
32+
.collect {
33+
case m if !Modifier.isStatic(m.getModifiers) && m.getName.startsWith("get") && !m.isDefault =>
34+
CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, m.getName.stripPrefix("get"))
35+
}
36+
.toSet
37+
} yield requiredFields).getOrElse(Set.empty)
38+
1839
@nowarn("cat=deprecation")
19-
// [0, N] field methods of the underlying builder. All are optional for the generated code.
40+
// [0, N] field methods of the underlying builder. All non-optional fields appear before optional fields.
2041
private[this] lazy val fieldMethods: List[FieldMethod] =
2142
underlying
2243
.getMethods
@@ -38,7 +59,7 @@ final case class CdkBuilder private[codegen](
3859
methodName,
3960
methodName,
4061
typeName,
41-
isOptional = true,
62+
isOptional = !requiredFieldNames.contains(methodName),
4263
annotations
4364
)
4465
)
@@ -51,12 +72,13 @@ final case class CdkBuilder private[codegen](
5172
s"$methodName$index",
5273
methodName,
5374
typeName,
54-
isOptional = true,
75+
isOptional = !requiredFieldNames.contains(methodName),
5576
annotations
5677
)
5778
}
5879
}
5980
.toList
81+
.sortBy(_.isOptional)
6082

6183
lazy val packageName: String = renamePackage(underlying.getPackageName)
6284

codegen/src/main/scala/io/burkard/cdk/codegen/Codegen.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ object Codegen {
2424
classInfo.getPackageName match {
2525
// Resource for some service.
2626
case ServiceRegex(_, name) =>
27-
name -> classInfo.load()
27+
// Bundle deprecated assets in core module.
28+
// TODO Remove once deprecated assets are gone.
29+
if (name.startsWith("assets")) {
30+
"core" -> classInfo.load()
31+
} else {
32+
name -> classInfo.load()
33+
}
2834

2935
// Shared resources are considered `core`.
3036
case CoreRegex() =>

codegen/src/main/scala/io/burkard/cdk/codegen/package.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,15 @@ package object codegen {
1414
private[this] val packageRewrites: List[(Regex, Regex.Match => String)] =
1515
List(
1616
ServiceRegex -> { m =>
17+
// Bundle deprecated assets in core module.
18+
// TODO Remove once deprecated assets are gone.
1719
if (m.group(1) == null) {
18-
s"io.burkard.cdk.${m.group(2)}"
20+
val second = m.group(2)
21+
if (second.startsWith("assets")) {
22+
s"io.burkard.cdk.core.$second"
23+
} else {
24+
s"io.burkard.cdk.$second"
25+
}
1926
} else {
2027
s"io.burkard.cdk.services.${m.group(2)}"
2128
}

codegen/src/test/scala/io/burkard/cdk/codegen/CdkBuilderSpec.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ class CdkBuilderSpec extends AnyFlatSpec with Matchers with OptionValues {
3131
.value mustBe directConstructorCdkBuilder
3232
}
3333

34+
it should "identify required fields" in {
35+
CdkBuilder
36+
.build(requiredFieldsServiceName, requiredFieldsBuilderClass)
37+
.value
38+
.requiredFieldNames mustBe requiredFieldsNames
39+
}
40+
3441
it should "reject a non-builder class" in {
3542
import CdkBuilderTestFixtures.Invalid._
3643

codegen/src/test/scala/io/burkard/cdk/codegen/CdkBuilderTestFixtures.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package io.burkard.cdk.codegen
33
import software.amazon.awscdk.Tag
44
import software.amazon.awscdk.services.cloudwatch.CfnDashboardProps
55
import software.amazon.awscdk.services.ec2.Connections
6+
import software.amazon.awscdk.services.kinesisanalytics.CfnApplicationV2
67
import software.amazon.awscdk.services.route53.CaaRecord
78

89
object CdkBuilderTestFixtures {
@@ -79,6 +80,14 @@ object CdkBuilderTestFixtures {
7980
constructorType = CdkBuilder.ConstructorType.DirectConstructorNoParameters,
8081
underlying = directConstructorBuilderClass
8182
)
83+
84+
val requiredFieldsServiceName: String = "kinesisanalytics"
85+
86+
lazy val requiredFieldsBuilderClass: Class[CfnApplicationV2.Builder] =
87+
classOf[CfnApplicationV2.Builder]
88+
89+
val requiredFieldsNames: Set[String] =
90+
Set("serviceExecutionRole", "runtimeEnvironment")
8291
}
8392

8493
object Invalid {

example/src/main/scala/io/burkard/cdk/example/ExampleApp.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ object ExampleApp extends App {
2020

2121
CfnApplicationV2(
2222
internalResourceId = "Runtime",
23+
serviceExecutionRole = "arn:example-role",
24+
runtimeEnvironment = "FLINK-1_13",
2325
tags = Some(
2426
List(
2527
CfnTag(key = Some("env"), value = Some(env)),
@@ -46,9 +48,7 @@ object ExampleApp extends App {
4648
)
4749
)
4850
)
49-
),
50-
serviceExecutionRole = Some("arn:example-role"),
51-
runtimeEnvironment = Some("FLINK-1_13")
51+
)
5252
)
5353
}
5454
}

modules/accessanalyzer/src/main/scala/io/burkard/cdk/services/accessanalyzer/CfnAnalyzer.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ object CfnAnalyzer {
88

99
def apply(
1010
internalResourceId: String,
11+
`type`: String,
1112
tags: Option[List[_ <: software.amazon.awscdk.CfnTag]] = None,
1213
analyzerName: Option[String] = None,
13-
`type`: Option[String] = None,
1414
archiveRules: Option[List[_]] = None
1515
)(implicit stackCtx: software.amazon.awscdk.Stack): software.amazon.awscdk.services.accessanalyzer.CfnAnalyzer =
1616
software.amazon.awscdk.services.accessanalyzer.CfnAnalyzer.Builder
1717
.create(stackCtx, internalResourceId)
18+
.`type`(`type`)
1819
.tags(tags.map(_.asJava).orNull)
1920
.analyzerName(analyzerName.orNull)
20-
.`type`(`type`.orNull)
2121
.archiveRules(archiveRules.map(_.asJava).orNull)
2222
.build()
2323
}

modules/acmpca/src/main/scala/io/burkard/cdk/services/acmpca/CfnCertificate.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@ object CfnCertificate {
55

66
def apply(
77
internalResourceId: String,
8+
certificateAuthorityArn: String,
9+
signingAlgorithm: String,
10+
validity: software.amazon.awscdk.services.acmpca.CfnCertificate.ValidityProperty,
11+
certificateSigningRequest: String,
812
apiPassthrough: Option[software.amazon.awscdk.services.acmpca.CfnCertificate.ApiPassthroughProperty] = None,
913
validityNotBefore: Option[software.amazon.awscdk.services.acmpca.CfnCertificate.ValidityProperty] = None,
10-
certificateAuthorityArn: Option[String] = None,
11-
signingAlgorithm: Option[String] = None,
12-
validity: Option[software.amazon.awscdk.services.acmpca.CfnCertificate.ValidityProperty] = None,
13-
templateArn: Option[String] = None,
14-
certificateSigningRequest: Option[String] = None
14+
templateArn: Option[String] = None
1515
)(implicit stackCtx: software.amazon.awscdk.Stack): software.amazon.awscdk.services.acmpca.CfnCertificate =
1616
software.amazon.awscdk.services.acmpca.CfnCertificate.Builder
1717
.create(stackCtx, internalResourceId)
18+
.certificateAuthorityArn(certificateAuthorityArn)
19+
.signingAlgorithm(signingAlgorithm)
20+
.validity(validity)
21+
.certificateSigningRequest(certificateSigningRequest)
1822
.apiPassthrough(apiPassthrough.orNull)
1923
.validityNotBefore(validityNotBefore.orNull)
20-
.certificateAuthorityArn(certificateAuthorityArn.orNull)
21-
.signingAlgorithm(signingAlgorithm.orNull)
22-
.validity(validity.orNull)
2324
.templateArn(templateArn.orNull)
24-
.certificateSigningRequest(certificateSigningRequest.orNull)
2525
.build()
2626
}

0 commit comments

Comments
 (0)