Skip to content

Commit

Permalink
Generate the inital KeyPair asynchronously.
Browse files Browse the repository at this point in the history
  • Loading branch information
kurtisvg committed Jun 12, 2019
1 parent 48f7ca0 commit 5449cfd
Showing 1 changed file with 25 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@
import com.google.cloud.sql.CredentialFactory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningScheduledExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.Uninterruptibles;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
Expand All @@ -46,6 +50,7 @@
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.logging.Logger;
Expand Down Expand Up @@ -93,7 +98,7 @@ public final class CoreSocketFactory {
private static CoreSocketFactory coreSocketFactory;

private final CertificateFactory certificateFactory;
private final KeyPair localKeyPair;
private final ListenableFuture<KeyPair> localKeyPair;
private final Credential credential;
private final ConcurrentHashMap<String, CloudSqlInstance> instances = new ConcurrentHashMap<>();
private final ListeningScheduledExecutorService executor;
Expand All @@ -108,21 +113,25 @@ public final class CoreSocketFactory {
} catch (CertificateException err) {
throw new RuntimeException("X509 implementation not available", err);
}
this.localKeyPair = localKeyPair;
this.credential = credential;
this.adminApi = adminApi;
this.serverProxyPort = serverProxyPort;
this.executor =
MoreExecutors.listeningDecorator(
MoreExecutors.getExitingScheduledExecutorService(
(ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(2)));

if (localKeyPair != null) {
this.localKeyPair = Futures.immediateFuture(localKeyPair);
} else {
this.localKeyPair = executor.submit(CoreSocketFactory::generateRsaKeyPair);
}
}

/** Returns the {@link CoreSocketFactory} singleton. */
public static synchronized CoreSocketFactory getInstance() {
if (coreSocketFactory == null) {
logger.info("First Cloud SQL connection, generating RSA key pair.");
KeyPair keyPair = generateRsaKeyPair();
CredentialFactory credentialFactory;
if (System.getProperty(CredentialFactory.CREDENTIAL_FACTORY_PROPERTY) != null) {
try {
Expand All @@ -141,7 +150,7 @@ public static synchronized CoreSocketFactory getInstance() {

SQLAdmin adminApi = createAdminApiClient(credential);
coreSocketFactory =
new CoreSocketFactory(keyPair, credential, adminApi, DEFAULT_SERVER_PROXY_PORT);
new CoreSocketFactory(null, credential, adminApi, DEFAULT_SERVER_PROXY_PORT);
}
return coreSocketFactory;
}
Expand Down Expand Up @@ -208,7 +217,7 @@ private static boolean runningOnGaeStandard() {
Socket createSslSocket(String instanceName, List<String> ipTypes) throws IOException {
CloudSqlInstance instance =
instances.computeIfAbsent(
instanceName, k -> new CloudSqlInstance(k, adminApi, executor, localKeyPair));
instanceName, k -> new CloudSqlInstance(k, adminApi, executor, getLocalKeyPair()));

try {
SSLSocket socket = instance.createSslSocket();
Expand Down Expand Up @@ -306,6 +315,17 @@ public Credential create() {
}
}

// Safely returns the result of localKeyPair, or else throws the cause of the exception
private KeyPair getLocalKeyPair() {
try {
return Uninterruptibles.getUninterruptibly(localKeyPair);
} catch (ExecutionException ex) {
Throwable cause = ex.getCause();
Throwables.throwIfUnchecked(cause);
throw new RuntimeException(cause);
}
}

private static KeyPair generateRsaKeyPair() {
KeyPairGenerator generator;
try {
Expand Down

0 comments on commit 5449cfd

Please sign in to comment.