Make JSch injection lazy

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=154958750
This commit is contained in:
guyben 2017-05-03 08:32:49 -07:00 committed by Ben McIlwain
parent 5e7834b00e
commit 93c2a1e4f0
4 changed files with 53 additions and 15 deletions

View file

@ -32,6 +32,7 @@ import com.google.common.io.ByteStreams;
import com.googlecode.objectify.VoidWork; import com.googlecode.objectify.VoidWork;
import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException; import com.jcraft.jsch.JSchException;
import dagger.Lazy;
import google.registry.config.RegistryConfig.Config; import google.registry.config.RegistryConfig.Config;
import google.registry.gcs.GcsUtils; import google.registry.gcs.GcsUtils;
import google.registry.keyring.api.KeyModule.Key; import google.registry.keyring.api.KeyModule.Key;
@ -87,7 +88,15 @@ public final class RdeUploadAction implements Runnable, EscrowTask {
@Inject GcsUtils gcsUtils; @Inject GcsUtils gcsUtils;
@Inject Ghostryde ghostryde; @Inject Ghostryde ghostryde;
@Inject EscrowTaskRunner runner; @Inject EscrowTaskRunner runner;
@Inject JSch jsch;
// Using Lazy<JSch> instead of JSch to prevent fetching of rdeSsh*Keys before we know we're
// actually going to use them. See b/37868282
//
// This prevents making an unnecessary time-expensive (and potentially failing) API call to the
// external KMS system when the RdeUploadAction ends up not being used (if the EscrowTaskRunner
// determins this EscrowTask was already completed today).
@Inject Lazy<JSch> lazyJsch;
@Inject JSchSshSessionFactory jschSshSessionFactory; @Inject JSchSshSessionFactory jschSshSessionFactory;
@Inject Response response; @Inject Response response;
@Inject RydePgpCompressionOutputStreamFactory pgpCompressionFactory; @Inject RydePgpCompressionOutputStreamFactory pgpCompressionFactory;
@ -193,7 +202,7 @@ public final class RdeUploadAction implements Runnable, EscrowTask {
Ghostryde.Decryptor decryptor = ghostryde.openDecryptor(gcsInput, stagingDecryptionKey); Ghostryde.Decryptor decryptor = ghostryde.openDecryptor(gcsInput, stagingDecryptionKey);
Ghostryde.Decompressor decompressor = ghostryde.openDecompressor(decryptor); Ghostryde.Decompressor decompressor = ghostryde.openDecompressor(decryptor);
Ghostryde.Input xmlInput = ghostryde.openInput(decompressor)) { Ghostryde.Input xmlInput = ghostryde.openInput(decompressor)) {
try (JSchSshSession session = jschSshSessionFactory.create(jsch, uploadUrl); try (JSchSshSession session = jschSshSessionFactory.create(lazyJsch.get(), uploadUrl);
JSchSftpChannel ftpChan = session.openSftpChannel()) { JSchSftpChannel ftpChan = session.openSftpChannel()) {
byte[] signature; byte[] signature;
String rydeFilename = name + ".ryde"; String rydeFilename = name + ".ryde";

View file

@ -33,7 +33,6 @@ import com.google.api.services.bigquery.model.JobStatus;
import com.google.appengine.api.taskqueue.TaskOptions; import com.google.appengine.api.taskqueue.TaskOptions;
import com.google.appengine.api.taskqueue.TaskOptions.Method; import com.google.appengine.api.taskqueue.TaskOptions.Method;
import com.google.appengine.api.taskqueue.dev.QueueStateInfo.TaskStateInfo; import com.google.appengine.api.taskqueue.dev.QueueStateInfo.TaskStateInfo;
import dagger.Lazy;
import google.registry.export.BigqueryPollJobAction.BigqueryPollJobEnqueuer; import google.registry.export.BigqueryPollJobAction.BigqueryPollJobEnqueuer;
import google.registry.request.HttpException.BadRequestException; import google.registry.request.HttpException.BadRequestException;
import google.registry.request.HttpException.NotModifiedException; import google.registry.request.HttpException.NotModifiedException;
@ -41,6 +40,7 @@ import google.registry.testing.AppEngineRule;
import google.registry.testing.ExceptionRule; import google.registry.testing.ExceptionRule;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
import google.registry.testing.FakeSleeper; import google.registry.testing.FakeSleeper;
import google.registry.testing.Lazies;
import google.registry.testing.TaskQueueHelper; import google.registry.testing.TaskQueueHelper;
import google.registry.testing.TaskQueueHelper.TaskMatcher; import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.util.CapturingLogHandler; import google.registry.util.CapturingLogHandler;
@ -94,12 +94,7 @@ public class BigqueryPollJobActionTest {
action.enqueuer = ENQUEUER; action.enqueuer = ENQUEUER;
action.projectId = PROJECT_ID; action.projectId = PROJECT_ID;
action.jobId = JOB_ID; action.jobId = JOB_ID;
action.chainedQueueName = action.chainedQueueName = Lazies.of(CHAINED_QUEUE_NAME);
new Lazy<String>() {
@Override
public String get() {
return CHAINED_QUEUE_NAME;
}};
Logger.getLogger(BigqueryPollJobAction.class.getName()).addHandler(logHandler); Logger.getLogger(BigqueryPollJobAction.class.getName()).addHandler(logHandler);
} }

View file

@ -68,6 +68,7 @@ import google.registry.testing.FakeResponse;
import google.registry.testing.FakeSleeper; import google.registry.testing.FakeSleeper;
import google.registry.testing.GpgSystemCommandRule; import google.registry.testing.GpgSystemCommandRule;
import google.registry.testing.IoSpyRule; import google.registry.testing.IoSpyRule;
import google.registry.testing.Lazies;
import google.registry.testing.Providers; import google.registry.testing.Providers;
import google.registry.testing.TaskQueueHelper.TaskMatcher; import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.testing.sftp.SftpServerRule; import google.registry.testing.sftp.SftpServerRule;
@ -189,10 +190,11 @@ public class RdeUploadActionTest {
action.clock = clock; action.clock = clock;
action.gcsUtils = new GcsUtils(gcsService, BUFFER_SIZE); action.gcsUtils = new GcsUtils(gcsService, BUFFER_SIZE);
action.ghostryde = new Ghostryde(BUFFER_SIZE); action.ghostryde = new Ghostryde(BUFFER_SIZE);
action.jsch = action.lazyJsch =
JSchModule.provideJSch( Lazies.of(
"user@ignored", JSchModule.provideJSch(
keyring.getRdeSshClientPrivateKey(), keyring.getRdeSshClientPublicKey()); "user@ignored",
keyring.getRdeSshClientPrivateKey(), keyring.getRdeSshClientPublicKey()));
action.jschSshSessionFactory = new JSchSshSessionFactory(standardSeconds(3)); action.jschSshSessionFactory = new JSchSshSessionFactory(standardSeconds(3));
action.response = response; action.response = response;
action.pgpCompressionFactory = compressFactory; action.pgpCompressionFactory = compressFactory;
@ -285,7 +287,7 @@ public class RdeUploadActionTest {
persistResource( persistResource(
Cursor.create(CursorType.RDE_STAGING, stagingCursor, Registry.get("tld"))); Cursor.create(CursorType.RDE_STAGING, stagingCursor, Registry.get("tld")));
RdeUploadAction action = createAction(uploadUrl); RdeUploadAction action = createAction(uploadUrl);
action.jsch = createThrowingJSchSpy(action.jsch, 2); action.lazyJsch = Lazies.of(createThrowingJSchSpy(action.lazyJsch.get(), 2));
action.runWithLock(uploadCursor); action.runWithLock(uploadCursor);
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
assertThat(response.getContentType()).isEqualTo(PLAIN_TEXT_UTF_8); assertThat(response.getContentType()).isEqualTo(PLAIN_TEXT_UTF_8);
@ -306,7 +308,7 @@ public class RdeUploadActionTest {
persistResource( persistResource(
Cursor.create(CursorType.RDE_STAGING, stagingCursor, Registry.get("tld"))); Cursor.create(CursorType.RDE_STAGING, stagingCursor, Registry.get("tld")));
RdeUploadAction action = createAction(uploadUrl); RdeUploadAction action = createAction(uploadUrl);
action.jsch = createThrowingJSchSpy(action.jsch, 3); action.lazyJsch = Lazies.of(createThrowingJSchSpy(action.lazyJsch.get(), 3));
thrown.expect(RuntimeException.class, "The crow flies in square circles."); thrown.expect(RuntimeException.class, "The crow flies in square circles.");
action.runWithLock(uploadCursor); action.runWithLock(uploadCursor);
} }

View file

@ -0,0 +1,32 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// 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 google.registry.testing;
import dagger.Lazy;
/** Helper functions for {@link Lazy}. */
public final class Lazies {
/**
* Returns a {@link Lazy} that supplies a constant value.
*/
public static <T> Lazy<T> of(final T instance) {
return new Lazy<T>() {
@Override
public T get() {
return instance;
}};
}
}