Skip to content

Commit 2c94683

Browse files
author
Ajay Kannan
committed
Initial import of MVM/SparkJava/gcloud-java example
1 parent 92907e5 commit 2c94683

File tree

13 files changed

+881
-0
lines changed

13 files changed

+881
-0
lines changed

managedvms/sparkjava/README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
gcloud-java example using Managed VMs & SparkJava
2+
=================================================
3+
4+
This app demonstrates how to use [`gcloud-java`'s Datastore client](https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-datastore#google-cloud-java-client-for-datastore) from within an [App Engine Managed VM](https://cloud.google.com/appengine/docs/java/managed-vms/) project using [SparkJava](http://sparkjava.com/). The app allows you to create and modify a database of "users", which contains their ID, name, and email information.
5+
6+
`gcloud-java` is an idiomatic Java client for [Google Cloud Platform](https://cloud.google.com/) services. Read more about the library [here](https://github.com/GoogleCloudPlatform/gcloud-java#google-cloud-java-client).
7+
8+
Setup
9+
-----
10+
11+
1. Create a Google Developers Console project with the Datastore API enabled. [Follow these instructions](https://cloud.google.com/docs/authentication#preparation) to get your project set up. If you wish to deploy this application, you will also need to [enable billing](https://support.google.com/cloud/?rd=2#topic=6288636).
12+
13+
2. Set up the local development environment by [installing the Google Cloud SDK](https://cloud.google.com/sdk/) and running the following commands in command line: `gcloud auth login` and `gcloud config set project [YOUR PROJECT ID]`.
14+
15+
3. Ensure that you have Maven installed. See installation instructions [here](https://maven.apache.org/install.html).
16+
17+
Running locally
18+
---------------
19+
20+
Run the application on your local machine by typing the following into your command line from the `sparkjava` directory: `mvn clean package exec:java`. Navigate to `localhost:8080` to view and interact with the application.
21+
22+
Deploying
23+
---------
24+
25+
If you've enabled billing (step 1 in [Setup](#Setup)), you can deploy the application to the web by running `mvn gcloud:deploy` from your command line (from the `sparkjava` directory).
26+
27+
How does it work?
28+
-----------------
29+
30+
You'll notice that the source code is split into three folders: `appengine`, `java/com/google/appengine/sparkdemo`, and `resource/public`. The `appengine` folder contains a `Dockerfile` and an `app.yaml`, necessary files to [configure the VM environment](https://cloud.google.com/appengine/docs/managed-vms/config). The `java/com/google/appengine/sparkdemo` folder contains the controller code, which uses the `gcloud-java` library to modify the records in the Google Cloud Datastore. Finally, the `resource/public` folder contains the home webpage, which uses jQuery to send HTTP requests to create, remove, and update records.
31+
32+
Spark runs the [`main` method](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managedvms/sparkjava-demo/src/main/java/com/google/appengine/sparkdemo/Main.java) upon server startup. The `main` method creates the controller, [`UserController`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managedvms/sparkjava-demo/src/main/java/com/google/appengine/sparkdemo/UserController.java). The URIs used to send HTTP requests in the [home page](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managedvms/sparkjava-demo/src/main/resources/public/index.html) correspond to methods in the `UserController` class. For example, the `index.html` code for `create` makes a `POST` request to the path `/api/users` with a body containing the name and email of a user to add. `UserController` contains the following code to process that request:
33+
34+
```java
35+
post("/api/users", (req, res) -> userService.createUser(
36+
req.queryParams("name"),
37+
req.queryParams("email),
38+
), json());
39+
```
40+
This code snippet gets the name and email of the user from the POST request and passes it to `createUser` (in [`UserService.java`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managedvms/sparkjava-demo/src/main/java/com/google/appengine/sparkdemo/UserService.java)) to create a database record using `gcloud-java`. If you want a more in-depth tutorial on using `gcloud-java` Datastore client, see the [Getting Started](https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-datastore#getting-started) section in the `gcloud-java-datastore` documentation.
41+
42+
Communication with the Google Cloud Datastore requires authentication and setting a project ID. When running locally, `gcloud-java` automatically detects your credentials and project ID because you logged into the Google Cloud SDK and set your project ID. There are also many other options for authenticating and setting a project ID. To read more, see the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication) and [Specifying a Project ID](https://github.com/GoogleCloudPlatform/gcloud-java#specifying-a-project-id) sections of the `gcloud-java` documentation.
43+
44+
You built and ran this application using Maven. To read more about using Maven with Managed VMs, see the [Using Apache Maven documentation](https://cloud.google.com/appengine/docs/java/managed-vms/maven). While this particular project uses Maven, `gcloud-java` can also be accessed using Gradle and SBT. See how to obtain the dependency in the [Quickstart section](https://github.com/GoogleCloudPlatform/gcloud-java#quickstart) of the `gcloud-java` documentation.
45+
46+
License
47+
-------
48+
49+
Apache 2.0 - See [LICENSE](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/LICENSE) for more information.

managedvms/sparkjava/pom.xml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<groupId>com.google.appengine.sparkdemo</groupId>
7+
<artifactId>sparkdemo</artifactId>
8+
<version>1.0</version>
9+
<dependencies>
10+
<dependency>
11+
<groupId>com.sparkjava</groupId>
12+
<artifactId>spark-core</artifactId>
13+
<version>2.3</version>
14+
</dependency>
15+
<dependency>
16+
<groupId>org.slf4j</groupId>
17+
<artifactId>slf4j-simple</artifactId>
18+
<version>1.7.12</version>
19+
</dependency>
20+
<dependency>
21+
<groupId>com.google.code.gson</groupId>
22+
<artifactId>gson</artifactId>
23+
<version>2.4</version>
24+
</dependency>
25+
<dependency>
26+
<groupId>junit</groupId>
27+
<artifactId>junit</artifactId>
28+
<version>4.12</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>com.google.gcloud</groupId>
32+
<artifactId>gcloud-java</artifactId>
33+
<version>0.1.1</version>
34+
</dependency>
35+
</dependencies>
36+
<build>
37+
<plugins>
38+
<plugin>
39+
<groupId>org.apache.maven.plugins</groupId>
40+
<artifactId>maven-compiler-plugin</artifactId>
41+
<version>2.5.1</version>
42+
<configuration>
43+
<source>1.8</source>
44+
<target>1.8</target>
45+
</configuration>
46+
</plugin>
47+
<plugin>
48+
<artifactId>maven-assembly-plugin</artifactId>
49+
<executions>
50+
<execution>
51+
<phase>package</phase>
52+
<goals>
53+
<goal>single</goal>
54+
</goals>
55+
</execution>
56+
</executions>
57+
<configuration>
58+
<descriptorRefs>
59+
<descriptorRef>jar-with-dependencies</descriptorRef>
60+
</descriptorRefs>
61+
<archive>
62+
<manifest>
63+
<mainClass>com.google.appengine.sparkdemo.Main</mainClass>
64+
</manifest>
65+
</archive>
66+
</configuration>
67+
</plugin>
68+
<plugin>
69+
<groupId>org.codehaus.mojo</groupId>
70+
<artifactId>exec-maven-plugin</artifactId>
71+
<version>1.4.0</version>
72+
<configuration>
73+
<mainClass>com.google.appengine.sparkdemo.Main</mainClass>
74+
<arguments>
75+
<argument>-jar</argument>
76+
<argument>target/sparkdemo-1.0-jar-with-dependencies.jar</argument>
77+
</arguments>
78+
</configuration>
79+
</plugin>
80+
<plugin>
81+
<groupId>com.google.appengine</groupId>
82+
<artifactId>gcloud-maven-plugin</artifactId>
83+
<version>2.0.9.88.v20151125</version>
84+
<configuration>
85+
</configuration>
86+
</plugin>
87+
</plugins>
88+
</build>
89+
</project>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM gcr.io/google_appengine/openjdk8
2+
VOLUME /tmp
3+
ADD sparkdemo-1.0-jar-with-dependencies.jar app.jar
4+
ENTRYPOINT [ "java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
runtime: custom
2+
vm: true
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2015 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you
5+
* may not use this file except in compliance with the License. You may
6+
* obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13+
* implied. See the License for the specific language governing
14+
* permissions and limitations under the License.
15+
*/
16+
17+
package com.google.appengine.sparkdemo;
18+
19+
import static spark.Spark.port;
20+
21+
import com.google.gcloud.datastore.DatastoreOptions;
22+
23+
public class Main {
24+
25+
public static void main(String[] args) {
26+
port(8080);
27+
UserController userController =
28+
new UserController(new UserService(DatastoreOptions.defaultInstance().service()));
29+
}
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2015 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you
5+
* may not use this file except in compliance with the License. You may
6+
* obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13+
* implied. See the License for the specific language governing
14+
* permissions and limitations under the License.
15+
*/
16+
17+
package com.google.appengine.sparkdemo;
18+
19+
public class ResponseError {
20+
21+
private String message;
22+
23+
public ResponseError(String message, String... args) {
24+
this.message = String.format(message, (Object) args);
25+
}
26+
27+
public ResponseError(Exception e) {
28+
this.message = e.getMessage();
29+
}
30+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2015 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you
5+
* may not use this file except in compliance with the License. You may
6+
* obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13+
* implied. See the License for the specific language governing
14+
* permissions and limitations under the License.
15+
*/
16+
17+
package com.google.appengine.sparkdemo;
18+
19+
import java.util.UUID;
20+
21+
public class User {
22+
23+
private String id;
24+
private String name;
25+
private String email;
26+
27+
public User(String name, String email) {
28+
this(UUID.randomUUID().toString(), name, email);
29+
}
30+
31+
public User(String id, String name, String email) {
32+
this.id = id;
33+
this.email = email;
34+
this.name = name;
35+
}
36+
37+
public String getId() {
38+
return id;
39+
}
40+
41+
public String getName() {
42+
return name;
43+
}
44+
45+
public String getEmail() {
46+
return email;
47+
}
48+
49+
void setId(String id) {
50+
this.id = id;
51+
}
52+
53+
public void setName(String name) {
54+
this.name = name;
55+
}
56+
57+
public void setEmail(String email) {
58+
this.email = email;
59+
}
60+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2015 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you
5+
* may not use this file except in compliance with the License. You may
6+
* obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13+
* implied. See the License for the specific language governing
14+
* permissions and limitations under the License.
15+
*/
16+
17+
package com.google.appengine.sparkdemo;
18+
19+
import static spark.Spark.after;
20+
import static spark.Spark.delete;
21+
import static spark.Spark.exception;
22+
import static spark.Spark.get;
23+
import static spark.Spark.post;
24+
import static spark.Spark.put;
25+
26+
import com.google.gson.Gson;
27+
28+
import spark.ResponseTransformer;
29+
import spark.Spark;
30+
31+
public class UserController {
32+
33+
public UserController(final UserService userService) {
34+
Spark.staticFileLocation("/public");
35+
36+
get("/api/users", (req, res) -> userService.getAllUsers(), UserController::toJson);
37+
38+
post("/api/users",
39+
(req, res) -> userService.createUser(req.queryParams("name"), req.queryParams("email")),
40+
json());
41+
42+
put("/api/users/:id", (req, res) -> userService.updateUser(
43+
req.params(":id"),
44+
req.queryParams("name"),
45+
req.queryParams("email")
46+
), json());
47+
48+
delete("/api/users/:id", (req, res) -> userService.deleteUser(req.params(":id")), json());
49+
50+
after((req, res) -> {
51+
res.type("application/json");
52+
});
53+
54+
exception(IllegalArgumentException.class, (e, req, res) -> {
55+
res.status(400);
56+
res.body(toJson(new ResponseError(e)));
57+
});
58+
}
59+
60+
private static String toJson(Object object) {
61+
return new Gson().toJson(object);
62+
}
63+
64+
private static ResponseTransformer json() {
65+
return UserController::toJson;
66+
}
67+
}

0 commit comments

Comments
 (0)