Question

I am using the Google Cloud SQL driver on a Google Compute Instance to persist results to a Google Cloud SQL database during a long running batch process.

At some point, perhaps after the first hour of running, the oAuth token seems to expire, and all subsequent requests fail with:

Caused by: java.sql.SQLException: 400 Bad Request
{
   "error" : "unauthorized_client"
}
at com.google.cloud.sql.jdbc.internal.googleapi.RpcGoogleApi.newOpenConnectionIOException(RpcGoogleApi.java:168)
at com.google.cloud.sql.jdbc.internal.googleapi.RpcGoogleApi.openConnection(RpcGoogleApi.java:104)
at com.google.cloud.sql.jdbc.internal.SqlProtoClient.openConnection(SqlProtoClient.java:58)
at com.google.cloud.sql.jdbc.Driver.connect(Driver.java:66)
at com.google.cloud.sql.Driver.connectImpl(Driver.java:109)
at com.google.cloud.sql.Driver.connect(Driver.java:98)
at com.google.cloud.sql.Driver.connect(Driver.java:31)

I can abort the process, run google_sql.sh from the client line and the restart the batch process, and the connection will be fine until the token expires again.

Apparently, the command line tool is doing something to refresh the token before connecting; how do I do the same for my batch process?

Was it helpful?

Solution 2

The client id and secret of the Cloud SQL tool need to be provided to the JDBC driver because we are using tokens which that particular tool has retrieved: https://developers.google.com/cloud-sql/docs/external

Properties props = new Properties()
props.put("oauth2ClientId", "32555940559.apps.googleusercontent.com");
props.put("oauth2ClientSecret", "ZmssLNjJy2998hD4CTg2ejr2");
DriverManager.getConnection("jdbc:google:rdbms://instance_name/database_name", props);

If you're using Hibernate as I was, you can add this to the persistence.xml:

<persistence-unit name="renjin-repo" transaction-type="RESOURCE_LOCAL">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  ...
  <properties>
  <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
    <property name="hibernate.hbm2ddl.auto" value="update"/>

    <property name="javax.persistence.jdbc.driver" value="com.google.cloud.sql.Driver"/>
    <property name="javax.persistence.jdbc.url" value="jdbc:google:rdbms://project:instance/database_name"/>
    <property name="javax.persistence.jdbc.user" value="root"/>

    <property name="hibernate.connection.oauth2ClientId" value="32555940559.apps.googleusercontent.com"/>
    <property name="hibernate.connection.oauth2ClientSecret" value="ZmssLNjJy2998hD4CTg2ejr2"/>
    <property name="hibernate.connection.pool_size" value="0" />
  </properties>
</persistence-unit>

OTHER TIPS

The Cloud SQL team are working on improving the connectivity from Compute Engine. If you send this question to google-cloud-sql-discuss@googlegroups.com, they will be able to follow up.

https://groups.google.com/forum/#!forum/google-cloud-sql-discuss

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top