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

GAE Std J8 getting started Samples - CloudSQL #911

Closed
wants to merge 2 commits into from
Closed
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
72 changes: 72 additions & 0 deletions appengine-j8-start/cloudsql/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Google App Engine Standard Environment Cloud SQL Sample

This sample demonstrates how to deploy an App Engine Java 8 application that
uses Cloud SQL for storage.

See the [Google App Engine standard environment documentation][ae-docs] for more
detailed instructions.

[ae-docs]: https://cloud.google.com/appengine/docs/java/

## Setup

* If you haven't already, Download and initialize the [Cloud
SDK](https://cloud.google.com/sdk/)

`gcloud init`

* If you haven't already, Create an App Engine app within the current Google
Cloud Project

`gcloud app create`

* If you haven't already, Setup [Application Default
Credentials](https://developers.google.com/identity/protocols/application-default-credentials)

`gcloud auth application-default login`

* [Create an
instance](https://cloud.google.com/sql/docs/mysql/create-instance)

* [Create a
Database](https://cloud.google.com/sql/docs/mysql/create-manage-databases)

* [Create a user](https://cloud.google.com/sql/docs/mysql/create-manage-users)

* Note the **Instance connection name** under Overview > properties

* Update the `<application>` tag in the `pom.xml` with your project name.

* Update the `<version>` tag in the `pom.xml` with your version name.

## Testing

This examples uses a local MySQL server to run tests.

1. Download and install [MySQL Community
Server](https://dev.mysql.com/downloads/mysql/).

1. Create the database and user for the tests.

1. Append the database name, username and password in the `serverUrl`
connection variable in the test files located in
`src/test/java/com/example/appengine`.

## Running locally

This example uses the [Cloud SDK Maven
plugin](https://cloud.google.com/appengine/docs/java/tools/using-maven). To run
this sample locally:

$ mvn appengine:run

To see the results of the sample application, open
[localhost:8080](http://localhost:8080) in a web browser.

## Deploying

In the following command, replace YOUR-PROJECT-ID with your [Google Cloud
Project ID](https://developers.google.com/console/help/new/#projectnumber) and
SOME-VERSION with a valid version number.

$ mvn appengine:deploy
128 changes: 128 additions & 0 deletions appengine-j8-start/cloudsql/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<!--
Copyright 2017 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<version>1.0</version>
<groupId>com.example.appengine</groupId>
<artifactId>cloudsql</artifactId>

<properties>
<appengine.app.appId>stuff-155523</appengine.app.appId>
<appengine.app.version>1</appengine.app.version>
<appengine.sdk.version>1.9.57</appengine.sdk.version>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>

<INSTANCE_CONNECTION_NAME>PROJECT INSTANCE NAME</INSTANCE_CONNECTION_NAME>
<user>DATABASE USERNAME</user>
<password>DATABASE PASSWORD</password>
<database>DATABASE NAME</database>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>

<dependencies>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<type>jar</type>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>

<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>${appengine.sdk.version}</version>
</dependency>

<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.10.3</version>
</dependency>

<!-- Testing dependencies -->

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>

<dependency>
<groupId>com.google.truth</groupId>
<artifactId>truth</artifactId>
<version>0.36</version>
</dependency>

<dependency> <!-- Only used locally -->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version>
</dependency>

<dependency>
<groupId>com.google.cloud.sql</groupId>
<artifactId>mysql-socket-factory</artifactId>
<version>1.0.4</version>
</dependency>

</dependencies>

<build>

<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<version>3.5.1</version>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>

<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.3.1</version>
<configuration>
<appId>${appengine.app.appId}</appId>
<version>${appengine.app.version}</version>
<cloudSdkPath>PATH TO CLOUD SDK DIRECTORY</cloudSdkPath>
</configuration>
</plugin>
</plugins>

</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* Copyright 2017 Google Inc.
*
* <p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.appengine.cloudsql;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;

@SuppressWarnings("serial")
@WebServlet(name = "create", description = "Write post content to SQL DB", urlPatterns = "/create")
public class CreateRecord extends HttpServlet {
// Creates a record from data sent in a HTML form and stores it in Cloud SQL

Connection conn;

// Table creation queries
final String createContentTableSql =
"CREATE TABLE IF NOT EXISTS posts ( post_id INT NOT NULL "
+ "AUTO_INCREMENT, author_id INT NOT NULL, timestamp DATETIME NOT NULL, "
+ "title VARCHAR(256) NOT NULL, "
+ "body VARCHAR(1337) NOT NULL, PRIMARY KEY (post_id) )";

final String createUserTableSql =
"CREATE TABLE IF NOT EXISTS users ( user_id INT NOT NULL "
+ "AUTO_INCREMENT, user_fullname VARCHAR(64) NOT NULL, "
+ "PRIMARY KEY (user_id) )";

// Post creation query
final String createPostSql =
"INSERT INTO posts (author_id, timestamp, title, body) VALUES (?, ?, ?, ?)";

@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

// Take the values submitted in an HTML form, clean them through jSoup, store
// them in a Cloud SQL database and then send the user to a JSP that has a
// personalised confirmation message.

// Create a map of the httpParameters that we want and run it through jSoup
Map<String, String> blogContent =
req.getParameterMap()
.entrySet()
.stream()
.filter(a -> a.getKey().startsWith("blogContent_"))
.collect(
Collectors.toMap(
p -> p.getKey(), p -> Jsoup.clean(p.getValue()[0], Whitelist.basic())));

// Build the SQL command to insert the blog post into the database
try (PreparedStatement statementCreatePost = conn.prepareStatement(createPostSql)) {
statementCreatePost.setInt(
1,
Integer.parseInt(
blogContent.get(
"blogContent_id"))); // set the author to the user ID from the user table
statementCreatePost.setTimestamp(2, new Timestamp(new Date().getTime()));
statementCreatePost.setString(3, blogContent.get("blogContent_title"));
statementCreatePost.setString(4, blogContent.get("blogContent_description"));
statementCreatePost.executeUpdate();

conn.close(); // close the connection to the MySQL server

// Send the user to the confirmation page with personalised confirmation text
String confirmation = "Post with title " + blogContent.get("blogContent_title") + " created.";

req.setAttribute("confirmation", confirmation);
req.getRequestDispatcher("/confirm.jsp").forward(req, resp);

} catch (SQLException e) {
throw new ServletException("SQL error when creating post", e);
}
}

@Override
public void init() throws ServletException {
try {
String url = System.getProperty("cloudsql");

try {
conn = DriverManager.getConnection(url); // Connect to the database

// Create the tables for first use
conn.createStatement().executeUpdate(createContentTableSql); // Create content table
conn.createStatement().executeUpdate(createUserTableSql); // Create user table
} catch (SQLException e) {
throw new ServletException("Unable to connect to Cloud SQL", e);
}

} finally {
// Nothing really to do here.
}
}
}
Loading