Skip to content

Commit 03d504c

Browse files
authored
Postgres & CloudSQL update for flex (#738)
1. update cloudSql to latest plugin and make the sample a bit cleaner. 2. add postgresql sample.
1 parent ad11bad commit 03d504c

File tree

10 files changed

+406
-63
lines changed

10 files changed

+406
-63
lines changed

flexible/cloudsql/README.md

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,38 @@
11
# Cloud SQL sample for Google App Engine Flexible
2-
This sample demonstrates how to use [Cloud SQL](https://cloud.google.com/sql/) on Google App Engine
3-
Flexible.
2+
3+
This sample demonstrates how to use [Cloud SQL](https://cloud.google.com/cloudsql/) on Google App
4+
Engine Flexible
45

56
## Setup
6-
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)
77

8-
1. Create a new user and database for the application. The easiest way to do this is via the [Google
9-
Developers Console](https://console.cloud.google.com/sql/instances). Alternatively, you can use
10-
MySQL tools such as the command line client or workbench.
11-
2. Change the root password (under Access Control) and / or create a new user / password.
12-
3. Create a Database (under Databases) (or use MySQL with `gcloud sql connect <instance> --user=root`)
13-
4. Note the **Instance connection name** under Overview > Properties
14-
(It will look like 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+
* [Create an instance](https://cloud.google.com/sql/docs/mysql/create-instance)
22+
23+
* [Create a Database](https://cloud.google.com/sql/docs/mysql/create-manage-databases)
24+
25+
* [Create a user](https://cloud.google.com/sql/docs/mysql/create-manage-users)
26+
27+
* Note the **Instance connection name** under Overview > properties
28+
29+
Looks like: `projectID:region:instance`
30+
31+
## Running locally
32+
33+
```bash
34+
$ mvn clean jetty:run -DINSTANCE_CONNECTION_NAME=instanceConnectionName -Duser=root -Dpassword=myPassowrd -Ddatabase=myDatabase
35+
```
1536

1637
## Deploying
1738

@@ -20,10 +41,8 @@ $ mvn clean appengine:deploy -DINSTANCE_CONNECTION_NAME=instanceConnectionName -
2041
-Dpassword=myPassword -Ddatabase=myDatabase
2142
```
2243

23-
Or you can update the properties in `pom.xml`
2444

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

27-
```bash
28-
$ mvn clean jetty:run -DINSTANCE_CONNECTION_NAME=instanceConnectionName -Duser=root -Dpassword=myPassowrd -Ddatabase=myDatabase
29-
```

flexible/cloudsql/pom.xml

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,20 @@
2929

3030
<!-- [START properties] -->
3131
<properties>
32-
<!-- INSTANCE_CONNECTION_NAME from Cloud Console > SQL > Instance Details > Properties
33-
or `gcloud sql instances describe <instance> | grep connectionName`
34-
project:region:instance for Cloud SQL 2nd Generation
32+
<!--
33+
INSTANCE_CONNECTION_NAME from Cloud Console > SQL > Instance Details > Properties
34+
or `gcloud sql instances describe <instance> | grep connectionName`
3535
-->
36-
<INSTANCE_CONNECTION_NAME></INSTANCE_CONNECTION_NAME>
36+
<INSTANCE_CONNECTION_NAME>Project:Region:Instance</INSTANCE_CONNECTION_NAME>
3737
<user>root</user>
38-
<password></password>
38+
<password>myPassword</password>
3939
<database>sqldemo</database>
4040
<!-- [START_EXCLUDE] -->
4141
<maven.compiler.target>1.8</maven.compiler.target>
4242
<maven.compiler.source>1.8</maven.compiler.source>
4343

4444
<failOnMissingWebXml>false</failOnMissingWebXml> <!-- REQUIRED -->
4545

46-
<appengine.maven.plugin>1.3.1</appengine.maven.plugin>
4746
<jetty>9.4.4.v20170414</jetty>
4847
<!-- [END_EXCLUDE] -->
4948
<sqlURL>jdbc:mysql://google/${database}?cloudSqlInstance=${INSTANCE_CONNECTION_NAME}&amp;socketFactory=com.google.cloud.sql.mysql.SocketFactory&amp;user=${user}&amp;password=${password}&amp;useSSL=false</sqlURL>
@@ -82,7 +81,7 @@
8281
<dependency>
8382
<groupId>com.google.cloud.sql</groupId>
8483
<artifactId>mysql-socket-factory-connector-j-6</artifactId>
85-
<version>1.0.2</version>
84+
<version>1.0.3</version>
8685
</dependency>
8786
<!-- [END dependencies] -->
8887
</dependencies>
@@ -97,28 +96,10 @@
9796
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
9897
<plugins>
9998

100-
<!--
101-
<plugin>
102-
<groupId>org.apache.maven.plugins</groupId>
103-
<artifactId>maven-war-plugin</artifactId>
104-
<version>3.0.0</version>
105-
<configuration>
106-
<webResources>
107-
<resource>
108-
<directory>${basedir}/src/main/appengine</directory>
109-
<filtering>true</filtering>
110-
<targetPath></targetPath>
111-
</resource>
112-
</webResources>
113-
</configuration>
114-
</plugin>
115-
-->
116-
117-
11899
<plugin>
119100
<groupId>com.google.cloud.tools</groupId>
120101
<artifactId>appengine-maven-plugin</artifactId>
121-
<version>${appengine.maven.plugin}</version>
102+
<version>1.3.1</version>
122103
</plugin>
123104

124105
<plugin>

flexible/cloudsql/src/main/java/com/example/cloudsql/CloudSqlServlet.java

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.example.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;
@@ -29,6 +31,7 @@
2931
import java.sql.Timestamp;
3032
import java.util.Date;
3133
import java.util.Properties;
34+
import java.util.concurrent.TimeUnit;
3235

3336
import javax.servlet.ServletException;
3437
import javax.servlet.annotation.WebServlet;
@@ -40,62 +43,86 @@
4043
@SuppressWarnings("serial")
4144
@WebServlet(name = "cloudsql", value = "")
4245
public class CloudSqlServlet extends HttpServlet {
43-
String url;
46+
Connection conn;
4447

4548
@Override
4649
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException,
4750
ServletException {
48-
// store only the first two octets of a users ip address
49-
String userIp = req.getRemoteAddr();
50-
InetAddress address = InetAddress.getByName(userIp);
51-
if (address instanceof Inet6Address) {
52-
// nest indexOf calls to find the second occurrence of a character in a
53-
// string
54-
// an alternative is to use Apache Commons Lang:
55-
// StringUtils.ordinalIndexOf()
56-
userIp = userIp.substring(0, userIp.indexOf(":", userIp.indexOf(":") + 1)) + ":*:*:*:*:*:*";
57-
} else if (address instanceof Inet4Address) {
58-
userIp = userIp.substring(0, userIp.indexOf(".", userIp.indexOf(".") + 1)) + ".*.*";
59-
}
60-
6151
final String createTableSql = "CREATE TABLE IF NOT EXISTS visits ( visit_id INT NOT NULL "
6252
+ "AUTO_INCREMENT, user_ip VARCHAR(46) NOT NULL, timestamp DATETIME NOT NULL, "
6353
+ "PRIMARY KEY (visit_id) )";
6454
final String createVisitSql = "INSERT INTO visits (user_ip, timestamp) VALUES (?, ?)";
6555
final String selectSql = "SELECT user_ip, timestamp FROM visits ORDER BY timestamp DESC "
6656
+ "LIMIT 10";
57+
58+
String path = req.getRequestURI();
59+
if (path.startsWith("/favicon.ico")) {
60+
return; // ignore the request for favicon.ico
61+
}
62+
6763
PrintWriter out = resp.getWriter();
6864
resp.setContentType("text/plain");
6965

70-
try (Connection conn = DriverManager.getConnection(url);
71-
PreparedStatement statementCreateVisit = conn.prepareStatement(createVisitSql)) {
66+
// store only the first two octets of a users ip address
67+
String userIp = req.getRemoteAddr();
68+
InetAddress address = InetAddress.getByName(userIp);
69+
if (address instanceof Inet6Address) {
70+
// nest indexOf calls to find the second occurrence of a character in a string
71+
// an alternative is to use Apache Commons Lang: StringUtils.ordinalIndexOf()
72+
userIp = userIp.substring(0, userIp.indexOf(":", userIp.indexOf(":") + 1)) + ":*:*:*:*:*:*";
73+
} else if (address instanceof Inet4Address) {
74+
userIp = userIp.substring(0, userIp.indexOf(".", userIp.indexOf(".") + 1)) + ".*.*";
75+
}
76+
77+
Stopwatch stopwatch = Stopwatch.createStarted();
78+
try (PreparedStatement statementCreateVisit = conn.prepareStatement(createVisitSql)) {
7279
conn.createStatement().executeUpdate(createTableSql);
7380
statementCreateVisit.setString(1, userIp);
7481
statementCreateVisit.setTimestamp(2, new Timestamp(new Date().getTime()));
7582
statementCreateVisit.executeUpdate();
7683

7784
try (ResultSet rs = conn.prepareStatement(selectSql).executeQuery()) {
85+
stopwatch.stop();
7886
out.print("Last 10 visits:\n");
7987
while (rs.next()) {
8088
String savedIp = rs.getString("user_ip");
8189
String timeStamp = rs.getString("timestamp");
8290
out.print("Time: " + timeStamp + " Addr: " + savedIp + "\n");
8391
}
92+
out.println("Elapsed: " + stopwatch.elapsed(TimeUnit.MILLISECONDS));
8493
}
8594
} catch (SQLException e) {
8695
throw new ServletException("SQL error", e);
8796
}
8897
}
8998

9099
@Override
91-
public void init() {
100+
public void init() throws ServletException {
92101
try {
102+
String url;
103+
93104
Properties properties = new Properties();
94-
properties.load(
95-
getServletContext().getResourceAsStream("/WEB-INF/classes/config.properties"));
96-
url = properties.getProperty("sqlUrl");
97-
} catch (IOException e) {
98-
log("no property", e); // Servlet Init should never fail.
105+
try {
106+
properties.load(
107+
getServletContext().getResourceAsStream("/WEB-INF/classes/config.properties"));
108+
url = properties.getProperty("sqlUrl");
109+
} catch (IOException e) {
110+
log("no property", e); // Servlet Init should never fail.
111+
return;
112+
}
113+
114+
log("connecting to: " + url);
115+
try {
116+
Class.forName("com.mysql.jdbc.Driver");
117+
conn = DriverManager.getConnection(url);
118+
} catch (ClassNotFoundException e) {
119+
throw new ServletException("Error loading JDBC Driver", e);
120+
} catch (SQLException e) {
121+
throw new ServletException("Unable to connect to PostGre", e);
122+
}
123+
124+
} finally {
125+
// Nothing really to do here.
99126
}
100127
}
101128
}

flexible/postgres/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/bin/
2+
target

flexible/postgres/README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# PostgreSQL sample for Google App Engine Flexible
2+
3+
This sample demonstrates how to use [Cloud SQL](https://cloud.google.com/sql/) on Google App
4+
Engine Flexible
5+
6+
## Setup
7+
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+
* [Create an instance](https://cloud.google.com/sql/docs/postgresql/create-instance)
22+
23+
* [Create a Database](https://cloud.google.com/sql/docs/postgresql/create-manage-databases)
24+
25+
* [Create a user](https://cloud.google.com/sql/docs/postgresql/create-manage-users)
26+
27+
* Note the **Instance connection name** under Overview > properties
28+
29+
Looks like: `projectID:region:instance`
30+
31+
## Running locally
32+
33+
```bash
34+
$ mvn clean jetty:run -DINSTANCE_CONNECTION_NAME=instanceConnectionName -Duser=root -Dpassword=myPassowrd -Ddatabase=myDatabase
35+
```
36+
37+
## Deploying
38+
39+
```bash
40+
$ mvn clean appengine:deploy -DINSTANCE_CONNECTION_NAME=instanceConnectionName -Duser=root
41+
-Dpassword=myPassword -Ddatabase=myDatabase
42+
```
43+
44+
45+
## Cleaning up
46+
47+
* [Delete your Instance](https://cloud.google.com/sql/docs/postgresql/delete-instance)
48+

0 commit comments

Comments
 (0)