Skip to content

Commit 4546b67

Browse files
author
Shun Fan
committed
Add cloudsql gen2 managed vms sample
1 parent eb3310f commit 4546b67

File tree

5 files changed

+238
-0
lines changed

5 files changed

+238
-0
lines changed

managed_vms/cloudsql/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/bin/

managed_vms/cloudsql/README.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Cloud SQL sample for Google Managed VMs
2+
This sample demonstrates how to use [Cloud SQL](https://cloud.google.com/sql/) on Google Managed VMs.
3+
4+
## Setup
5+
Before you can run or deploy the sample, you will need to do the following:
6+
7+
1. Create a [Second Generation Cloud SQL](https://cloud.google.com/sql/docs/create-instance) instance. You can do this from the [Cloud Console](https://console.developers.google.com) or via the [Cloud SDK](https://cloud.google.com/sdk). To create it via the SDK use the following command:
8+
9+
$ gcloud sql instances create YOUR_INSTANCE_NAME \
10+
--activation-policy=ALWAYS \
11+
--tier=db-n1-standard-1
12+
13+
1. Set the root password on your Cloud SQL instance:
14+
15+
$ gcloud sql instances set-root-password YOUR_INSTANCE_NAME --password YOUR_INSTANCE_ROOT_PASSWORD
16+
17+
1. Use the MySQL command line tools (or a management tool of your choice) to create a [new user](https://cloud.google.com/sql/docs/create-user) and [database](https://cloud.google.com/sql/docs/create-database) for your application:
18+
19+
$ mysql -h [IP Address of database] -u root -p
20+
mysql> create database YOUR_DATABASE;
21+
mysql> create user 'YOUR_USER'@'%' identified by 'PASSWORD';
22+
mysql> grant all on YOUR_DATABASE.* to 'YOUR_USER'@'%';
23+
24+
1. Set the connection string environment variable in src/main/appengine/app.yaml
25+
26+
## Running locally
27+
$ mvn clean jetty:run
28+
29+
## Deploying
30+
$ mvn clean gcloud:deploy

managed_vms/cloudsql/pom.xml

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright 2016 Google Inc. All Rights Reserved.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<project>
18+
<modelVersion>4.0.0</modelVersion>
19+
<packaging>war</packaging>
20+
<version>1.0-SNAPSHOT</version>
21+
<groupId>com.example.managedvms</groupId>
22+
<artifactId>managed-vms-cloudsql</artifactId>
23+
24+
<parent>
25+
<artifactId>doc-samples</artifactId>
26+
<groupId>com.google.cloud</groupId>
27+
<version>1.0.0</version>
28+
<relativePath>../..</relativePath>
29+
</parent>
30+
31+
<dependencies>
32+
<dependency>
33+
<groupId>javax.servlet</groupId>
34+
<artifactId>javax.servlet-api</artifactId>
35+
<version>3.1.0</version>
36+
<type>jar</type>
37+
<scope>provided</scope>
38+
</dependency>
39+
<!-- [START dependencies] -->
40+
<dependency> <!-- http://dev.mysql.com/doc/connector-j/en/ -->
41+
<groupId>mysql</groupId>
42+
<artifactId>mysql-connector-java</artifactId>
43+
<version>5.1.38</version>
44+
</dependency>
45+
<dependency>
46+
<groupId>com.google.cloud.sql</groupId>
47+
<artifactId>mysql-socket-factory</artifactId>
48+
<version>1.0.0-beta1</version>
49+
</dependency>
50+
<!-- [END dependencies] -->
51+
</dependencies>
52+
<build>
53+
<!-- for hot reload of the web application -->
54+
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
55+
<plugins>
56+
<plugin>
57+
<groupId>com.google.appengine</groupId>
58+
<artifactId>gcloud-maven-plugin</artifactId>
59+
<version>2.0.9.106.v20160420</version>
60+
</plugin>
61+
<plugin>
62+
<groupId>org.apache.maven.plugins</groupId>
63+
<artifactId>maven-war-plugin</artifactId>
64+
<version>2.6</version>
65+
<configuration>
66+
<failOnMissingWebXml>false</failOnMissingWebXml>
67+
</configuration>
68+
</plugin>
69+
<plugin>
70+
<groupId>org.apache.maven.plugins</groupId>
71+
<artifactId>maven-compiler-plugin</artifactId>
72+
<version>3.3</version>
73+
<configuration>
74+
<source>1.8</source>
75+
<target>1.8</target>
76+
</configuration>
77+
</plugin>
78+
<plugin>
79+
<groupId>org.eclipse.jetty</groupId>
80+
<artifactId>jetty-maven-plugin</artifactId>
81+
<version>9.3.7.v20160115</version>
82+
</plugin>
83+
</plugins>
84+
</build>
85+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2016 Google Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
runtime: java
16+
vm: true
17+
18+
handlers:
19+
- url: /.*
20+
script: this field is required, but ignored
21+
secure: always
22+
23+
# [START env_variables]
24+
env_variables:
25+
SQL_REMOTE_URL: jdbc:mysql://google/YOUR-DB-NAME?cloudSqlInstance=YOUR-INSTANCE-NAME&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=USERNAME&password=PASSWORD
26+
SQL_LOCAL_URL: jdbc:mysql://localhost/YOUR-DB-NAME?user=YOUR-USERNAME&password=PASSWORD&useSSL=false
27+
# [END env_variables]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* Copyright 2016 Google Inc. All Rights Reserved.
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+
17+
package com.example.managedvms.cloudsql;
18+
19+
import java.io.IOException;
20+
import java.io.PrintWriter;
21+
import java.net.Inet4Address;
22+
import java.net.Inet6Address;
23+
import java.net.InetAddress;
24+
import java.sql.Connection;
25+
import java.sql.DriverManager;
26+
import java.sql.PreparedStatement;
27+
import java.sql.ResultSet;
28+
import java.sql.SQLException;
29+
import java.sql.Timestamp;
30+
import java.util.Date;
31+
32+
import javax.servlet.ServletException;
33+
import javax.servlet.annotation.WebServlet;
34+
import javax.servlet.http.HttpServlet;
35+
import javax.servlet.http.HttpServletRequest;
36+
import javax.servlet.http.HttpServletResponse;
37+
38+
// [START example]
39+
@SuppressWarnings("serial")
40+
@WebServlet(name = "cloudsql", value = "")
41+
public class CloudSqlServlet extends HttpServlet {
42+
43+
@Override
44+
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException,
45+
ServletException {
46+
// store only the first two octets of a users ip address
47+
String userIp = req.getRemoteAddr();
48+
InetAddress address = InetAddress.getByName(userIp);
49+
if (address instanceof Inet6Address) {
50+
// nest indexOf calls to find the second occurrence of a character in a
51+
// string
52+
// an alternative is to use Apache Commons Lang:
53+
// StringUtils.ordinalIndexOf()
54+
userIp = userIp.substring(0, userIp.indexOf(":", userIp.indexOf(":") + 1)) + ":*:*:*:*:*:*";
55+
} else if (address instanceof Inet4Address) {
56+
userIp = userIp.substring(0, userIp.indexOf(".", userIp.indexOf(".") + 1)) + ".*.*";
57+
}
58+
59+
final String createTableSql = "CREATE TABLE IF NOT EXISTS visits ( visit_id INT NOT NULL "
60+
+ "AUTO_INCREMENT, user_ip VARCHAR(46) NOT NULL, timestamp DATETIME NOT NULL, "
61+
+ "PRIMARY KEY (visit_id) )";
62+
final String createVisitSql = "INSERT INTO visits (user_ip, timestamp) VALUES (?, ?)";
63+
final String selectSql = "SELECT user_ip, timestamp FROM visits ORDER BY timestamp DESC "
64+
+ "LIMIT 10";
65+
PrintWriter out = resp.getWriter();
66+
resp.setContentType("text/plain");
67+
// Detect if running remotely or locally and select correct connection url
68+
String url;
69+
if (System.getenv().containsKey("GAE_MODULE_INSTANCE")) {
70+
url = System.getenv("SQL_REMOTE_URL");
71+
} else {
72+
url = System.getenv("SQL_LOCAL_URL");
73+
}
74+
75+
try (Connection conn = DriverManager.getConnection(url);
76+
PreparedStatement statementCreateVisit = conn.prepareStatement(createVisitSql)) {
77+
conn.createStatement().executeUpdate(createTableSql);
78+
statementCreateVisit.setString(1, userIp);
79+
statementCreateVisit.setTimestamp(2, new Timestamp(new Date().getTime()));
80+
statementCreateVisit.executeUpdate();
81+
82+
try (ResultSet rs = conn.prepareStatement(selectSql).executeQuery()) {
83+
out.print("Last 10 visits:\n");
84+
while (rs.next()) {
85+
String savedIp = rs.getString("user_ip");
86+
String timeStamp = rs.getString("timestamp");
87+
out.print("Time: " + timeStamp + " Addr: " + savedIp + "\n");
88+
}
89+
}
90+
} catch (SQLException e) {
91+
throw new ServletException("SQL error", e);
92+
}
93+
}
94+
}
95+
// [END example]

0 commit comments

Comments
 (0)