Skip to content

Commit ad11bad

Browse files
authored
1. Updated Cloud SQL to use latest driver. J8 2. PostGreSQL for J8 3. Add a J7 gaeinfo
1 parent 9d1b692 commit ad11bad

File tree

16 files changed

+740
-63
lines changed

16 files changed

+740
-63
lines changed

appengine-java8/cloudsql/README.md

+29-17
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,36 @@
11
# Cloud SQL sample for Google App Engine
2-
This sample demonstrates how to use [Cloud SQL](https://cloud.google.com/sql/) on Google App Engine
2+
3+
This sample demonstrates how to use [Cloud SQL](https://cloud.google.com/cloudsql/) on Google App
4+
Engine standard Java 8
35

46
## Setup
5-
Before you can run or deploy the sample, you will need to create a [Cloud SQL instance)](https://cloud.google.com/sql/docs/create-instance)
67

7-
1. Create a new user and database for the application. The easiest way to do this is via the [Google
8-
Developers Console](https://console.cloud.google.com/sql/instances). Alternatively, you can use MySQL tools such as the command line client or workbench.
9-
2. Change the root password (under Access Control) and / or create a new user / password.
10-
3. Create a Database (under Databases) (or use MySQL with `gcloud beta sql connect <instance> --user=root`)
11-
4. Note the **Instance connection name** under Overview > properties
12-
(It will look like project:instance for 1st Generation or project:region:zone for 2nd Generation)
8+
* If you haven't already, Download and initialize the [Cloud SDK](https://cloud.google.com/sdk/)
9+
10+
`gcloud init`
11+
12+
* If you haven't already, Create an App Engine app within the current Google Cloud Project
13+
14+
`gcloud app create`
15+
16+
* If you haven't already, Setup
17+
[Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials)
18+
19+
`gcloud auth application-default login`
20+
21+
22+
* [Create an instance](https://cloud.google.com/sql/docs/mysql/create-instance)
23+
24+
* [Create a Database](https://cloud.google.com/sql/docs/mysql/create-manage-databases)
1325

14-
or
26+
* [Create a user](https://cloud.google.com/sql/docs/mysql/create-manage-users)
27+
28+
* Note the **Instance connection name** under Overview > properties
29+
30+
## Running locally
1531

1632
```bash
17-
gcloud sql instances describe <instance> | grep connectionName
33+
$ mvn clean appengine:run -DINSTANCE_CONNECTION_NAME=instanceConnectionName -Duser=root -Dpassword=myPassowrd -Ddatabase=myDatabase
1834
```
1935

2036
## Deploying
@@ -24,12 +40,8 @@ $ mvn clean appengine:deploy -DINSTANCE_CONNECTION_NAME=instanceConnectionName -
2440
-Dpassword=myPassword -Ddatabase=myDatabase
2541
```
2642

27-
Or you can update the properties in `pom.xml`
2843

29-
## Running locally
44+
## Cleaning up
45+
46+
* [Delete your Instance](https://cloud.google.com/sql/docs/mysql/delete-instance)
3047

31-
```bash
32-
$ mvn clean appengine:run -DINSTANCE_CONNECTION_NAME=instanceConnectionName -Duser=root -Dpassword=myPassowrd -Ddatabase=myDatabase
33-
```
34-
Note - you must use a local mysql instance for the 1st Generation instance and change the local Url
35-
in `src/main/webapp/WEB-INF/appengine-web.xml` to use your local server.

appengine-java8/cloudsql/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
<dependency>
7878
<groupId>com.google.cloud.sql</groupId>
7979
<artifactId>mysql-socket-factory</artifactId> <!-- mysql-socket-factory-connector-j-6 -->
80-
<version>1.0.2</version>
80+
<version>1.0.3</version>
8181
</dependency>
8282
<!-- [END dependencies] -->
8383
</dependencies>

appengine-java8/cloudsql/src/main/java/com/example/appengine/cloudsql/CloudSqlServlet.java

+38-29
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.example.appengine.cloudsql;
1818

19+
import com.google.common.base.Stopwatch;
20+
1921
import java.io.IOException;
2022
import java.io.PrintWriter;
2123
import java.net.Inet4Address;
@@ -28,6 +30,7 @@
2830
import java.sql.SQLException;
2931
import java.sql.Timestamp;
3032
import java.util.Date;
33+
import java.util.concurrent.TimeUnit;
3134

3235
import javax.servlet.ServletException;
3336
import javax.servlet.annotation.WebServlet;
@@ -41,14 +44,26 @@
4144
@WebServlet(name = "CloudSQL", description = "CloudSQL: Write low order IP address to Cloud SQL",
4245
urlPatterns = "/cloudsql")
4346
public class CloudSqlServlet extends HttpServlet {
47+
Connection conn;
4448

4549
@Override
4650
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException,
4751
ServletException {
52+
final String createTableSql = "CREATE TABLE IF NOT EXISTS visits ( visit_id INT NOT NULL "
53+
+ "AUTO_INCREMENT, user_ip VARCHAR(46) NOT NULL, timestamp DATETIME NOT NULL, "
54+
+ "PRIMARY KEY (visit_id) )";
55+
final String createVisitSql = "INSERT INTO visits (user_ip, timestamp) VALUES (?, ?)";
56+
final String selectSql = "SELECT user_ip, timestamp FROM visits ORDER BY timestamp DESC "
57+
+ "LIMIT 10";
58+
4859
String path = req.getRequestURI();
4960
if (path.startsWith("/favicon.ico")) {
5061
return; // ignore the request for favicon.ico
5162
}
63+
64+
PrintWriter out = resp.getWriter();
65+
resp.setContentType("text/plain");
66+
5267
// store only the first two octets of a users ip address
5368
String userIp = req.getRemoteAddr();
5469
InetAddress address = InetAddress.getByName(userIp);
@@ -60,51 +75,45 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOExc
6075
userIp = userIp.substring(0, userIp.indexOf(".", userIp.indexOf(".") + 1)) + ".*.*";
6176
}
6277

63-
final String createTableSql = "CREATE TABLE IF NOT EXISTS visits ( visit_id INT NOT NULL "
64-
+ "AUTO_INCREMENT, user_ip VARCHAR(46) NOT NULL, timestamp DATETIME NOT NULL, "
65-
+ "PRIMARY KEY (visit_id) )";
66-
final String createVisitSql = "INSERT INTO visits (user_ip, timestamp) VALUES (?, ?)";
67-
final String selectSql = "SELECT user_ip, timestamp FROM visits ORDER BY timestamp DESC "
68-
+ "LIMIT 10";
69-
70-
PrintWriter out = resp.getWriter();
71-
resp.setContentType("text/plain");
72-
String url;
73-
if (System
74-
.getProperty("com.google.appengine.runtime.version").startsWith("Google App Engine/")) {
75-
// Check the System properties to determine if we are running on appengine or not
76-
// Google App Engine sets a few system properties that will reliably be present on a remote
77-
// instance.
78-
url = System.getProperty("ae-cloudsql.cloudsql-database-url");
79-
try {
80-
// Load the class that provides the new "jdbc:google:mysql://" prefix.
81-
Class.forName("com.mysql.jdbc.GoogleDriver");
82-
} catch (ClassNotFoundException e) {
83-
throw new ServletException("Error loading Google JDBC Driver", e);
84-
}
85-
} else {
86-
// Set the url with the local MySQL database connection url when running locally
87-
url = System.getProperty("ae-cloudsql.local-database-url");
88-
}
89-
log("connecting to: " + url);
90-
try (Connection conn = DriverManager.getConnection(url);
91-
PreparedStatement statementCreateVisit = conn.prepareStatement(createVisitSql)) {
78+
Stopwatch stopwatch = Stopwatch.createStarted();
79+
try (PreparedStatement statementCreateVisit = conn.prepareStatement(createVisitSql)) {
9280
conn.createStatement().executeUpdate(createTableSql);
9381
statementCreateVisit.setString(1, userIp);
9482
statementCreateVisit.setTimestamp(2, new Timestamp(new Date().getTime()));
9583
statementCreateVisit.executeUpdate();
9684

9785
try (ResultSet rs = conn.prepareStatement(selectSql).executeQuery()) {
86+
stopwatch.stop();
9887
out.print("Last 10 visits:\n");
9988
while (rs.next()) {
10089
String savedIp = rs.getString("user_ip");
10190
String timeStamp = rs.getString("timestamp");
10291
out.print("Time: " + timeStamp + " Addr: " + savedIp + "\n");
10392
}
93+
out.println("Elapsed: " + stopwatch.elapsed(TimeUnit.MILLISECONDS));
10494
}
10595
} catch (SQLException e) {
10696
throw new ServletException("SQL error", e);
10797
}
10898
}
99+
100+
@Override
101+
public void init() throws ServletException {
102+
try {
103+
String url = System.getProperty("cloudsql");
104+
log("connecting to: " + url);
105+
try {
106+
Class.forName("com.mysql.jdbc.Driver");
107+
conn = DriverManager.getConnection(url);
108+
} catch (ClassNotFoundException e) {
109+
throw new ServletException("Error loading JDBC Driver", e);
110+
} catch (SQLException e) {
111+
throw new ServletException("Unable to connect to PostGre", e);
112+
}
113+
114+
} finally {
115+
// Nothing really to do here.
116+
}
117+
}
109118
}
110119
// [END example]

appengine-java8/cloudsql/src/main/webapp/WEB-INF/appengine-web.xml

+1-3
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@
1616
<threadsafe>true</threadsafe>
1717
<runtime>java8</runtime>
1818

19-
<!-- <use-google-connector-j>true</use-google-connector-j> NO LONGER REQUIRED -->
2019
<system-properties>
21-
<property name="ae-cloudsql.cloudsql-database-url" value="jdbc:mysql://google/${database}?useSSL=false&amp;cloudSqlInstance=${INSTANCE_CONNECTION_NAME}&amp;socketFactory=com.google.cloud.sql.mysql.SocketFactory&amp;user=${user}&amp;password=${password}" />
22-
<property name="ae-cloudsql.local-database-url" value="jdbc:mysql://google/${database}?useSSL=false&amp;cloudSqlInstance=${INSTANCE_CONNECTION_NAME}&amp;socketFactory=com.google.cloud.sql.mysql.SocketFactory&amp;user=${user}&amp;password=${password}" />
20+
<property name="cloudsql" value="jdbc:mysql://google/${database}?useSSL=false&amp;cloudSqlInstance=${INSTANCE_CONNECTION_NAME}&amp;socketFactory=com.google.cloud.sql.mysql.SocketFactory&amp;user=${user}&amp;password=${password}" />
2321
</system-properties>
2422
</appengine-web-app>
2523
<!-- [END config] -->

appengine-java8/gaeinfo/README.md

-13
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,6 @@ Use either:
2323

2424
$ mvn appengine:deploy
2525

26-
## Gradle
27-
### Running locally
28-
29-
$ gradle appengineRun
30-
31-
If you do not have gradle installed, you can run using `./gradlew appengineRun`.
32-
33-
### Deploying
34-
35-
$ gradle appengineDeploy
36-
37-
If you do not have gradle installed, you can deploy using `./gradlew appengineDeploy`.
38-
3926
<!--
4027
## Intelij Idea
4128
Limitations - Appengine Standard support in the Intellij plugin is only available for the Ultimate Edition of Idea.

appengine-java8/pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
<module>memcache</module>
6464
<module>multitenancy</module>
6565
<module>oauth2</module>
66+
<module>postgres</module>
6667
<module>requests</module>
6768

6869
<module>remote-client</module>

appengine-java8/postgres/README.md

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Postgre SQL sample for Google App Engine J8
2+
This sample demonstrates how to use [Cloud SQL](https://cloud.google.com/cloudsql/) on Google App
3+
Engine standard Java 8
4+
5+
## Setup
6+
7+
* If you haven't already, Download and initialize the [Cloud SDK](https://cloud.google.com/sdk/)
8+
9+
`gcloud init`
10+
11+
* If you haven't already, Create an App Engine app within the current Google Cloud Project
12+
13+
`gcloud app create`
14+
15+
* If you haven't already, Setup [Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials)
16+
17+
`gcloud auth application-default login`
18+
19+
20+
* [Create an instance](https://cloud.google.com/sql/docs/postgres/create-instance)
21+
22+
* [Create a Database](https://cloud.google.com/sql/docs/postgres/create-manage-databases)
23+
24+
* [Create a user](https://cloud.google.com/sql/docs/postgres/create-manage-users)
25+
26+
* Note the **Instance connection name** under Overview > properties
27+
28+
## Running locally
29+
30+
```bash
31+
$ mvn clean appengine:run -DINSTANCE_CONNECTION_NAME=instanceConnectionName -Duser=root -Dpassword=myPassowrd -Ddatabase=myDatabase
32+
```
33+
34+
## Deploying
35+
36+
```bash
37+
$ mvn clean appengine:deploy -DINSTANCE_CONNECTION_NAME=instanceConnectionName -Duser=root
38+
-Dpassword=myPassword -Ddatabase=myDatabase
39+
```
40+
41+
42+
## Cleaning up
43+
44+
* [Delete your Instance](https://cloud.google.com/sql/docs/postgres/delete-instance)
45+

appengine-java8/postgres/pom.xml

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<!--
2+
Copyright 2017 Google Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may 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 implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
<project>
17+
<modelVersion>4.0.0</modelVersion>
18+
<packaging>war</packaging>
19+
<version>1.0-SNAPSHOT</version>
20+
<groupId>com.example.appengine</groupId>
21+
<artifactId>appengine-postgreSQL-j8</artifactId>
22+
23+
<parent>
24+
<artifactId>appengine-java8-samples</artifactId>
25+
<groupId>com.google.cloud</groupId>
26+
<version>1.0.0</version>
27+
<relativePath>..</relativePath>
28+
</parent>
29+
30+
<!-- [START properties] -->
31+
<properties>
32+
<!-- INSTANCE_CONNECTION_NAME from Cloud Console > SQL > Instance Details > Properties
33+
or gcloud sql instances describe <instance>
34+
-->
35+
<INSTANCE_CONNECTION_NAME>Project:Region:Instance</INSTANCE_CONNECTION_NAME>
36+
<user>root</user>
37+
<password>myPassword</password>
38+
<database>sqldemo</database>
39+
40+
<!-- [START_EXCLUDE] -->
41+
<maven.compiler.target>1.8</maven.compiler.target>
42+
<maven.compiler.source>1.8</maven.compiler.source>
43+
<!-- [END_EXCLUDE] -->
44+
</properties>
45+
<!-- [END properties] -->
46+
47+
<dependencies>
48+
<!-- Parent POM defines ${appengine.sdk.version} (updates frequently). -->
49+
<dependency>
50+
<groupId>com.google.appengine</groupId>
51+
<artifactId>appengine-api-1.0-sdk</artifactId>
52+
<version>1.9.54</version>
53+
</dependency>
54+
55+
<dependency>
56+
<groupId>javax.servlet</groupId>
57+
<artifactId>javax.servlet-api</artifactId>
58+
<version>3.1.0</version>
59+
<type>jar</type>
60+
<scope>provided</scope>
61+
</dependency>
62+
63+
<dependency>
64+
<groupId>com.google.api-client</groupId>
65+
<artifactId>google-api-client-appengine</artifactId>
66+
<version>1.22.0</version>
67+
</dependency>
68+
69+
<!-- [START dependencies] -->
70+
<dependency>
71+
<groupId>org.postgresql</groupId>
72+
<artifactId>postgresql</artifactId>
73+
<version>42.1.1</version>
74+
</dependency>
75+
76+
<dependency>
77+
<groupId>com.google.cloud.sql</groupId>
78+
<artifactId>postgres-socket-factory</artifactId>
79+
<version>1.0.3</version>
80+
</dependency>
81+
<!-- [END dependencies] -->
82+
</dependencies>
83+
84+
<build>
85+
<!-- for hot reload of the web application -->
86+
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
87+
<plugins>
88+
<plugin>
89+
<groupId>org.apache.maven.plugins</groupId>
90+
<artifactId>maven-war-plugin</artifactId>
91+
<version>3.0.0</version>
92+
<configuration>
93+
<webResources>
94+
<!-- in order to interpolate version from pom into appengine-web.xml -->
95+
<resource>
96+
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
97+
<filtering>true</filtering>
98+
<targetPath>WEB-INF</targetPath>
99+
</resource>
100+
</webResources>
101+
</configuration>
102+
</plugin>
103+
104+
<plugin>
105+
<groupId>com.google.cloud.tools</groupId>
106+
<artifactId>appengine-maven-plugin</artifactId>
107+
<version>1.3.1</version>
108+
<configuration>
109+
<deploy.promote>true</deploy.promote>
110+
<deploy.stopPreviousVersion>true</deploy.stopPreviousVersion>
111+
</configuration>
112+
</plugin>
113+
114+
</plugins>
115+
</build>
116+
</project>

0 commit comments

Comments
 (0)