All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.cloud.sql.mysql.SocketFactory Maven / Gradle / Ivy

Go to download

Socket factory for the MySQL JDBC driver (version 8.x) that allows a user with the appropriate permissions to connect to a Cloud SQL database without having to deal with IP allowlisting or SSL certificates manually.

There is a newer version: 1.24.0
Show newest version
/*
 * Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.cloud.sql.mysql;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.cloud.sql.core.SslSocketFactory;
import com.mysql.cj.protocol.ServerSession;
import com.mysql.cj.protocol.SocketConnection;

import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
import jnr.unixsocket.UnixSocketAddress;
import jnr.unixsocket.UnixSocketChannel;

/**
 * A MySQL {@link SocketFactory} that establishes a secure connection to a Cloud SQL instance using
 * ephemeral certificates.
 *
 * 

The heavy lifting is done by the singleton {@link SslSocketFactory} class. */ public class SocketFactory implements com.mysql.cj.protocol.SocketFactory { private static final Logger logger = Logger.getLogger(SocketFactory.class.getName()); private static final String CloudSqlPrefix = "/cloudsql/"; private Socket socket; @Override public Socket connect(String host, int portNumber, Properties props, int loginTimeout) throws IOException { String instanceName = props.getProperty("cloudSqlInstance"); checkArgument( instanceName != null, "cloudSqlInstance property not set. Please specify this property in the JDBC URL or " + "the connection Properties with value in form \"project:region:instance\""); // gaeEnv="standard" indicates standard instances // runEnv="Production" indicates production instances String gaeEnv = System.getenv("GAE_ENV"); String runEnv = System.getProperty("com.google.appengine.runtime.environment"); // Custom env variable for forcing unix socket Boolean forceUnixSocket = System.getenv("CLOUD_SQL_FORCE_UNIX_SOCKET") != null; // If running on GAE Standard, connect with unix socket if (forceUnixSocket || "standard".equals(gaeEnv) && "Production".equals(runEnv)) { logger.info(String.format( "Connecting to Cloud SQL instance [%s] via unix socket.", instanceName)); UnixSocketAddress socketAddress = new UnixSocketAddress( new File(CloudSqlPrefix + instanceName)); this.socket = UnixSocketChannel.open(socketAddress).socket(); } else { // Default to SSL Socket logger.info(String.format( "Connecting to Cloud SQL instance [%s] via ssl socket.", instanceName)); List ipTypes = SslSocketFactory.listIpTypes( props.getProperty("ipTypes", SslSocketFactory.DEFAULT_IP_TYPES)); this.socket = SslSocketFactory.getInstance().create(instanceName, ipTypes); } return this.socket; } // Cloud SQL sockets always use TLS and the socket returned by connect above is already TLS-ready. It is fine // to implement these as no-ops. @Override public void beforeHandshake() {} @Override public Socket performTlsHandshake(SocketConnection socketConnection, ServerSession serverSession) { return socket; } @Override public void afterHandshake() {} }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy