Skip to content

Commit

Permalink
Java init template (#229)
Browse files Browse the repository at this point in the history
The template includes a java shim for the toolkit called "app.sh". The shim depends on a file `.classpath.txt` that's generated by maven during build. It points to `target/classes` for classpath. This supports a workflow where you can iterate in the IDE (and run unit tests), but then go to the command line to execute the toolkit, and you will target the same classes the IDE compiled.

BETA: the template includes a pom.xml file that depends on `~/.cdk/repo/maven` as a pragmatic solution for beta. There's value in adding the repository in the pom.xml file directly as this gets us seamless IDE experience that works out of the box.

This change also modifies the pom.xml file for aws-cdk-java to not explicitly include the local jsii repository, which is temporary anyway until we publish to Maven Central. This allows us to include the full pom.xml in the maven package, so transitive dependencies work.
  • Loading branch information
Elad Ben-Israel authored Jul 3, 2018
1 parent 8db8ad9 commit 44b0b2a
Show file tree
Hide file tree
Showing 17 changed files with 567 additions and 35 deletions.
1 change: 1 addition & 0 deletions packages/@aws-cdk/cloudwatch/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ tslint.json
*.d.ts
dist
lib/generated/resources.ts
*.tgz
1 change: 1 addition & 0 deletions packages/@aws-cdk/codepipeline/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ tslint.json
*.d.ts
dist
lib/generated/resources.ts
*.tgz
5 changes: 5 additions & 0 deletions packages/aws-cdk-java/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ set -euo pipefail

mkdir -p project

# deploy jsii-runtime to the local maven repo so it will be discoverable
jsii_runtime_repo=$(node -e "console.log(path.join(path.dirname(require.resolve('jsii-java-runtime/package.json')), 'maven-repo'))")
mkdir -p ~/.m2/repository
rsync -av ${jsii_runtime_repo}/ ~/.m2/repository/

echo "Generating pom.xml..."
node ./pom.xml.t.js > project/pom.xml

Expand Down
4 changes: 1 addition & 3 deletions packages/aws-cdk-java/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@
"url": "https://aws.amazon.com"
},
"license": "Apache-2.0",
"dependencies": {
"aws-cdk-all": "^0.7.2-beta"
},
"devDependencies": {
"aws-cdk-all": "^0.7.2-beta",
"pkgtools": "^0.7.2-beta"
},
"keywords": [
Expand Down
15 changes: 3 additions & 12 deletions packages/aws-cdk-java/pom.xml.t.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
const path = require('path');
const version = require('./package.json').version.replace(/\+.+$/, ''); // omit "+build" postfix

const jsiiRuntime = {
version: require('jsii-java-runtime/package.json').version,
repo: path.join(path.dirname(require.resolve('jsii-java-runtime')), 'maven-repo'),
};
const jsiiRuntimeVersion = require('jsii-java-runtime/package.json').version;

process.stdout.write(`<?xml version="1.0" encoding="UTF-8"?>
<project
Expand All @@ -23,13 +20,6 @@ process.stdout.write(`<?xml version="1.0" encoding="UTF-8"?>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>jsii</id>
<url>file://${jsiiRuntime.repo}</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
Expand Down Expand Up @@ -75,6 +65,7 @@ process.stdout.write(`<?xml version="1.0" encoding="UTF-8"?>
<groupId>\${project.groupId}</groupId>
<artifactId>\${project.artifactId}</artifactId>
<version>\${project.version}</version>
<pomFile>\${project.basedir}/pom.xml</pomFile>
<packaging>jar</packaging>
</configuration>
</execution>
Expand All @@ -88,7 +79,7 @@ process.stdout.write(`<?xml version="1.0" encoding="UTF-8"?>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>jsii-runtime</artifactId>
<version>${jsiiRuntime.version}</version>
<version>${jsiiRuntimeVersion}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
Expand Down
8 changes: 8 additions & 0 deletions packages/aws-cdk/lib/init-templates/app/java/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.classpath.txt
target
.classpath
.project
.idea
.settings
.vscode
*.iml
24 changes: 24 additions & 0 deletions packages/aws-cdk/lib/init-templates/app/java/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

Welcome to your CDK Java project!

It is a Maven-based project, so you can open this directory with any Maven-compatible Java IDE,
and you should be able to build and run tests from your IDE.

You should explore the contents of this template. It demonstrates a CDK app with two instances of
a stack (`HelloStack`) which also uses a user-defined construct (`HelloConstruct`).

The `cdk.json` file tells the CDK Toolkit how to execute your app. It uses a script called `app.sh`
to do that. Note that this script expects a local file called `.classpath.txt` to exist. This file
is automatically created by `mvn package`.

# Useful commands

* `mvn package` compile and run tests
* `cdk ls` list all stacks in the app
* `cdk synth` emits the synthesized CloudFormation template
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk docs` open CDK documentation

Enjoy!

6 changes: 6 additions & 0 deletions packages/aws-cdk/lib/init-templates/app/java/app.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash
# This script is configured in cdk.json to be used to execute
# the CDK java app by the command-line toolkit.
# The file .classpath.txt is created by when `mvn package` is called
# The first argument will be used as argv[0]
exec java -cp target/classes:$(cat .classpath.txt) com.myorg.HelloApp hello-cdk $@
3 changes: 3 additions & 0 deletions packages/aws-cdk/lib/init-templates/app/java/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"app": "./app.sh"
}
69 changes: 69 additions & 0 deletions packages/aws-cdk/lib/init-templates/app/java/pom.template.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<repositories>
<repository>
<id>cdk</id>
<url>file://%cdk-home%/repo/maven</url>
</repository>
</repositories>

<groupId>com.myorg</groupId>
<artifactId>%name%</artifactId>
<version>0.1</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>

<!-- Emit the classpath to ./.classpath.txt so cdk.json can use it -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>build-classpath</id>
<phase>generate-sources</phase>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<outputFile>.classpath.txt</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

<dependencies>
<!-- AWS Cloud Development Kit -->
<dependency>
<groupId>com.amazonaws.cdk</groupId>
<artifactId>aws-cdk</artifactId>
<version>LATEST</version>
</dependency>

<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.myorg;

import com.amazonaws.cdk.App;

import java.util.Arrays;

public class HelloApp {
public static void main(final String argv[]) {
App app = new App(Arrays.asList(argv));

new HelloStack(app, "hello-cdk-1");
new HelloStack(app, "hello-cdk-2");

System.out.println(app.run());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.myorg;

import com.amazonaws.cdk.Construct;
import com.amazonaws.cdk.iam.IIdentityResource;
import com.amazonaws.cdk.s3.Bucket;

import java.util.ArrayList;
import java.util.List;

/**
* Example of a reusable construct. This one defines N buckets.
*/
public class HelloConstruct extends Construct {
private final List<Bucket> buckets = new ArrayList<>();

public HelloConstruct(final Construct parent, final String name, final HelloConstructProps props) {
super(parent, name);

for (int i = 0; i < props.getBucketCount(); ++i) {
buckets.add(new Bucket(this, "Bucket" + String.valueOf(i)));
}
}

/**
* Given an principal, grants it READ access on all buckets.
* @param principal The principal (User, Group, Role)
*/
public void grantRead(final IIdentityResource principal) {
buckets.forEach(b -> b.grantRead(principal));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.myorg;

public class HelloConstructProps {
private int bucketCount;

public static HelloConstructPropsBuilder builder() {
return new HelloConstructPropsBuilder();
}

public int getBucketCount() {
return bucketCount;
}

public void setBucketCount(int bucketCount) {
this.bucketCount = bucketCount;
}


public static final class HelloConstructPropsBuilder {
private int bucketCount;

private HelloConstructPropsBuilder() {
}

public static HelloConstructPropsBuilder aHelloConstructProps() {
return new HelloConstructPropsBuilder();
}

public HelloConstructPropsBuilder withBucketCount(int bucketCount) {
this.bucketCount = bucketCount;
return this;
}

public HelloConstructProps build() {
HelloConstructProps helloConstructProps = new HelloConstructProps();
helloConstructProps.setBucketCount(bucketCount);
return helloConstructProps;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.myorg;

import com.amazonaws.cdk.App;
import com.amazonaws.cdk.Stack;
import com.amazonaws.cdk.StackProps;
import com.amazonaws.cdk.iam.User;
import com.amazonaws.cdk.sns.Topic;
import com.amazonaws.cdk.sns.TopicProps;
import com.amazonaws.cdk.sqs.Queue;
import com.amazonaws.cdk.sqs.QueueProps;

public class HelloStack extends Stack {
public HelloStack(final App parent, final String name) {
this(parent, name, null);
}

public HelloStack(final App parent, final String name, final StackProps props) {
super(parent, name, props);

Queue queue = new Queue(this, "MyFirstQueue", QueueProps.builder()
.withVisibilityTimeoutSec(300)
.build());

Topic topic = new Topic(this, "MyFirstTopic", TopicProps.builder()
.withDisplayName("My First Topic Yeah")
.build());

topic.subscribeQueue(queue);

HelloConstruct hello = new HelloConstruct(this, "Buckets", HelloConstructProps.builder()
.withBucketCount(5)
.build());

User user = new User(this, "MyUser");
hello.grantRead(user);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.myorg;

import com.amazonaws.cdk.App;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.junit.Test;

import java.io.IOException;

import static junit.framework.TestCase.assertEquals;

public class HelloStackTest {
private final static ObjectMapper JSON =
new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true);

@Test
public void testStack() throws IOException {
App app = new App();
HelloStack stack = new HelloStack(app, "test");

// synthesize the stack to a CloudFormation template and compare against
// a checked-in JSON file.
JsonNode actual = JSON.valueToTree(app.synthesizeStack(stack.getName()).getTemplate());
JsonNode expected = JSON.readTree(getClass().getResource("expected.cfn.json"));
assertEquals(expected, actual);
}
}
Loading

0 comments on commit 44b0b2a

Please sign in to comment.