diff --git a/java/google/registry/rde/RdeUploadAction.java b/java/google/registry/rde/RdeUploadAction.java index f1948303a..07bd4da94 100644 --- a/java/google/registry/rde/RdeUploadAction.java +++ b/java/google/registry/rde/RdeUploadAction.java @@ -32,6 +32,7 @@ import com.google.common.io.ByteStreams; import com.googlecode.objectify.VoidWork; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; +import dagger.Lazy; import google.registry.config.RegistryConfig.Config; import google.registry.gcs.GcsUtils; import google.registry.keyring.api.KeyModule.Key; @@ -87,7 +88,15 @@ public final class RdeUploadAction implements Runnable, EscrowTask { @Inject GcsUtils gcsUtils; @Inject Ghostryde ghostryde; @Inject EscrowTaskRunner runner; - @Inject JSch jsch; + + // Using Lazy 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 lazyJsch; + @Inject JSchSshSessionFactory jschSshSessionFactory; @Inject Response response; @Inject RydePgpCompressionOutputStreamFactory pgpCompressionFactory; @@ -193,7 +202,7 @@ public final class RdeUploadAction implements Runnable, EscrowTask { Ghostryde.Decryptor decryptor = ghostryde.openDecryptor(gcsInput, stagingDecryptionKey); Ghostryde.Decompressor decompressor = ghostryde.openDecompressor(decryptor); 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()) { byte[] signature; String rydeFilename = name + ".ryde"; diff --git a/javatests/google/registry/export/BigqueryPollJobActionTest.java b/javatests/google/registry/export/BigqueryPollJobActionTest.java index 28c6e658b..8f599166e 100644 --- a/javatests/google/registry/export/BigqueryPollJobActionTest.java +++ b/javatests/google/registry/export/BigqueryPollJobActionTest.java @@ -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.Method; import com.google.appengine.api.taskqueue.dev.QueueStateInfo.TaskStateInfo; -import dagger.Lazy; import google.registry.export.BigqueryPollJobAction.BigqueryPollJobEnqueuer; import google.registry.request.HttpException.BadRequestException; import google.registry.request.HttpException.NotModifiedException; @@ -41,6 +40,7 @@ import google.registry.testing.AppEngineRule; import google.registry.testing.ExceptionRule; import google.registry.testing.FakeClock; import google.registry.testing.FakeSleeper; +import google.registry.testing.Lazies; import google.registry.testing.TaskQueueHelper; import google.registry.testing.TaskQueueHelper.TaskMatcher; import google.registry.util.CapturingLogHandler; @@ -94,12 +94,7 @@ public class BigqueryPollJobActionTest { action.enqueuer = ENQUEUER; action.projectId = PROJECT_ID; action.jobId = JOB_ID; - action.chainedQueueName = - new Lazy() { - @Override - public String get() { - return CHAINED_QUEUE_NAME; - }}; + action.chainedQueueName = Lazies.of(CHAINED_QUEUE_NAME); Logger.getLogger(BigqueryPollJobAction.class.getName()).addHandler(logHandler); } diff --git a/javatests/google/registry/rde/RdeUploadActionTest.java b/javatests/google/registry/rde/RdeUploadActionTest.java index 40d561c6c..bb4b238e4 100644 --- a/javatests/google/registry/rde/RdeUploadActionTest.java +++ b/javatests/google/registry/rde/RdeUploadActionTest.java @@ -68,6 +68,7 @@ import google.registry.testing.FakeResponse; import google.registry.testing.FakeSleeper; import google.registry.testing.GpgSystemCommandRule; import google.registry.testing.IoSpyRule; +import google.registry.testing.Lazies; import google.registry.testing.Providers; import google.registry.testing.TaskQueueHelper.TaskMatcher; import google.registry.testing.sftp.SftpServerRule; @@ -189,10 +190,11 @@ public class RdeUploadActionTest { action.clock = clock; action.gcsUtils = new GcsUtils(gcsService, BUFFER_SIZE); action.ghostryde = new Ghostryde(BUFFER_SIZE); - action.jsch = - JSchModule.provideJSch( - "user@ignored", - keyring.getRdeSshClientPrivateKey(), keyring.getRdeSshClientPublicKey()); + action.lazyJsch = + Lazies.of( + JSchModule.provideJSch( + "user@ignored", + keyring.getRdeSshClientPrivateKey(), keyring.getRdeSshClientPublicKey())); action.jschSshSessionFactory = new JSchSshSessionFactory(standardSeconds(3)); action.response = response; action.pgpCompressionFactory = compressFactory; @@ -285,7 +287,7 @@ public class RdeUploadActionTest { persistResource( Cursor.create(CursorType.RDE_STAGING, stagingCursor, Registry.get("tld"))); RdeUploadAction action = createAction(uploadUrl); - action.jsch = createThrowingJSchSpy(action.jsch, 2); + action.lazyJsch = Lazies.of(createThrowingJSchSpy(action.lazyJsch.get(), 2)); action.runWithLock(uploadCursor); assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getContentType()).isEqualTo(PLAIN_TEXT_UTF_8); @@ -306,7 +308,7 @@ public class RdeUploadActionTest { persistResource( Cursor.create(CursorType.RDE_STAGING, stagingCursor, Registry.get("tld"))); 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."); action.runWithLock(uploadCursor); } diff --git a/javatests/google/registry/testing/Lazies.java b/javatests/google/registry/testing/Lazies.java new file mode 100644 index 000000000..6d8f422af --- /dev/null +++ b/javatests/google/registry/testing/Lazies.java @@ -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 Lazy of(final T instance) { + return new Lazy() { + @Override + public T get() { + return instance; + }}; + } +}