Skip to content

Commit

Permalink
feat: Update StateMachineStage to use definitionBody instead of d…
Browse files Browse the repository at this point in the history
…eprecated `definition` (#372)

* update definition -> definitionBody

* adding tests and updating props in stages
  • Loading branch information
malachi-constant committed Jun 30, 2023
1 parent 72fbb56 commit b0107df
Show file tree
Hide file tree
Showing 15 changed files with 491 additions and 58 deletions.
28 changes: 14 additions & 14 deletions .projen/deps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .projenrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { awscdk, javascript, release, DependencyType } = require("projen");

const CDK_VERSION = "2.80.0";
const CDK_VERSION = "2.85.0";

const project = new awscdk.AwsCdkConstructLibrary({
author: "AWS Professional Services",
Expand Down
248 changes: 248 additions & 0 deletions API.md

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 32 additions & 3 deletions src/pipelines/stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,40 @@ export abstract class DataStage extends Stage {
}
}

function getDefinitionBody(definition?: sfn.IChainable | string, definitionFile?: string): sfn.DefinitionBody {
if (definition && definitionFile) {
throw new Error("Only one of 'definition' or 'definitionFile' should be provided.");
}
if (!definition && !definitionFile) {
throw new Error("One of 'definition' or 'definitionFile' must be provided.");
}

if (definitionFile) {
return sfn.DefinitionBody.fromFile(definitionFile, {});
} else {
if (typeof definition == "string") {
return sfn.DefinitionBody.fromString(definition);
}
if (definition) {
return sfn.DefinitionBody.fromChainable(definition);
}
}
throw new Error("Not able to create a definition body.");
}

/**
* Properties of a state machine stage.
*/
export interface StateMachineStageProps extends StageProps {
/**
* Steps for the state machine.
* Can either be provided as 'sfn.IChainable' or a JSON string.
*/
readonly definition?: sfn.IChainable | string;
/**
* File containing a JSON definition for the state machine.
*/
readonly definitionFile?: string;
/**
* Input of the state machine.
*/
Expand Down Expand Up @@ -223,13 +253,12 @@ export abstract class StateMachineStage extends DataStage {

/**
* Constructs a state machine from the definition.
* @param definition Steps for the state machine.
* @param props State machine stage properties.
* @returns Dictionary with event pattern, targets and state machine construct.
*/
protected createStateMachine(definition: sfn.IChainable, props: StateMachineStageProps): CreateStateMachineResult {
protected createStateMachine(props: StateMachineStageProps): CreateStateMachineResult {
const stateMachine = new sfn.StateMachine(this, "State Machine", {
definition: definition,
definitionBody: getDefinitionBody(props.definition, props.definitionFile),
stateMachineName: props.stateMachineName,
});

Expand Down
2 changes: 1 addition & 1 deletion src/stages/appflow-ingestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export class AppFlowIngestionStage extends StateMachineStage {
eventPattern: this.eventPattern,
targets: this.targets,
stateMachine: this.stateMachine,
} = this.createStateMachine(definition, props));
} = this.createStateMachine({ definition: definition, ...props }));
this.stateMachine.addToRolePolicy(
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
Expand Down
5 changes: 4 additions & 1 deletion src/stages/athena-sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ export class AthenaSQLStage extends StateMachineStage {

const definition = athenaQueryExec.next(new sfn.Succeed(this, "Success"));

({ eventPattern: this.eventPattern, stateMachine: this.stateMachine } = this.createStateMachine(definition, props));
({ eventPattern: this.eventPattern, stateMachine: this.stateMachine } = this.createStateMachine({
definition: definition,
...props,
}));
this.targets = [
new eventsTargets.SfnStateMachine(this.stateMachine, {
input: props.queryString
Expand Down
2 changes: 1 addition & 1 deletion src/stages/databrew-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ export class DataBrewTransformStage extends StateMachineStage {
eventPattern: this.eventPattern,
targets: this.targets,
stateMachine: this.stateMachine,
} = this.createStateMachine(definition, props));
} = this.createStateMachine({ definition: definition, ...props }));
}

private createDefaultDataBrewJobRole(): iam.Role {
Expand Down
2 changes: 1 addition & 1 deletion src/stages/glue-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export class GlueTransformStage extends StateMachineStage {
eventPattern: this.eventPattern,
targets: this.targets,
stateMachine: this.stateMachine,
} = this.createStateMachine(definition, props));
} = this.createStateMachine({ definition: definition, ...props }));
}

private getGlueJob(scope: Construct, id: string, props: GlueTransformStageProps): glue_alpha.IJob {
Expand Down
2 changes: 1 addition & 1 deletion src/stages/mwaa-trigger-dags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export class MWAATriggerDagsStage extends StateMachineStage {
eventPattern: this.eventPattern,
targets: this.targets,
stateMachine: this.stateMachine,
} = this.createStateMachine(definition, props));
} = this.createStateMachine({ definition: definition, ...props }));
}

private buildLambdas(): MWAALambdasResult {
Expand Down
5 changes: 4 additions & 1 deletion src/stages/redshift-data-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ export class RedshiftDataApiStage extends StateMachineStage {
.otherwise(wait),
);

({ eventPattern: this.eventPattern, stateMachine: this.stateMachine } = this.createStateMachine(definition, props));
({ eventPattern: this.eventPattern, stateMachine: this.stateMachine } = this.createStateMachine({
definition: definition,
...props,
}));
this.stateMachine.addToRolePolicy(
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
Expand Down
2 changes: 1 addition & 1 deletion test/base-stack.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ test("Test Permissions Boundary Creation and Usage in BaseStack", () => {
const stackTemplate = Template.fromStack(stack);
stackTemplate.hasResourceProperties("AWS::IAM::Role", {
PermissionsBoundary: {
Ref: "DDKDefaultPermissionsBoundary6721F63A",
"Fn::ImportValue": "my-bootstrap-stack:ExportsOutputRefDDKDefaultPermissionsBoundary6721F63A9C9C311E",
},
});
});
Expand Down
56 changes: 56 additions & 0 deletions test/sfn-stage.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as cdk from "aws-cdk-lib";
import * as events from "aws-cdk-lib/aws-events";
import * as sfn from "aws-cdk-lib/aws-stepfunctions";
import { Construct } from "constructs";

import { StateMachineStage, StateMachineStageProps } from "../src";

class TestSFNStage extends StateMachineStage {
readonly targets?: events.IRuleTarget[];
readonly eventPattern?: events.EventPattern;
readonly stateMachine: sfn.StateMachine;

constructor(scope: Construct, id: string, props: StateMachineStageProps) {
super(scope, id, props);
({
eventPattern: this.eventPattern,
targets: this.targets,
stateMachine: this.stateMachine,
} = this.createStateMachine({
definition: props.definition,
definitionFile: props.definitionFile,
...props,
}));
}
}

test("State Machine Stage Definition File", () => {
const stack = new cdk.Stack();
new TestSFNStage(stack, "MySFN", {
definitionFile: "./test/test-sfn-config.json",
});
});

test("State Machine Stage Definition String", () => {
const stack = new cdk.Stack();
new TestSFNStage(stack, "MySFN", {
definition: '{"StartAt":"Pass","States":{"Pass":{"Type":"Pass","End":true}}}',
});
});

test("SFN No Definition", () => {
const stack = new cdk.Stack();
expect(() => {
new TestSFNStage(stack, "MySFN", {});
}).toThrowError("One of 'definition' or 'definitionFile' must be provided.");
});

test("SFN Redundant Definitions", () => {
const stack = new cdk.Stack();
expect(() => {
new TestSFNStage(stack, "MySFN", {
definition: '{"StartAt":"Pass","States":{"Pass":{"Type":"Pass","End":true}}}',
definitionFile: "./test/test-sfn-config.json",
});
}).toThrowError("Only one of 'definition' or 'definitionFile' should be provided.");
});
Loading

0 comments on commit b0107df

Please sign in to comment.