Can't connect to Google Cloud 2nd Gen from GAE - google-app-engine

I backed up my Cloud SQL V1 DB to a bucket and restored to a new 2nd-gen instance. Connecting via the console works fine. I can select, look at procs etc. Connecting to it from my Java GAE app doesn't. The GAE app and the Cloud SQL DB are in the same project.
I get these values in the logs:
GAE log:
java.sql.SQLInvalidAuthorizationSpecException: Not authorized to access instance: xxxx
SQL log:
[Warning] User 'root'#'%' was assigned access 0x1fffffff but was allowed to have only 0x1fff7dff.
Any tips?

Make sure your JDBC URL uses the jdbc:google:mysql:// prefix and not the old/deprecated jdbc:google:rdbms:// prefix.
While jdbc:google:rdbms:// continues to work for First Generation instances, it won't work when connecting to Second Generation instances. jdbc:google:mysql:// will work for both.

Related

Cloud SQL / MySQL server fails after deploying to Google Cloud

I have a Google App Engine application that operates perfectly when run locally using localhost:8080, but after I deploy to the cloud using gcloud app deploy, I receive the following error:
Warning: PDO::__construct(): MySQL server has gone away in /base/data/home/apps/s~fileabcd/20190320t221240.123456737151234567/gac_abcd.php on line 7
Warning: PDO::__construct(): Error while reading greeting packet. PID=-1 in /base/data/home/apps/s~fileabcd/20190320t221240.123456737151234567/gac_abcd.php on line 7
Any ideas why this is happening?
I discovered the reason why my Google App Engine (GAE) application functioned properly on localhost, but threw a MySQL server has gone away error after being deployed to [PROJECT-ID].appspot.com.
The reason is because my application was connecting to a Cloud SQL instance in a different project, and in order to do this you must grant the default appengine service account ([PROJECT-ID]#appspot.gserviceaccount.com) one of the following IAM roles:
Cloud SQL Client
Cloud SQL Editor
Cloud SQL Admin
After I added the App Engine default service account as a Cloud SQL Client Role in the project containing the Cloud SQL instance, everything worked perfectly.
From the Cloud SQL documentation.

"TLS requested but server does not support TLS" error with Google Cloud SQL (2nd generation) from Google App Engine?

I'm running into an issue in re-using my connection string (resolved here ... Cannot connect to Google Cloud SQL using SSL + Golang from Google App Engine ...) from connecting to a Google Cloud SQL generation one instance while trying to connect to a generation two instance. I'm receiving this error: TLS requested but server does not support TLS
I can't figure out how to get around this, and the documentation is pretty scarce.
I caught the fact that Instance connection name follows a different structure on generation two, but that doesn't seem like the issue. Has anyone solved this? I'm connecting from Golang.
MySQL level SSL is not currently supported between App Engine Standard Environment and Cloud SQL Second Generation instances.
Communication between App Engine Standard Environment and Cloud SQL is already encrypted so using MySQL level SSL does not add a lot of value, though I can understand that doing application level SSL can add some peace of mind since what happens between Cloud SQL and App Engine is opaque.
I'll try to see if this is something we can change.

Communications link failure when connect to Google Cloud SQL(second gen) only from prod

Setting up a google cloud platform app with google cloud sql and for the life of me I cannot get a connection to the db when I run the code from google servers.
Following this example: https://cloud.google.com/appengine/docs/java/cloud-sql/?csw=1
I've gotten the non production url constructed properly and can connect with no issues to the cloud sql with this url
Class.forName("com.mysql.jdbc.Driver");
url = "jdbc:mysql://<ip-address>:3306/<database>?user=root";
So that's all good. This is the url I'm building for the prod connection.
Class.forName("com.mysql.jdbc.GoogleDriver");
url = "jdbc:google:mysql://<project-id>:<cloud sql instance name>/<database>?user=root";
I got the Project ID from the dashboard and the Instance ID SQL Instances List, database is the same as the non prod value and since non prod works I'm confident that's alright
Product and Instance ID locations I pulled them from
After deploying it all out I get the error message:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
appengine-web.xml does have use-google-connector-j set to true and I saw that for the second generation cloud sql you do not need to specify your app on the authorization list in cloud SQL.
Any help would be appreciated
https://cloud.google.com/sql/docs/dev-access#gaev1-csqlv2-connect
You should look at "instance connection name" in "Instance details" of your instance. For second generation, it's "project-id:region-name:cloud-sql-instance-name", not "project-id:cloud-sql-instance-name" as in the first generation.
When trying to connect to GCP SQL from google cloud run, do not forget to enable connection to GCP SQL from the google cloud run service level settings.
Having the setting disabled (default) can also cause the communications link faulure error.

Google Cloud SQL connection is always null (NullPointerException)

I'm trying out a new app on app-engine. The app basically does some operations on Cloud SQL and displays the results on the app side. Everything works perfectly fine locally. That is i'm able to connect to local MySql db, create connection to the db and manipulate data on it. But when the app is deployed to app-engine i'm always getting NullPointerException as the Connection object returned as a result of this line :-
connection = DriverManager.getConnection("jdbc:google:mysql://your-project- id:your-instance-name/htlaets?user=root");
is always null.
I'm very sure that my project id and instance name are correct.
I have enabled the google connector in appengine-web.xml.
Have authorized my app for the SQL instance.
Both the db and app are in the same region.
Also, i'm able to connect to this instance(First generation) through my MySql Client application.
I don't know what wrong I'm doing here. Can someone please suggest how solve this ?

Connect to google cloud sql from local development server

I have just started with google appengine. I am developing an app in php. If I wanted to see the result, I used
dev_appserver.py ./ --php_executable_path /usr/bin/php5-cgi
(It doesn't work without the --php_executable_path parameter for me)
It works fine, except I cannot connect to the cloud sql instance. I read this https://cloud.google.com/appengine/docs/php/cloud-sql and tried to connect to the cloud sql by:
$sql = new mysqli(null,
'root', // username
'', // password
,
null,
'/cloudsql/:'
);
If I deploy something to appengine, this works, but what should I do, if I need to debug the app localy and it depends on the database?
#DTing's answer is correct that Google's docs encourage you to use a local MySQL from the local development server and recommend that pattern.
However, if you disagree and want to run the development server against your "production" SQL in the cloud, that's supported, too (just not encouraged because a bug during development could destroy your production data!).
Specifically, you follow the general instructions at, and pointed to by, https://cloud.google.com/sql/docs/getting-started#work (ignoring the appengine-specific part): make sure your Cloud SQL instance has an IP address, enable the outside-visible IP address of your workstation, make sure the SQL instance has a root password -- then check everything is working with a command line MySQL client, e.g
[[Note: to verify your workstation's outside-visible IP address, use e.g a browser to visit a site such as http://checkmyip.com/ ]]
$ mysql --host=INSTANCE_IP --user=root --password
and once everything is set up properly you just follow the instructions at https://cloud.google.com/appengine/docs/php/cloud-sql/#PHP_Using_a_local_MySQL_instance_during_development :
To connect to a Cloud SQL instance from your development environment,
substitute "127.0.0.1" with the instance IP address. You do not use
the "/cloudsql/"-based connection string to connect to a Cloud SQL
instance if your App Engine app is running locally in the Development
Server.
If you want to use the same code locally and deployed, you can use a
Special $_SERVER keys variable (SERVER_SOFTWARE) to determine where
your code is running. This approach is shown below.
So for example if your Cloud SQL's IP address is 12.34.56.78, you'd use
$sql = new mysqli('12.34.56.78:3306',
'<username>',
'<password>',
<database-name>
);
when $_SERVER['SERVER_SOFTWARE'] is not set or does not contain Google App Engine (which means you're running on the local development server).
https://cloud.google.com/appengine/docs/php/cloud-sql/#PHP_Using_a_local_MySQL_instance_during_development
The Guestbook example above shows how your application can connect to a Cloud SQL instance when the code runs in App Engine and connect to a local MySQL server when the code runs in the Development Server. We encourage this pattern to minimize confusion and maximize flexibility.

Resources