Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java init template #229

Merged
merged 3 commits into from
Jul 3, 2018
Merged
Show file tree
Hide file tree
Changes from 2 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
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')), 'maven-repo'))")
Copy link
Contributor

Choose a reason for hiding this comment

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

This path will be that of whatever file the main field of package.json points to, which can be considered an implementation detail. I would advise against depending on that. Using the path to require.resolve('jsii-java-runtime/package.json') would be better. And better yet would be making jsii-java-runtime have an actual JS function or property that provides the path to the repository root.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch. Changed to require.resolve('jsii-java-runtime/package.json')

mkdir -p ~/.m2/repository
Copy link
Contributor

Choose a reason for hiding this comment

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

I do not like how you're going to be messing with my ~/.m2 as part of this. There could be things in there that will interfere with the build, and this could cause the build to interfere with some of my things.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As mentioned in the commit message, this is going away very soon once we publish jsii to Maven Central. For now, this seems like a pragmatic option.

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"
Copy link
Contributor

Choose a reason for hiding this comment

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

I doubt this is windows-friendly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😢 you are probably correct. I'll add to #138

}
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 static ObjectMapper JSON = new ObjectMapper()
.configure(SerializationFeature.INDENT_OUTPUT, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't like this way to indent the chain... Would prefer (but no hard feelings):

private static ObjectMapper JSON =
    new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true);

Also, should be private final static

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed


@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