Skip to content
This repository was archived by the owner on Aug 1, 2024. It is now read-only.

fix(java): fixed sample code and created CI job to validate #264

Merged
merged 2 commits into from
Sep 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/build-java-sample-code.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Synth Java sample code

on:
pull_request:
paths:
- code/java/**

jobs:
main-workshop:
name: CDK synth main-workshop sample code
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2

- uses: actions/setup-java@v2
with:
distribution: zulu
java-version: 8

- name: Resolve Maven dependencies
working-directory: code/java/main-workshop
run: mvn dependency:analyze

- name: CDK synth
working-directory: code/java/main-workshop
run: npx cdk synth

pipelines-workshop:
name: CDK synth pipelines-workshop sample code
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2

- uses: actions/setup-java@v2
with:
distribution: zulu
java-version: 8

- name: Resolve Maven dependencies
working-directory: code/java/pipelines-workshop
run: mvn dependency:analyze

- name: CDK synth
working-directory: code/java/pipelines-workshop
run: npx cdk synth
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.js
!**/lambda/*.js
!workshop/static/js/*
*.d.ts
node_modules
Expand Down
8 changes: 8 additions & 0 deletions code/java/main-workshop/lambda/hello.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
exports.handler = async function(event) {
console.log('request:', JSON.stringify(event, undefined, 2));
return {
statusCode: 200,
headers: { 'Content-Type': 'text/plain' },
body: `Hello, CDK! You've hit "${event.path}". That's not very polite, "${event.path}" did not do anything to you...\n`
};
};
28 changes: 28 additions & 0 deletions code/java/main-workshop/lambda/hitcounter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const { DynamoDB, Lambda } = require('aws-sdk');

exports.handler = async function(event) {
console.log("request:", JSON.stringify(event, undefined, 2));

// create AWS SDK clients
const dynamo = new DynamoDB();
const lambda = new Lambda();

// update dynamo entry for "path" with hits++
await dynamo.updateItem({
TableName: process.env.HITS_TABLE_NAME,
Key: { path: { S: event.path } },
UpdateExpression: 'ADD hits :incr',
ExpressionAttributeValues: { ':incr': { N: '1' } }
}).promise();

// call downstream function and capture response
const resp = await lambda.invoke({
FunctionName: process.env.DOWNSTREAM_FUNCTION_NAME,
Payload: JSON.stringify(event)
}).promise();

console.log('downstream response:', JSON.stringify(resp, undefined, 2));

// return response back to upstream caller
return JSON.parse(resp.Payload);
};
10 changes: 5 additions & 5 deletions code/java/main-workshop/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,31 @@
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>core</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>

<!-- Respective AWS Construct Libraries -->
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>apigateway</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>dynamodb</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>lambda</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>

<!-- Additional Construct Libraries -->
<dependency>
<groupId>com.github.eladb</groupId>
<artifactId>cdk-dynamo-table-viewer</artifactId>
<version>[3.1.2,4)</version>
<version>3.0.7</version>
</dependency>

<!-- https://mvnrepository.com/artifact/junit/junit -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import software.amazon.awscdk.core.App;

public final class CdkWorkshopApp {
public static void main(final String[] args) {
public static void main(final String args[]) {
App app = new App();

new CdkWorkshopStack(app, "CdkWorkshopStack");
Expand Down
8 changes: 8 additions & 0 deletions code/java/pipelines-workshop/lambda/hello.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
exports.handler = async function(event) {
console.log('request:', JSON.stringify(event, undefined, 2));
return {
statusCode: 200,
headers: { 'Content-Type': 'text/plain' },
body: `Hello, CDK! You've hit "${event.path}". That's not very polite, "${event.path}" did not do anything to you...\n`
};
};
28 changes: 28 additions & 0 deletions code/java/pipelines-workshop/lambda/hitcounter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const { DynamoDB, Lambda } = require('aws-sdk');

exports.handler = async function(event) {
console.log("request:", JSON.stringify(event, undefined, 2));

// create AWS SDK clients
const dynamo = new DynamoDB();
const lambda = new Lambda();

// update dynamo entry for "path" with hits++
await dynamo.updateItem({
TableName: process.env.HITS_TABLE_NAME,
Key: { path: { S: event.path } },
UpdateExpression: 'ADD hits :incr',
ExpressionAttributeValues: { ':incr': { N: '1' } }
}).promise();

// call downstream function and capture response
const resp = await lambda.invoke({
FunctionName: process.env.DOWNSTREAM_FUNCTION_NAME,
Payload: JSON.stringify(event)
}).promise();

console.log('downstream response:', JSON.stringify(resp, undefined, 2));

// return response back to upstream caller
return JSON.parse(resp.Payload);
};
20 changes: 10 additions & 10 deletions code/java/pipelines-workshop/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,51 +34,51 @@
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>core</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>

<!-- Respective AWS Construct Libraries -->
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>apigateway</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>dynamodb</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>lambda</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>codecommit</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>codepipeline</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>codepipeline-actions</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>
<dependency>
<groupId>software.amazon.awscdk</groupId>
<artifactId>cdk-pipelines</artifactId>
<version>1.71.0</version>
<version>1.117.0</version>
</dependency>

<!-- Additional Construct Libraries -->
<dependency>
<dependency>
<groupId>com.github.eladb</groupId>
<artifactId>cdk-dynamo-table-viewer</artifactId>
<version>[3.1.2,4)</version>
<version>3.0.7</version>
</dependency>

<!-- https://mvnrepository.com/artifact/junit/junit -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public final class CdkWorkshopApp {
public static void main(final String[] args) {
App app = new App();

new WorkshopPipelineStack(app, "WorkshopPipelineStack");
new PipelineStack(app, "PipelineStack");

app.synth();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ public CdkWorkshopStack(final Construct parent, final String id, final StackProp
.build();

hcViewerUrl = CfnOutput.Builder.create(this, "TableViewerUrl")
.value(tv.endpoint)
.value(tv.getEndpoint())
.build();

hcEndpoint = CfnOutput.Builder.create(this, "GatewayUrl")
.value(gateway.url)
.value(gateway.getUrl())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
package com.myorg;

import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;

import software.amazon.awscdk.core.Construct;
import software.amazon.awscdk.core.Stack;
import software.amazon.awscdk.core.StackProps;

import software.amazon.awscdk.services.codecommit.Repository;

import software.amazon.awscdk.services.codepipeline.Artifact;
import software.amazon.awscdk.services.codepipeline.actions.CodeCommitSourceAction;
import software.amazon.awscdk.pipelines.CdkPipeline;
import software.amazon.awscdk.pipelines.SimpleSynthAction;
import software.amazon.awscdk.pipelines.CdkStage;
import software.amazon.awscdk.pipelines.ShellScriptAction;
import software.amazon.awscdk.pipelines.StackOutput;

import software.amazon.awscdk.services.codepipeline.actions.CodeCommitSourceAction;

public class WorkshopPipelineStack extends Stack {
Copy link
Contributor Author

@ryparker ryparker Aug 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java would throw an error if the class did not match the filename. To resolve this I renamed the class to PipelineStack.

public WorkshopPipelineStack(final Construct parent, final String id) {
public class PipelineStack extends Stack {
public PipelineStack(final Construct parent, final String id) {
this(parent, id, null);
}

public WorkshopPipelineStack(final Construct parent, final String id, final StackProps props) {
public PipelineStack(final Construct parent, final String id, final StackProps props) {
super(parent, id, props);

// This creates a new CodeCommit repository called 'WorkshopRepo'
Expand All @@ -29,7 +32,7 @@ public WorkshopPipelineStack(final Construct parent, final String id, final Stac

// Defines the artifact representing the sourcecode
final Artifact sourceArtifact = new Artifact();
// Defines the artifact representing the cloud assembly
// Defines the artifact representing the cloud assembly
// (cloudformation template + all other assets)
final Artifact cloudAssemblyArtifact = new Artifact();

Expand All @@ -38,39 +41,47 @@ public WorkshopPipelineStack(final Construct parent, final String id, final Stac
final CdkPipeline pipeline = CdkPipeline.Builder.create(this, "Pipeline")
.pipelineName("WorkshopPipeline")
.cloudAssemblyArtifact(cloudAssemblyArtifact)

// Generates the source artifact from the repo we created in the last step
.sourceAction(CodeCommitSourceAction.Builder.create()
.actionName("CodeCommit") // Any Git-based source control
.output(sourceArtifact) // Indicates where the artifact is stored
.repository(repo) // Designates the repo to draw code from
.build())

// Builds our source code outlined above into a could assembly artifact
.synthAction(SimpleSynthAction.Builder.create()
.installCommands(List.of("npm install -g aws-cdk")) // Commands to run before build
.installCommands(Arrays.asList("npm install -g aws-cdk")) // Commands to run before build
.synthCommand("npx cdk synth") // Synth command (always same)
.sourceArtifact(sourceArtifact) // Where to get source code to build
.cloudAssemblyArtifact(cloudAssemblyArtifact) // Where to place built source
.buildCommands(List.of("mvn package")) // Language-specific build cmds
.buildCommands(Arrays.asList("mvn package")) // Language-specific build cmds
.build())
.build();

final WorkshopPipelineStage deploy = new WorkshopPipelineStage(this, "Deploy");
final PipelineStage deploy = new PipelineStage(this, "Deploy");
final CdkStage deployStage = pipeline.addApplicationStage(deploy);

final Map<String, StackOutput> TestViewerEndpointOutputs = new HashMap<>();
TestViewerEndpointOutputs.put("ENDPOINT_URL", pipeline.stackOutput(deploy.hcViewerUrl));

deployStage.addActions(ShellScriptAction.Builder.create()
.actionName("TestViewerEndpoint")
.useOutputs(Map.of("ENDPOINT_URL", deploy.hcViewerUrl))
.commands(List.of("curl -Ssf $ENDPOINT_URL"))
Copy link
Contributor Author

@ryparker ryparker Aug 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Map.of and List.of are not supported in Java 8 which is the minimum Java version we support.

To fix this I replaced..

  • Map.of with final Map<String, StackOutput> TestViewerEndpointOutputs = new HashMap
  • List.of with Arrays.asList

There was also an existing type error that was being thrown on the useOutputs() param. To fix this I replaced deploy.hcEndpoint with pipeline.stackOutput(deploy.hcEndpoint) to get the appropriate type object that is expected in useOutputs().

.useOutputs(TestViewerEndpointOutputs)
.commands(Arrays.asList("curl -Ssf $ENDPOINT_URL"))
.build());

final Map<String, StackOutput> TestAPIGatewayEndpointOutputs = new HashMap<>();
TestAPIGatewayEndpointOutputs.put("ENDPOINT_URL", pipeline.stackOutput(deploy.hcEndpoint));

deployStage.addActions(ShellScriptAction.Builder.create()
.actionName("TestAPIGatewayEndpoint")
.useOutputs(Map.of("ENDPOINT_URL", deploy.hcEndpoint))
.commands(List.of(
.useOutputs(TestAPIGatewayEndpointOutputs)
.commands(Arrays.asList(
"curl -Ssf $ENDPOINT_URL",
"curl -Ssf $ENDPOINT_URL/hello",
"curl -Ssf $ENDPOINT_URL/test"
))
.build());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
import software.amazon.awscdk.core.StageProps;
import software.amazon.awscdk.core.CfnOutput;

public class WorkshopPipelineStage extends Stage {
public class PipelineStage extends Stage {

public final CfnOutput hcViewerUrl;
public final CfnOutput hcEndpoint;

public WorkshopPipelineStage(final Construct scope, final String id) {
Copy link
Contributor Author

@ryparker ryparker Aug 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as PipelineStack. The class must match the file name.

public PipelineStage(final Construct scope, final String id) {
this(scope, id, null);
}

public WorkshopPipelineStage(final Construct scope, final String id, final StageProps props) {
public PipelineStage(final Construct scope, final String id, final StageProps props) {
super(scope, id, props);

final CdkWorkshopStack service = new CdkWorkshopStack(this, "WebService");

hcViewerUrl = service.hcViewerUrl;
hcEndpoint = service.hcEndpoint;
}
}
}
Loading