Skip to content

Commit 90c0649

Browse files
authored
Merge pull request #121 from Clever/dead-7-migrate-1
migrate to aws-sdk-go v2
2 parents 6bbd243 + 6eca74a commit 90c0649

File tree

9 files changed

+252
-164
lines changed

9 files changed

+252
-164
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ mocks:
3939
mkdir -p bin
4040
go build -o bin/mockgen -mod=vendor ./vendor/github.com/golang/mock/mockgen
4141
rm -rf mocks/mock_*.go
42-
./bin/mockgen -source ./vendor/github.com/aws/aws-sdk-go/service/sfn/sfniface/interface.go -destination mocks/mock_sfn.go -package mocks
43-
./bin/mockgen -source ./vendor/github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface/interface.go -destination mocks/mock_cloudwatch.go -package mocks
42+
./bin/mockgen -source cmd/sfncli/runner.go -destination mocks/mock_sfn.go -package mocks
43+
./bin/mockgen -source cmd/sfncli/cloudwatchreporter.go -destination mocks/mock_cloudwatch.go -package mocks
4444

4545
install_deps:
4646
go mod vendor

cmd/sfncli/cloudwatchreporter.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,23 @@ import (
55
"sync"
66
"time"
77

8-
"github.com/aws/aws-sdk-go/aws"
9-
"github.com/aws/aws-sdk-go/service/cloudwatch"
10-
"github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface"
11-
"gopkg.in/Clever/kayvee-go.v6/logger"
8+
"github.com/Clever/kayvee-go/v7/logger"
9+
"github.com/aws/aws-sdk-go-v2/aws"
10+
"github.com/aws/aws-sdk-go-v2/service/cloudwatch"
11+
"github.com/aws/aws-sdk-go-v2/service/cloudwatch/types"
1212
)
1313

14+
// CloudWatchAPI defines the interface for CloudWatch API operations used by sfncli
15+
type CloudWatchAPI interface {
16+
PutMetricData(ctx context.Context, params *cloudwatch.PutMetricDataInput, optFns ...func(*cloudwatch.Options)) (*cloudwatch.PutMetricDataOutput, error)
17+
}
18+
1419
const metricNameActivityActivePercent = "ActivityActivePercent"
1520
const namespaceStatesCustom = "StatesCustom"
1621

1722
// CloudWatchReporter reports useful metrics about the activity.
1823
type CloudWatchReporter struct {
19-
cwapi cloudwatchiface.CloudWatchAPI
24+
cwapi CloudWatchAPI
2025
activityArn string
2126

2227
// state to keep track of active percent
@@ -33,7 +38,7 @@ type CloudWatchReporter struct {
3338
lastPausedStateChange time.Time
3439
}
3540

36-
func NewCloudWatchReporter(cwapi cloudwatchiface.CloudWatchAPI, activityArn string) *CloudWatchReporter {
41+
func NewCloudWatchReporter(cwapi CloudWatchAPI, activityArn string) *CloudWatchReporter {
3742
now := time.Now()
3843
c := &CloudWatchReporter{
3944
cwapi: cwapi,
@@ -57,7 +62,7 @@ func (c *CloudWatchReporter) ReportActivePercent(ctx context.Context, interval t
5762
case <-ctx.Done():
5863
break
5964
case <-ticker.C:
60-
c.report()
65+
c.report(ctx)
6166
}
6267
}
6368
}
@@ -109,7 +114,7 @@ func maxTime(a, b time.Time) time.Time {
109114
}
110115

111116
// report computes and sends the active time metric to cloudwatch, resetting state related to tracking active time.
112-
func (c *CloudWatchReporter) report() {
117+
func (c *CloudWatchReporter) report(ctx context.Context) {
113118
c.mu.Lock()
114119
defer c.mu.Unlock()
115120
now := time.Now()
@@ -133,23 +138,24 @@ func (c *CloudWatchReporter) report() {
133138
c.activeTime = time.Duration(0)
134139
c.pausedTime = time.Duration(0)
135140
// fire and forget the metric
136-
go c.putMetricData(activePercent)
141+
go c.putMetricData(ctx, activePercent)
137142
}
138143

139-
func (c *CloudWatchReporter) putMetricData(activePercent float64) {
144+
func (c *CloudWatchReporter) putMetricData(ctx context.Context, activePercent float64) {
140145
log.TraceD("put-metric-data", logger.M{"activity-arn": c.activityArn, "metric-name": metricNameActivityActivePercent, "value": activePercent})
141-
if _, err := c.cwapi.PutMetricData(&cloudwatch.PutMetricDataInput{
142-
MetricData: []*cloudwatch.MetricDatum{{
143-
Dimensions: []*cloudwatch.Dimension{{
146+
_, err := c.cwapi.PutMetricData(ctx, &cloudwatch.PutMetricDataInput{
147+
MetricData: []types.MetricDatum{{
148+
Dimensions: []types.Dimension{{
144149
Name: aws.String("ActivityArn"),
145150
Value: aws.String(c.activityArn),
146151
}},
147152
MetricName: aws.String(metricNameActivityActivePercent),
148-
Unit: aws.String(cloudwatch.StandardUnitPercent),
153+
Unit: types.StandardUnitPercent,
149154
Value: aws.Float64(activePercent),
150155
}},
151156
Namespace: aws.String(namespaceStatesCustom),
152-
}); err != nil {
157+
})
158+
if err != nil {
153159
log.ErrorD("put-metric-data", logger.M{"error": err.Error()})
154160
}
155161
}

cmd/sfncli/cloudwatchreporter_test.go

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import (
99
"time"
1010

1111
"github.com/Clever/sfncli/mocks"
12-
"github.com/aws/aws-sdk-go/aws"
13-
"github.com/aws/aws-sdk-go/service/cloudwatch"
12+
"github.com/aws/aws-sdk-go-v2/aws"
13+
"github.com/aws/aws-sdk-go-v2/service/cloudwatch"
14+
"github.com/aws/aws-sdk-go-v2/service/cloudwatch/types"
1415
"github.com/golang/mock/gomock"
1516
)
1617

@@ -24,14 +25,14 @@ func TestCloudWatchReporterReportsActiveZero(t *testing.T) {
2425
mockCW := mocks.NewMockCloudWatchAPI(controller)
2526
cwr := NewCloudWatchReporter(mockCW, mockActivityArn)
2627
go cwr.ReportActivePercent(testCtx, 100*time.Millisecond)
27-
mockCW.EXPECT().PutMetricData(&cloudwatch.PutMetricDataInput{
28-
MetricData: []*cloudwatch.MetricDatum{{
29-
Dimensions: []*cloudwatch.Dimension{{
28+
mockCW.EXPECT().PutMetricData(gomock.Any(), &cloudwatch.PutMetricDataInput{
29+
MetricData: []types.MetricDatum{{
30+
Dimensions: []types.Dimension{{
3031
Name: aws.String("ActivityArn"),
3132
Value: aws.String(mockActivityArn),
3233
}},
3334
MetricName: aws.String(metricNameActivityActivePercent),
34-
Unit: aws.String(cloudwatch.StandardUnitPercent),
35+
Unit: types.StandardUnitPercent,
3536
Value: aws.Float64(0.0),
3637
}},
3738
Namespace: aws.String(namespaceStatesCustom),
@@ -45,14 +46,14 @@ func TestCloudWatchReporterReportsActiveFiftyPercent(t *testing.T) {
4546
controller := gomock.NewController(t)
4647
defer controller.Finish()
4748
mockCW := mocks.NewMockCloudWatchAPI(controller)
48-
mockCW.EXPECT().PutMetricData(fuzzy(&cloudwatch.PutMetricDataInput{
49-
MetricData: []*cloudwatch.MetricDatum{{
50-
Dimensions: []*cloudwatch.Dimension{{
49+
mockCW.EXPECT().PutMetricData(gomock.Any(), fuzzy(&cloudwatch.PutMetricDataInput{
50+
MetricData: []types.MetricDatum{{
51+
Dimensions: []types.Dimension{{
5152
Name: aws.String("ActivityArn"),
5253
Value: aws.String(mockActivityArn),
5354
}},
5455
MetricName: aws.String(metricNameActivityActivePercent),
55-
Unit: aws.String(cloudwatch.StandardUnitPercent),
56+
Unit: types.StandardUnitPercent,
5657
Value: aws.Float64(50.0),
5758
}},
5859
Namespace: aws.String(namespaceStatesCustom),
@@ -76,14 +77,14 @@ func TestCloudWatchReporterReportsActiveHundredPercent(t *testing.T) {
7677
controller := gomock.NewController(t)
7778
defer controller.Finish()
7879
mockCW := mocks.NewMockCloudWatchAPI(controller)
79-
mockCW.EXPECT().PutMetricData(fuzzy(&cloudwatch.PutMetricDataInput{
80-
MetricData: []*cloudwatch.MetricDatum{{
81-
Dimensions: []*cloudwatch.Dimension{{
80+
mockCW.EXPECT().PutMetricData(gomock.Any(), fuzzy(&cloudwatch.PutMetricDataInput{
81+
MetricData: []types.MetricDatum{{
82+
Dimensions: []types.Dimension{{
8283
Name: aws.String("ActivityArn"),
8384
Value: aws.String(mockActivityArn),
8485
}},
8586
MetricName: aws.String(metricNameActivityActivePercent),
86-
Unit: aws.String(cloudwatch.StandardUnitPercent),
87+
Unit: types.StandardUnitPercent,
8788
Value: aws.Float64(100.0),
8889
}},
8990
Namespace: aws.String(namespaceStatesCustom),
@@ -100,14 +101,14 @@ func TestCloudWatchReporterReportsActiveOneHundredPercentWhenPausedForever(t *te
100101
controller := gomock.NewController(t)
101102
defer controller.Finish()
102103
mockCW := mocks.NewMockCloudWatchAPI(controller)
103-
mockCW.EXPECT().PutMetricData(fuzzy(&cloudwatch.PutMetricDataInput{
104-
MetricData: []*cloudwatch.MetricDatum{{
105-
Dimensions: []*cloudwatch.Dimension{{
104+
mockCW.EXPECT().PutMetricData(gomock.Any(), fuzzy(&cloudwatch.PutMetricDataInput{
105+
MetricData: []types.MetricDatum{{
106+
Dimensions: []types.Dimension{{
106107
Name: aws.String("ActivityArn"),
107108
Value: aws.String(mockActivityArn),
108109
}},
109110
MetricName: aws.String(metricNameActivityActivePercent),
110-
Unit: aws.String(cloudwatch.StandardUnitPercent),
111+
Unit: types.StandardUnitPercent,
111112
Value: aws.Float64(100.0),
112113
}},
113114
Namespace: aws.String(namespaceStatesCustom),
@@ -138,14 +139,14 @@ func TestCloudWatchReporterReportsActiveOnehundredPercentWhenPaused(t *testing.T
138139
controller := gomock.NewController(t)
139140
defer controller.Finish()
140141
mockCW := mocks.NewMockCloudWatchAPI(controller)
141-
mockCW.EXPECT().PutMetricData(fuzzy(&cloudwatch.PutMetricDataInput{
142-
MetricData: []*cloudwatch.MetricDatum{{
143-
Dimensions: []*cloudwatch.Dimension{{
142+
mockCW.EXPECT().PutMetricData(gomock.Any(), fuzzy(&cloudwatch.PutMetricDataInput{
143+
MetricData: []types.MetricDatum{{
144+
Dimensions: []types.Dimension{{
144145
Name: aws.String("ActivityArn"),
145146
Value: aws.String(mockActivityArn),
146147
}},
147148
MetricName: aws.String(metricNameActivityActivePercent),
148-
Unit: aws.String(cloudwatch.StandardUnitPercent),
149+
Unit: types.StandardUnitPercent,
149150
Value: aws.Float64(100.0),
150151
}},
151152
Namespace: aws.String(namespaceStatesCustom),
@@ -174,14 +175,14 @@ func TestCloudWatchReporterReportsActiveFiftyPercentWhenPaused(t *testing.T) {
174175
controller := gomock.NewController(t)
175176
defer controller.Finish()
176177
mockCW := mocks.NewMockCloudWatchAPI(controller)
177-
mockCW.EXPECT().PutMetricData(fuzzy(&cloudwatch.PutMetricDataInput{
178-
MetricData: []*cloudwatch.MetricDatum{{
179-
Dimensions: []*cloudwatch.Dimension{{
178+
mockCW.EXPECT().PutMetricData(gomock.Any(), fuzzy(&cloudwatch.PutMetricDataInput{
179+
MetricData: []types.MetricDatum{{
180+
Dimensions: []types.Dimension{{
180181
Name: aws.String("ActivityArn"),
181182
Value: aws.String(mockActivityArn),
182183
}},
183184
MetricName: aws.String(metricNameActivityActivePercent),
184-
Unit: aws.String(cloudwatch.StandardUnitPercent),
185+
Unit: types.StandardUnitPercent,
185186
Value: aws.Float64(50.0),
186187
}},
187188
Namespace: aws.String(namespaceStatesCustom),
@@ -225,7 +226,9 @@ func (f fuzzyMatcher) Matches(x interface{}) bool {
225226
return reflect.DeepEqual(f.expected, got)
226227
}
227228
for i, md := range f.expected.MetricData {
228-
if math.Abs(aws.Float64Value(md.Value)-aws.Float64Value(got.MetricData[i].Value)) > epsilon {
229+
expectedValue := *md.Value
230+
gotValue := *got.MetricData[i].Value
231+
if math.Abs(expectedValue-gotValue) > epsilon {
229232
return false
230233
}
231234
// so that deepequal succeeds, make values match exactly if they're within epsilon

cmd/sfncli/error_names.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package main
22

33
import (
4+
"context"
45
"fmt"
56
"strings"
67

7-
"github.com/aws/aws-sdk-go/aws"
8-
"github.com/aws/aws-sdk-go/service/sfn"
9-
"gopkg.in/Clever/kayvee-go.v6/logger"
8+
"github.com/Clever/kayvee-go/v7/logger"
9+
"github.com/aws/aws-sdk-go-v2/aws"
10+
"github.com/aws/aws-sdk-go-v2/service/sfn"
1011
)
1112

1213
// States language has the concept of "Error Names"--unique strings that correspond
@@ -31,13 +32,14 @@ func (t TaskRunner) sendTaskFailure(err TaskFailureError) error {
3132
const maxErrorLength = 256
3233
const maxCauseLength = 32768
3334

34-
// don't use SendTaskFailureWithContext, since the failure itself could be from the parent
35-
// context being cancelled, but we still want to report to AWS the failure of the task.
36-
_, sendErr := t.sfnapi.SendTaskFailure(&sfn.SendTaskFailureInput{
37-
Error: aws.String(truncateString(err.ErrorName(), maxErrorLength, "[truncated]")),
38-
Cause: aws.String(truncateString(err.ErrorCause(), maxCauseLength, "[truncated]")),
39-
TaskToken: &t.taskToken,
40-
})
35+
_, sendErr := t.sfnapi.SendTaskFailure(
36+
context.Background(),
37+
&sfn.SendTaskFailureInput{
38+
Error: aws.String(truncateString(err.ErrorName(), maxErrorLength, "[truncated]")),
39+
Cause: aws.String(truncateString(err.ErrorCause(), maxCauseLength, "[truncated]")),
40+
TaskToken: &t.taskToken,
41+
},
42+
)
4143
if sendErr != nil {
4244
t.logger.ErrorD("send-task-failure-error", logger.M{"error": sendErr.Error()})
4345
}

cmd/sfncli/runner.go

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@ import (
1414
"syscall"
1515
"time"
1616

17+
"github.com/Clever/kayvee-go/v7/logger"
1718
"github.com/armon/circbuf"
18-
"github.com/aws/aws-sdk-go/aws"
19-
"github.com/aws/aws-sdk-go/service/sfn"
20-
"github.com/aws/aws-sdk-go/service/sfn/sfniface"
21-
"gopkg.in/Clever/kayvee-go.v6/logger"
19+
"github.com/aws/aws-sdk-go-v2/aws"
20+
"github.com/aws/aws-sdk-go-v2/service/sfn"
2221
)
2322

23+
// SFNAPI defines the interface for Step Functions API operations used by sfncli
24+
type SFNAPI interface {
25+
SendTaskFailure(ctx context.Context, params *sfn.SendTaskFailureInput, optFns ...func(*sfn.Options)) (*sfn.SendTaskFailureOutput, error)
26+
SendTaskSuccess(ctx context.Context, params *sfn.SendTaskSuccessInput, optFns ...func(*sfn.Options)) (*sfn.SendTaskSuccessOutput, error)
27+
SendTaskHeartbeat(ctx context.Context, params *sfn.SendTaskHeartbeatInput, optFns ...func(*sfn.Options)) (*sfn.SendTaskHeartbeatOutput, error)
28+
}
29+
2430
// stay within documented limits of SFN APIs
2531
const (
2632
maxTaskOutputLength = 32768
@@ -29,7 +35,7 @@ const (
2935

3036
// TaskRunner manages resources for executing a task
3137
type TaskRunner struct {
32-
sfnapi sfniface.SFNAPI
38+
sfnapi SFNAPI
3339
taskToken string
3440
cmd string
3541
logger logger.KayveeLogger
@@ -41,7 +47,7 @@ type TaskRunner struct {
4147
}
4248

4349
// NewTaskRunner instantiates a new TaskRunner
44-
func NewTaskRunner(cmd string, sfnapi sfniface.SFNAPI, taskToken string, workDirectory string) TaskRunner {
50+
func NewTaskRunner(cmd string, sfnapi SFNAPI, taskToken string, workDirectory string) TaskRunner {
4551
return TaskRunner{
4652
sfnapi: sfnapi,
4753
taskToken: taskToken,
@@ -153,15 +159,8 @@ func (t *TaskRunner) Process(ctx context.Context, args []string, input string) e
153159
if err != nil {
154160
return t.sendTaskFailure(TaskFailureUnknown{fmt.Errorf("JSON output re-marshalling failed. This should never happen. %s", err)})
155161
}
156-
_, err = t.sfnapi.SendTaskSuccessWithContext(ctx, &sfn.SendTaskSuccessInput{
157-
Output: aws.String(string(finalTaskOutput)),
158-
TaskToken: &t.taskToken,
159-
})
160-
if err != nil {
161-
t.logger.ErrorD("send-task-success-error", logger.M{"error": err.Error()})
162-
}
163162

164-
return err
163+
return t.sendTaskSuccess(ctx, string(finalTaskOutput))
165164
}
166165

167166
func (t *TaskRunner) handleSignals(ctx context.Context) {
@@ -231,3 +230,17 @@ func taskOutputFromStdout(stdout string) string {
231230
}
232231
return taskOutput
233232
}
233+
234+
func (t *TaskRunner) sendTaskSuccess(ctx context.Context, output string) error {
235+
_, err := t.sfnapi.SendTaskSuccess(
236+
ctx,
237+
&sfn.SendTaskSuccessInput{
238+
Output: aws.String(output),
239+
TaskToken: &t.taskToken,
240+
},
241+
)
242+
if err != nil {
243+
t.logger.ErrorD("send-task-success-error", logger.M{"error": err.Error()})
244+
}
245+
return err
246+
}

0 commit comments

Comments
 (0)