Skip to content

Commit 8cd70d1

Browse files
author
javaage
committed
add postgres-backup
1 parent 8c2040a commit 8cd70d1

30 files changed

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

flexible/postgres-backup/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+

flexible/postgres-backup/pom.xml

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<!-- Copyright 2017 Google Inc. Licensed under the Apache License, Version
2+
2.0 (the "License"); you may not use this file except in compliance with
3+
the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
4+
Unless required by applicable law or agreed to in writing, software distributed
5+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
6+
OR CONDITIONS OF ANY KIND, either express or implied. See the License for
7+
the specific language governing permissions and limitations under the License. -->
8+
<project>
9+
<modelVersion>4.0.0</modelVersion>
10+
<packaging>war</packaging>
11+
<version>1.0-SNAPSHOT</version>
12+
<groupId>com.example.flexible</groupId>
13+
<artifactId>flexible-postgres</artifactId>
14+
15+
<parent>
16+
<artifactId>appengine-flexible</artifactId>
17+
<groupId>com.google.cloud</groupId>
18+
<version>1.0.0</version>
19+
<relativePath>..</relativePath>
20+
</parent>
21+
22+
<!-- [START properties] -->
23+
<properties>
24+
<!-- INSTANCE_CONNECTION_NAME from Cloud Console > SQL > Instance Details
25+
> Properties or `gcloud sql instances describe <instance> | grep connectionName` -->
26+
27+
<!-- [START_EXCLUDE silent] -->
28+
<maven.compiler.target>1.8</maven.compiler.target>
29+
<maven.compiler.source>1.8</maven.compiler.source>
30+
31+
<failOnMissingWebXml>false</failOnMissingWebXml> <!-- REQUIRED -->
32+
33+
<jetty>9.4.4.v20170414</jetty>
34+
<!-- [END_EXCLUDE] -->
35+
<INSTANCE_CONNECTION_NAME>newagent-25039:asia-northeast1:la</INSTANCE_CONNECTION_NAME>
36+
<user>postgres</user>
37+
<password>la123456</password>
38+
<database>postgres</database>
39+
<sqlURL>jdbc:postgresql://google/${database}?useSSL=false&amp;socketFactoryArg=${INSTANCE_CONNECTION_NAME}&amp;socketFactory=com.google.cloud.sql.postgres.SocketFactory&amp;user=${user}&amp;password=${password}</sqlURL>
40+
</properties>
41+
<!-- [END properties] -->
42+
43+
<dependencies>
44+
<dependency>
45+
<groupId>com.google.api-client</groupId>
46+
<artifactId>google-api-client</artifactId>
47+
<version>1.23.0</version>
48+
</dependency>
49+
<dependency>
50+
<groupId>com.google.api-client</groupId>
51+
<artifactId>google-api-client-appengine</artifactId>
52+
<version>1.23.0</version>
53+
</dependency>
54+
<dependency>
55+
<groupId>com.google.api-client</groupId>
56+
<artifactId>google-api-client-servlet</artifactId>
57+
<version>1.23.0</version>
58+
</dependency>
59+
<dependency>
60+
<groupId>javax.servlet</groupId>
61+
<artifactId>javax.servlet-api</artifactId>
62+
<version>3.1.0</version>
63+
<type>jar</type>
64+
<scope>provided</scope>
65+
</dependency>
66+
<!-- [START dependencies] -->
67+
<dependency>
68+
<groupId>org.postgresql</groupId>
69+
<artifactId>postgresql</artifactId>
70+
<version>42.1.4.jre7</version>
71+
</dependency>
72+
73+
<dependency>
74+
<groupId>com.google.cloud.sql</groupId>
75+
<artifactId>postgres-socket-factory</artifactId>
76+
<version>1.0.4</version>
77+
</dependency>
78+
<!-- [END dependencies] -->
79+
</dependencies>
80+
<build>
81+
<resources>
82+
<resource>
83+
<directory>src/main/resources</directory>
84+
<filtering>true</filtering>
85+
</resource>
86+
</resources>
87+
<!-- for hot reload of the web application -->
88+
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
89+
<plugins>
90+
91+
<plugin>
92+
<groupId>com.google.cloud.tools</groupId>
93+
<artifactId>appengine-maven-plugin</artifactId>
94+
<version>1.3.1</version>
95+
</plugin>
96+
97+
<plugin>
98+
<groupId>org.eclipse.jetty</groupId>
99+
<artifactId>jetty-maven-plugin</artifactId>
100+
<version>${jetty}</version>
101+
</plugin>
102+
</plugins>
103+
</build>
104+
</project>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright 2017 Google Inc.
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+
env: flex
17+
18+
handlers:
19+
- url: /.*
20+
script: this field is required, but ignored
21+
22+
automatic_scaling:
23+
min_num_instances: 1
24+
max_num_instances: 2
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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+
17+
package com.example.postgres;
18+
19+
import com.google.common.base.Stopwatch;
20+
21+
import java.io.IOException;
22+
import java.io.PrintWriter;
23+
import java.net.Inet4Address;
24+
import java.net.Inet6Address;
25+
import java.net.InetAddress;
26+
import java.sql.Connection;
27+
import java.sql.DriverManager;
28+
import java.sql.PreparedStatement;
29+
import java.sql.ResultSet;
30+
import java.sql.SQLException;
31+
import java.sql.Timestamp;
32+
import java.util.Date;
33+
import java.util.Properties;
34+
import java.util.concurrent.TimeUnit;
35+
36+
import javax.servlet.ServletException;
37+
import javax.servlet.annotation.WebServlet;
38+
import javax.servlet.http.HttpServlet;
39+
import javax.servlet.http.HttpServletRequest;
40+
import javax.servlet.http.HttpServletResponse;
41+
42+
// [START example]
43+
@SuppressWarnings("serial")
44+
@WebServlet(name = "postgresql", value = "")
45+
public class PostgresSqlServlet extends HttpServlet {
46+
Connection conn;
47+
48+
@Override
49+
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException,
50+
ServletException {
51+
52+
final String createTableSql = "CREATE TABLE IF NOT EXISTS visits ( visit_id SERIAL NOT NULL, "
53+
+ "user_ip VARCHAR(46) NOT NULL, ts timestamp NOT NULL, "
54+
+ "PRIMARY KEY (visit_id) );";
55+
final String createVisitSql = "INSERT INTO visits (user_ip, ts) VALUES (?, ?);";
56+
final String selectSql = "SELECT user_ip, ts FROM visits ORDER BY ts DESC "
57+
+ "LIMIT 10;";
58+
59+
String path = req.getRequestURI();
60+
if (path.startsWith("/favicon.ico")) {
61+
return; // ignore the request for favicon.ico
62+
}
63+
64+
PrintWriter out = resp.getWriter();
65+
resp.setContentType("text/plain");
66+
67+
// store only the first two octets of a users ip address
68+
String userIp = req.getRemoteAddr();
69+
InetAddress address = InetAddress.getByName(userIp);
70+
if (address instanceof Inet6Address) {
71+
// nest indexOf calls to find the second occurrence of a character in a string
72+
// an alternative is to use Apache Commons Lang: StringUtils.ordinalIndexOf()
73+
userIp = userIp.substring(0, userIp.indexOf(":", userIp.indexOf(":") + 1)) + ":*:*:*:*:*:*";
74+
} else if (address instanceof Inet4Address) {
75+
userIp = userIp.substring(0, userIp.indexOf(".", userIp.indexOf(".") + 1)) + ".*.*";
76+
}
77+
78+
Stopwatch stopwatch = Stopwatch.createStarted();
79+
try (PreparedStatement statementCreateVisit = conn.prepareStatement(createVisitSql)) {
80+
conn.createStatement().executeUpdate(createTableSql);
81+
statementCreateVisit.setString(1, userIp);
82+
statementCreateVisit.setTimestamp(2, new Timestamp(new Date().getTime()));
83+
statementCreateVisit.executeUpdate();
84+
85+
try (ResultSet rs = conn.prepareStatement(selectSql).executeQuery()) {
86+
stopwatch.stop();
87+
out.print("Last 10 visits:\n");
88+
while (rs.next()) {
89+
String savedIp = rs.getString("user_ip");
90+
String timeStamp = rs.getString("ts");
91+
out.println("Time: " + timeStamp + " Addr: " + savedIp);
92+
}
93+
out.println("Elapsed: " + stopwatch.elapsed(TimeUnit.MILLISECONDS));
94+
}
95+
} catch (SQLException e) {
96+
throw new ServletException("SQL error", e);
97+
}
98+
}
99+
100+
@Override
101+
public void init() throws ServletException {
102+
String url;
103+
104+
Properties properties = new Properties();
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("org.postgresql.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+
} finally {
123+
// Nothing really to do here.
124+
}
125+
}
126+
}
127+
// [END example]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sqlUrl=${sqlURL}

flexible/postgres/src/main/java/com/cisco/la/mapper/CourseHistoryModelMapper.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,44 +9,44 @@ public interface CourseHistoryModelMapper {
99

1010
/**
1111
* This method was generated by MyBatis Generator. This method corresponds to the database table public.la_crs_history
12-
* @mbg.generated Mon Jan 08 10:27:08 CST 2018
12+
* @mbg.generated Tue Jan 09 17:10:04 CST 2018
1313
*/
1414
long countByExample(CourseHistoryModelExample example);
1515

1616
/**
1717
* This method was generated by MyBatis Generator. This method corresponds to the database table public.la_crs_history
18-
* @mbg.generated Mon Jan 08 10:27:08 CST 2018
18+
* @mbg.generated Tue Jan 09 17:10:04 CST 2018
1919
*/
2020
int deleteByExample(CourseHistoryModelExample example);
2121

2222
/**
2323
* This method was generated by MyBatis Generator. This method corresponds to the database table public.la_crs_history
24-
* @mbg.generated Mon Jan 08 10:27:08 CST 2018
24+
* @mbg.generated Tue Jan 09 17:10:04 CST 2018
2525
*/
2626
int insert(CourseHistoryModel record);
2727

2828
/**
2929
* This method was generated by MyBatis Generator. This method corresponds to the database table public.la_crs_history
30-
* @mbg.generated Mon Jan 08 10:27:08 CST 2018
30+
* @mbg.generated Tue Jan 09 17:10:04 CST 2018
3131
*/
3232
int insertSelective(CourseHistoryModel record);
3333

3434
/**
3535
* This method was generated by MyBatis Generator. This method corresponds to the database table public.la_crs_history
36-
* @mbg.generated Mon Jan 08 10:27:08 CST 2018
36+
* @mbg.generated Tue Jan 09 17:10:04 CST 2018
3737
*/
3838
List<CourseHistoryModel> selectByExample(CourseHistoryModelExample example);
3939

4040
/**
4141
* This method was generated by MyBatis Generator. This method corresponds to the database table public.la_crs_history
42-
* @mbg.generated Mon Jan 08 10:27:08 CST 2018
42+
* @mbg.generated Tue Jan 09 17:10:04 CST 2018
4343
*/
4444
int updateByExampleSelective(@Param("record") CourseHistoryModel record,
4545
@Param("example") CourseHistoryModelExample example);
4646

4747
/**
4848
* This method was generated by MyBatis Generator. This method corresponds to the database table public.la_crs_history
49-
* @mbg.generated Mon Jan 08 10:27:08 CST 2018
49+
* @mbg.generated Tue Jan 09 17:10:04 CST 2018
5050
*/
5151
int updateByExample(@Param("record") CourseHistoryModel record,
5252
@Param("example") CourseHistoryModelExample example);

0 commit comments

Comments
 (0)