Skip to content

Commit ed9e054

Browse files
authored
Refactor SetResourceForStruct to iterate over targetShape members (#289)
Issue #, if available: aws-controllers-k8s/community#1146 After a recent update to `/pkg/model/field.go`, shapes _may_ contain **additional** fields/members with a "nested" format such as **DHCPOptions.Fields**: `[DHCPConfigurations TagSpecifications.Tags.Value Tags.Value TagSpecifications DHCPConfigurations.Values TagSpecifications.ResourceType TagSpecifications.Tags Tags.Key DHCPOptionsID OwnerID DHCPConfigurations.Key TagSpecifications.Tags.Key DryRun Tags]` The purpose of that update is to allow users to easily fetch nested shapes and their corresponding configurations using the "nested" field name as the key. However, `SetResourceForStruct` will never have the opportunity to process and/or fetch shapes and configs for these "nested" fields because the algorithm processes fields **iff they exist in sourceShape**. *Note, sourceShape comes directly from `aws-sdk` in this context, so will NOT have these additional, nested fields.* This patch iterates over `targetShape.Members` instead of `sourceShape` so these "nested" fields can be included in the lookup logic, but continues to use `sourceShape` index for consistency throughout codebase. There's no change in functionality, but this paves the way for a follow-up PR to check a targetShape's nested Field `SetConfig` if the Field cannot be found in the sourceShape: ``` sourceMemberShapeRef := sourceShape.MemberRefs[targetMemberName] if sourceMemberShapeRef == nil { continue } // Future patch: check if targetMemberName has SetConfig logic that needs to be processed ``` By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent edec6da commit ed9e054

File tree

3 files changed

+63
-18
lines changed

3 files changed

+63
-18
lines changed

pkg/generate/code/common.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package code
1515

1616
import (
17+
"fmt"
1718
"strings"
1819

1920
awssdkmodel "github.com/aws/aws-sdk-go/private/model/api"
@@ -188,3 +189,14 @@ func FindPrimaryIdentifierFieldNames(
188189
}
189190
return crField, shapeField
190191
}
192+
193+
// GetMemberIndex returns the index of memberName by iterating over
194+
// shape's slice of member names for deterministic ordering
195+
func GetMemberIndex(shape *awssdkmodel.Shape, memberName string) (int, error) {
196+
for index, shapeMemberName := range shape.MemberNames() {
197+
if strings.EqualFold(shapeMemberName, memberName) {
198+
return index, nil
199+
}
200+
}
201+
return -1, fmt.Errorf("Could not find %s in shape %s", memberName, shape.ShapeName)
202+
}

pkg/generate/code/common_test.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,27 @@ func TestFindPluralizedIdentifiersInShape_EC2_SG_ReadMany_Rename(t *testing.T) {
176176

177177
assert.Equal(expModelIdentifier, crIdentifier)
178178
assert.Equal(expShapeIdentifier, shapeIdentifier)
179-
}
179+
}
180+
181+
func TestGetMemberIndex_EC2_DHCPOptions_ReadMany(t *testing.T) {
182+
assert := assert.New(t)
183+
require := require.New(t)
184+
185+
g := testutil.NewModelForService(t, "ec2")
186+
187+
crd := testutil.GetCRDByName(t, g, "DhcpOptions")
188+
require.NotNil(crd)
189+
190+
op := crd.Ops.ReadMany
191+
inputShape := op.InputRef.Shape
192+
// inputShape members: [DhcpOptionsIds DryRun Filters MaxResults NextToken]
193+
194+
memberIndex, _ := code.GetMemberIndex(inputShape, "DhcpOptionsIds")
195+
assert.Equal(0, memberIndex)
196+
memberIndex, _ = code.GetMemberIndex(inputShape, "MaxResults")
197+
assert.Equal(3, memberIndex)
198+
199+
memberIndex, err := code.GetMemberIndex(inputShape, "notValidMember")
200+
assert.Equal(-1, memberIndex)
201+
assert.NotNil(err)
202+
}

pkg/generate/code/set_resource.go

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,53 +1226,63 @@ func SetResourceForStruct(
12261226
sourceShape := sourceShapeRef.Shape
12271227
targetShape := targetShapeRef.Shape
12281228

1229-
for memberIndex, memberName := range sourceShape.MemberNames() {
1230-
targetMemberShapeRef := targetShape.MemberRefs[memberName]
1231-
if targetMemberShapeRef == nil {
1229+
for _, targetMemberName := range targetShape.MemberNames() {
1230+
sourceMemberShapeRef := sourceShape.MemberRefs[targetMemberName]
1231+
if sourceMemberShapeRef == nil {
12321232
continue
12331233
}
1234-
memberVarName := fmt.Sprintf("%sf%d", targetVarName, memberIndex)
1235-
memberShapeRef := sourceShape.MemberRefs[memberName]
1236-
memberShape := memberShapeRef.Shape
1237-
cleanNames := names.New(memberName)
1238-
sourceAdaptedVarName := sourceVarName + "." + memberName
1234+
// Upstream logic iterates over sourceShape members and therefore uses
1235+
// the sourceShape's index; continue using sourceShape's index here for consistency.
1236+
sourceMemberIndex, err := GetMemberIndex(sourceShape, targetMemberName)
1237+
if err != nil {
1238+
msg := fmt.Sprintf(
1239+
"could not determine source shape index: %v", err)
1240+
panic(msg)
1241+
}
1242+
1243+
targetMemberShapeRef := targetShape.MemberRefs[targetMemberName]
1244+
indexedVarName := fmt.Sprintf("%sf%d", targetVarName, sourceMemberIndex)
1245+
sourceMemberShape := sourceMemberShapeRef.Shape
1246+
targetMemberCleanNames := names.New(targetMemberName)
1247+
sourceAdaptedVarName := sourceVarName + "." + targetMemberName
12391248
out += fmt.Sprintf(
12401249
"%sif %s != nil {\n", indent, sourceAdaptedVarName,
12411250
)
12421251
qualifiedTargetVar := fmt.Sprintf(
1243-
"%s.%s", targetVarName, cleanNames.Camel,
1252+
"%s.%s", targetVarName, targetMemberCleanNames.Camel,
12441253
)
1245-
switch memberShape.Type {
1254+
1255+
switch sourceMemberShape.Type {
12461256
case "list", "structure", "map":
12471257
{
12481258
out += varEmptyConstructorK8sType(
12491259
cfg, r,
1250-
memberVarName,
1260+
indexedVarName,
12511261
targetMemberShapeRef.Shape,
12521262
indentLevel+1,
12531263
)
12541264
out += setResourceForContainer(
12551265
cfg, r,
1256-
cleanNames.Camel,
1257-
memberVarName,
1266+
targetMemberCleanNames.Camel,
1267+
indexedVarName,
12581268
targetMemberShapeRef,
12591269
nil,
12601270
sourceAdaptedVarName,
1261-
memberShapeRef,
1271+
sourceMemberShapeRef,
12621272
indentLevel+1,
12631273
)
12641274
out += setResourceForScalar(
12651275
qualifiedTargetVar,
1266-
memberVarName,
1267-
memberShapeRef,
1276+
indexedVarName,
1277+
sourceMemberShapeRef,
12681278
indentLevel+1,
12691279
)
12701280
}
12711281
default:
12721282
out += setResourceForScalar(
12731283
qualifiedTargetVar,
12741284
sourceAdaptedVarName,
1275-
memberShapeRef,
1285+
sourceMemberShapeRef,
12761286
indentLevel+1,
12771287
)
12781288
}

0 commit comments

Comments
 (0)