diff --git a/flexible/cloudsql/.gitignore b/flexible/cloudsql/.gitignore index ae3c1726048..83926cdbcaa 100644 --- a/flexible/cloudsql/.gitignore +++ b/flexible/cloudsql/.gitignore @@ -1 +1,2 @@ /bin/ +target diff --git a/flexible/cloudsql/README.md b/flexible/cloudsql/README.md index 7b8be9c60fd..d2c3f3e6e67 100644 --- a/flexible/cloudsql/README.md +++ b/flexible/cloudsql/README.md @@ -1,32 +1,29 @@ -# Cloud SQL sample for Google Managed VMs -This sample demonstrates how to use [Cloud SQL](https://cloud.google.com/sql/) on Google Managed VMs. +# Cloud SQL sample for Google App Engine Flexible +This sample demonstrates how to use [Cloud SQL](https://cloud.google.com/sql/) on Google App Engine +Flexible. ## Setup -Before you can run or deploy the sample, you will need to do the following: +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) -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: +1. Create a new user and database for the application. The easiest way to do this is via the [Google +Developers Console](https://console.cloud.google.com/sql/instances). Alternatively, you can use +MySQL tools such as the command line client or workbench. +2. Change the root password (under Access Control) and / or create a new user / password. +3. Create a Database (under Databases) (or use MySQL with `gcloud sql connect <instance> --user=root`) +4. Note the **Instance connection name** under Overview > Properties +(It will look like project:region:zone for 2nd Generation) - $ gcloud sql instances create YOUR_INSTANCE_NAME \ - --activation-policy=ALWAYS \ - --tier=db-n1-standard-1 - -1. Set the root password on your Cloud SQL instance: - - $ gcloud sql instances set-root-password YOUR_INSTANCE_NAME --password YOUR_INSTANCE_ROOT_PASSWORD - -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: +## Deploying - $ mysql -h [IP Address of database] -u root -p - mysql> create database YOUR_DATABASE; - mysql> create user 'YOUR_USER'@'%' identified by 'PASSWORD'; - mysql> grant all on YOUR_DATABASE.* to 'YOUR_USER'@'%'; +```bash +$ mvn clean appengine:deploy -DINSTANCE_CONNECTION_NAME=instanceConnectionName -Duser=root +-Dpassword=myPassword -Ddatabase=myDatabase +``` -1. Set the connection string environment variable in src/main/appengine/app.yaml +Or you can update the properties in `pom.xml` ## Running locally - Export local variables - $ export SQL_URL="jdbc:mysql://google/YOUR-DB-NAME?cloudSqlInstance=YOUR-INSTANCE-NAME&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=USERNAME&password=PASSWORD" - $ mvn clean jetty:run -## Deploying - $ mvn clean appengine:deploy +```bash +$ mvn clean jetty:run -DINSTANCE_CONNECTION_NAME=instanceConnectionName -Duser=root -Dpassword=myPassowrd -Ddatabase=myDatabase +``` diff --git a/flexible/cloudsql/pom.xml b/flexible/cloudsql/pom.xml index 71782bdf0b3..f9c20800396 100644 --- a/flexible/cloudsql/pom.xml +++ b/flexible/cloudsql/pom.xml @@ -1,5 +1,5 @@ <!-- - Copyright 2016 Google Inc. All Rights Reserved. + Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -27,7 +27,17 @@ <relativePath>../..</relativePath> </parent> +<!-- [START properties] --> <properties> +<!-- INSTANCE_CONNECTION_NAME from Cloud Console > SQL > Instance Details > Properties + or `gcloud sql instances describe <instance> | grep connectionName` + project:region:instance for Cloud SQL 2nd Generation +--> + <INSTANCE_CONNECTION_NAME></INSTANCE_CONNECTION_NAME> + <user>root</user> + <password></password> + <database>sqldemo</database> +<!-- [START_EXCLUDE] --> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> @@ -35,7 +45,10 @@ <jetty.maven.plugin>9.3.8.v20160314</jetty.maven.plugin> <failOnMissingWebXml>false</failOnMissingWebXml> <!-- REQUIRED --> +<!-- [END_EXCLUDE] --> + <sqlURL>jdbc:mysql://google/${database}?cloudSqlInstance=${INSTANCE_CONNECTION_NAME}&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=${user}&password=${password}&useSSL=false</sqlURL> </properties> +<!-- [END properties] --> <dependencies> <dependency> @@ -46,23 +59,51 @@ <scope>provided</scope> </dependency> <!-- [START dependencies] --> + <dependency> <!-- http://dev.mysql.com/doc/connector-j/en/ --> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>6.0.5</version> + </dependency> <dependency> <groupId>com.google.cloud.sql</groupId> - <artifactId>mysql-socket-factory</artifactId> + <artifactId>mysql-socket-factory-connector-j-6</artifactId> <version>1.0.2</version> </dependency> <!-- [END dependencies] --> </dependencies> <build> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + </resources> <!-- for hot reload of the web application --> <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory> <plugins> + +<!-- + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <version>3.0.0</version> + <configuration> + <webResources> + <resource> + <directory>${basedir}/src/main/appengine</directory> + <filtering>true</filtering> + <targetPath></targetPath> + </resource> + </webResources> + </configuration> + </plugin> + --> + + <plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>appengine-maven-plugin</artifactId> <version>${appengine.maven.plugin}</version> - <configuration> - </configuration> </plugin> <plugin> diff --git a/flexible/cloudsql/src/main/appengine/app.yaml b/flexible/cloudsql/src/main/appengine/app.yaml index 3e936c97ac4..698951aaf74 100644 --- a/flexible/cloudsql/src/main/appengine/app.yaml +++ b/flexible/cloudsql/src/main/appengine/app.yaml @@ -1,4 +1,4 @@ -# Copyright 2016 Google Inc. All Rights Reserved. +# Copyright 2016 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,16 +13,13 @@ # limitations under the License. runtime: java -vm: true +env: flex handlers: - url: /.* script: this field is required, but ignored secure: always -# [START env_variables] -# YOUR-INSTANCE-NAME is ProjectID:Region:DbInstance -# YOUR-DB-NAME is your DatabaseName -env_variables: - SQL_URL: jdbc:mysql://google/YOUR-DB-NAME?cloudSqlInstance=YOUR-INSTANCE-NAME&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=USERNAME&password=PASSWORD -# [END env_variables] +automatic_scaling: + min_num_instances: 1 + max_num_instances: 2 diff --git a/flexible/cloudsql/src/main/java/com/example/cloudsql/CloudSqlServlet.java b/flexible/cloudsql/src/main/java/com/example/cloudsql/CloudSqlServlet.java index 7400583bfa0..45558bb24f8 100644 --- a/flexible/cloudsql/src/main/java/com/example/cloudsql/CloudSqlServlet.java +++ b/flexible/cloudsql/src/main/java/com/example/cloudsql/CloudSqlServlet.java @@ -1,5 +1,5 @@ /** - * Copyright 2016 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import java.sql.SQLException; import java.sql.Timestamp; import java.util.Date; +import java.util.Properties; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; @@ -39,6 +40,7 @@ @SuppressWarnings("serial") @WebServlet(name = "cloudsql", value = "") public class CloudSqlServlet extends HttpServlet { + String url; @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, @@ -64,8 +66,6 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOExc + "LIMIT 10"; PrintWriter out = resp.getWriter(); resp.setContentType("text/plain"); - // Detect if running remotely or locally and select correct connection url - String url = System.getenv("SQL_URL"); try (Connection conn = DriverManager.getConnection(url); PreparedStatement statementCreateVisit = conn.prepareStatement(createVisitSql)) { @@ -86,5 +86,17 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOExc throw new ServletException("SQL error", e); } } + + @Override + public void init() { + try { + Properties properties = new Properties(); + properties.load( + getServletContext().getResourceAsStream("/WEB-INF/classes/config.properties")); + url = properties.getProperty("sqlUrl"); + } catch (IOException e) { + log("no property", e); // Servlet Init should never fail. + } + } } // [END example] diff --git a/flexible/cloudsql/src/main/resources/config.properties b/flexible/cloudsql/src/main/resources/config.properties new file mode 100644 index 00000000000..405c4a6848e --- /dev/null +++ b/flexible/cloudsql/src/main/resources/config.properties @@ -0,0 +1 @@ +sqlUrl=${sqlURL}