Skip to content

Commit 9f6ca92

Browse files
authored
Allow OperatorType to be a list such that one API can map to multiple operations (#166)
Allow OperatorType to be a list such that one API can map to multiple operations. This is required in certain cases where the same API call maps to both Create and Update operations such as `RegisterScalableTarget` and `PutScalingPolicy` [Link to ApplicationAutoscaling PR with the related change](aws-controllers-k8s/applicationautoscaling-controller#27) Note: This change will require all other services to update their generator configs as well. Issue #, if available: aws-controllers-k8s/community#867 ### Description of changes: The `getOpTypeAndResourceName` method handles each of the following cases same as before in addition to the new case 5- 1. the cfg itself is nil 2. cfg is not nil but opId is not in the cfg 3. cfg is not nil, the opID is in the cfg but the opType is not specified ``` operations: DescribeScalableTargets: primary_identifier_field_name: ResourceID ``` 4. One API -> one operations ``` operations: PutScalingPolicy: operation_type: - Create ``` 5. One API -> multiple operations ``` operations: PutScalingPolicy: operation_type: - Create - Update ``` ### Testing - I tested by generating the controller code for both applicationAutoscaling and the SageMaker repos. - The unit tests pass as is. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent ea9b76d commit 9f6ca92

File tree

2 files changed

+47
-17
lines changed

2 files changed

+47
-17
lines changed

pkg/generate/config/operation.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,17 @@
1414
package config
1515

1616
import (
17+
"encoding/json"
18+
1719
awssdkmodel "github.com/aws/aws-sdk-go/private/model/api"
1820

19-
"github.com/aws-controllers-k8s/code-generator/pkg/util"
21+
"github.com/aws-controllers-k8s/code-generator/pkg/util"
2022
)
2123

24+
// StringArray is a type that can be represented in JSON as *either* a string
25+
// *or* an array of strings
26+
type StringArray []string
27+
2228
// OperationConfig represents instructions to the ACK code generator to
2329
// specify the overriding values for API operation parameters and its custom implementation.
2430
type OperationConfig struct {
@@ -37,7 +43,8 @@ type OperationConfig struct {
3743
ResourceName string `json:"resource_name"`
3844
// Override for operation type in case of heuristic failure
3945
// An example of this is `Put...` or `Register...` API operations not being correctly classified as `Create` op type
40-
OperationType string `json:"operation_type"`
46+
// OperationType []string `json:"operation_type"`
47+
OperationType StringArray `json:"operation_type"`
4148
// PrimaryIdentifierFieldName provides the name of the field that should be
4249
// interpreted as the "primary" identifier field. This field will be used as
4350
// the primary field for resource adoption.
@@ -75,3 +82,21 @@ func (c *Config) ListOpMatchFieldNames(
7582
}
7683
return rConfig.ListOperation.MatchFields
7784
}
85+
86+
// UnmarshalJSON parses input for a either a string or
87+
// or a list and returns a StringArray.
88+
func (a *StringArray) UnmarshalJSON(b []byte) error {
89+
var multi []string
90+
err := json.Unmarshal(b, &multi)
91+
if err != nil {
92+
var single string
93+
err := json.Unmarshal(b, &single)
94+
if err != nil {
95+
return err
96+
}
97+
*a = []string{single}
98+
} else {
99+
*a = multi
100+
}
101+
return nil
102+
}

pkg/model/sdk_helper.go

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
ackgenconfig "github.com/aws-controllers-k8s/code-generator/pkg/generate/config"
2828
"github.com/aws-controllers-k8s/code-generator/pkg/names"
2929
"github.com/aws-controllers-k8s/code-generator/pkg/util"
30+
3031
awssdkmodel "github.com/aws/aws-sdk-go/private/model/api"
3132
)
3233

@@ -206,11 +207,13 @@ func (a *SDKAPI) GetOperationMap(cfg *ackgenconfig.Config) *OperationMap {
206207
// create an index of Operations by operation types and resource name
207208
opMap := OperationMap{}
208209
for opID, op := range a.API.Operations {
209-
opType, resName := getOpTypeAndResourceName(opID, cfg)
210-
if _, found := opMap[opType]; !found {
211-
opMap[opType] = map[string]*awssdkmodel.Operation{}
210+
opTypeArray, resName := getOpTypeAndResourceName(opID, cfg)
211+
for _, opType := range opTypeArray {
212+
if _, found := opMap[opType]; !found {
213+
opMap[opType] = map[string]*awssdkmodel.Operation{}
214+
}
215+
opMap[opType][resName] = op
212216
}
213-
opMap[opType][resName] = op
214217
}
215218
a.opMap = &opMap
216219
return &opMap
@@ -382,20 +385,22 @@ func (a *SDKAPI) SDKAPIInterfaceTypeName() string {
382385
}
383386

384387
// Override the operation type and/or resource name if specified in config
385-
func getOpTypeAndResourceName(opID string, cfg *ackgenconfig.Config) (OpType, string) {
388+
func getOpTypeAndResourceName(opID string, cfg *ackgenconfig.Config) ([]OpType, string) {
386389
opType, resName := GetOpTypeAndResourceNameFromOpID(opID)
390+
opTypes := []OpType{opType}
387391

388-
if cfg != nil {
389-
if operationConfig, exists := cfg.Operations[opID]; exists {
390-
if operationConfig.OperationType != "" {
391-
opType = OpTypeFromString(operationConfig.OperationType)
392-
}
392+
if cfg == nil {
393+
return opTypes, resName
394+
}
395+
if operationConfig, exists := cfg.Operations[opID]; exists {
396+
if operationConfig.ResourceName != "" {
397+
resName = operationConfig.ResourceName
398+
}
393399

394-
if operationConfig.ResourceName != "" {
395-
resName = operationConfig.ResourceName
396-
}
400+
for _, operationType := range operationConfig.OperationType {
401+
opType = OpTypeFromString(operationType)
402+
opTypes = append(opTypes, opType)
397403
}
398404
}
399-
400-
return opType, resName
405+
return opTypes, resName
401406
}

0 commit comments

Comments
 (0)