From 450a9adcd84dfe5241a971e276e13ce87d419eab Mon Sep 17 00:00:00 2001 From: rickle-msft Date: Wed, 25 Mar 2020 09:27:55 -0700 Subject: [PATCH 1/5] Added abort and close --- ChangeLog.txt | 3 + .../storage/blob/CloudBlockBlobTests.java | 65 +++++++++++++++++++ .../azure/storage/blob/BlobDecryptStream.java | 5 ++ .../azure/storage/blob/BlobEncryptStream.java | 5 ++ .../azure/storage/blob/BlobOutputStream.java | 6 ++ .../blob/BlobOutputStreamInternal.java | 15 +++++ .../storage/blob/BlobRequestOptions.java | 36 +++++++++- .../azure/storage/blob/CloudBlockBlob.java | 24 +++++-- .../storage/blob/LengthLimitingStream.java | 5 ++ pom.xml | 2 +- 10 files changed, 157 insertions(+), 9 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 156a70dfc..921ce20ec 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,6 @@ +2020.03.25 Version 8.6.3 + * Added the commitWriteOnInputStreamException option to BlobRequestOptions, which will allow the user to configure whether any data staged through openWrite when using the upload(InputStream, long) method will be committed upon failures in the InputStream. + 2020.03.18 Version 8.6.2 * Fixed a bug in the pom that disrupted the ability to download from maven central. diff --git a/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java index c4ec4334d..5bfd86dd9 100644 --- a/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java +++ b/microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java @@ -2755,6 +2755,71 @@ public void testSkipEtagCheck() throws StorageException, IOException, URISyntaxE stream.close(); } + private static class ExceptionInputStream extends InputStream { + private final byte[] data; + int index = 0; + boolean firstRead = true; + + ExceptionInputStream(byte[] data) { + this.data = data; + } + + @Override + public int read() throws IOException { + return 0; + } + + @Override + public int read(byte[] arr, int offset, int len) throws IOException { + if (firstRead) { + // Fill either half the incoming buffer or use half the data, whichever is smaller. + // For safe partial write. + int size = Math.min(data.length, len) / 2; + if (len >= 0) System.arraycopy(data, index, arr, offset, size); + firstRead = false; + return size; + } else { + throw new IOException(); + } + } + } + + @Test + public void testCommitOnInputStreamException() throws StorageException, IOException, URISyntaxException { + final int blobSize = 2 * Constants.DEFAULT_MINIMUM_READ_SIZE_IN_BYTES; // so BlobInputStream doesn't read entire blob at once. + + CloudBlobContainer container = BlobTestHelper.getRandomContainerReference(); + container.createIfNotExists(); + CloudBlockBlob blob = container.getBlockBlobReference(BlobTestHelper.generateRandomBlobNameWithPrefix("")); + + BlobRequestOptions options = new BlobRequestOptions(); + + // Upload with no commit on failure. + byte[] data = TestHelper.getRandomBuffer(blobSize); + InputStream is = new ExceptionInputStream(data); + options.setCommitWriteOnInputStreamException(false); + + try { + blob.upload(is, blobSize, null, null, options, null); + fail(); + } catch(IOException e) { + assertFalse(blob.exists()); + } + + // Upload with commit on failure. + is = new ExceptionInputStream(data); + options = new BlobRequestOptions(); // Test the default. Should be true. + + try { + blob.upload(is, blobSize, null, null, options, null); + fail(); + } catch (IOException e) { + assertTrue(blob.exists()); + } + + container.delete(); + } + @Test public void testPutGetBlobCPK() throws URISyntaxException, StorageException, IOException { // load CPK into options diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobDecryptStream.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobDecryptStream.java index 10d5e5076..9ede15ceb 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobDecryptStream.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobDecryptStream.java @@ -59,6 +59,11 @@ public void close() throws IOException this.cryptoStream.close(); } + @Override + void abortAndClose() throws IOException { + this.cryptoStream.close(); + } + @Override public void write(byte[] data, int offset, int length) throws IOException { // Keep buffering until we have 16 bytes of IV. diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobEncryptStream.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobEncryptStream.java index 165193906..3c9241a09 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobEncryptStream.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobEncryptStream.java @@ -159,4 +159,9 @@ public void close() throws IOException { this.cipherStream.close(); } + @Override + void abortAndClose() throws IOException { + this.cipherStream.close(); + } + } diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStream.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStream.java index 6269ff71b..157003899 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStream.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStream.java @@ -111,4 +111,10 @@ public void write(final byte[] data) throws IOException { @Override @DoesServiceRequest public abstract void close() throws IOException; + + /** + * Closes the output stream without committing the data to the service, typically to be used in cases of errors or + * exceptions in the data source. + */ + abstract void abortAndClose() throws IOException; } \ No newline at end of file diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStreamInternal.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStreamInternal.java index f824f7df7..1cc423bc2 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStreamInternal.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStreamInternal.java @@ -339,6 +339,21 @@ public synchronized void close() throws IOException { } } + @Override + public void abortAndClose() throws IOException { + try { + this.checkStreamState(); + + this.threadExecutor.shutdown(); + } finally { + this.lastError = new IOException(SR.STREAM_CLOSED); + + if (!this.threadExecutor.isShutdown()) { + this.threadExecutor.shutdown(); + } + } + } + /** * Commits the blob, for block blob this uploads the block list. * diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequestOptions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequestOptions.java index b2424ab12..67012db73 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequestOptions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequestOptions.java @@ -89,7 +89,15 @@ public final class BlobRequestOptions extends RequestOptions { * Default is false. */ private boolean skipEtagLocking = false; - + + /** + * A boolean that defines the behavior for handling exceptions when reading from the + * InputStream and using openWrite. If true the data that has been read from + * the stream up to the point of the exception will be flushed and a new blob will be committed with that data. + * Otherwise, the upload will be aborted and no data will be committed. + */ + private boolean commitWriteOnInputStreamException = true; + /** * Creates an instance of the BlobRequestOptions class. */ @@ -119,6 +127,7 @@ public BlobRequestOptions(final BlobRequestOptions other) { //this.setSourceCustomerProvidedKey(other.getSourceCustomerProvidedKey()); this.setValidateEncryptionPolicy(other.getValidateEncryptionPolicy()); this.setSkipEtagLocking(other.getSkipEtagLocking()); + this.setCommitWriteOnInputStreamException(other.getCommitWriteOnInputStreamException()); } } @@ -362,6 +371,18 @@ public boolean getSkipEtagLocking() { return this.skipEtagLocking; } + /** + * A boolean that defines the behavior for handling exceptions when reading from the + * InputStream and using openWrite. If true the data that has been read from + * the stream up to the point of the exception will be flushed and a new blob will be committed with that data. + * Otherwise, the upload will be aborted and no data will be committed. + * + * @return true if data will be committed upon an exception; otherwise, false. + */ + public boolean getCommitWriteOnInputStreamException() { + return this.commitWriteOnInputStreamException; + } + /** * Sets whether a conditional failure should be absorbed on a retry attempt for the request. This option * is only used by {@link CloudAppendBlob} in upload and openWrite methods. By default, it is set to @@ -528,6 +549,19 @@ public void setSkipEtagLocking(boolean skipEtagLocking) { this.skipEtagLocking = skipEtagLocking; } + /** + * A boolean that defines the behavior for handling exceptions when reading from the + * InputStream and using openWrite. If true the data that has been read from + * the stream up to the point of the exception will be flushed and a new blob will be committed with that data. + * Otherwise, the upload will be aborted and no data will be committed. + * + * @param commitWriteOnInputStreamException + * Use true if data will be committed upon an exception; otherwise, false. + */ + public void setCommitWriteOnInputStreamException(boolean commitWriteOnInputStreamException) { + this.commitWriteOnInputStreamException = commitWriteOnInputStreamException; + } + /** * Assert that if validation is on, an encryption policy is not specified. */ diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java index 4c4bc2a5f..08a3ba125 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java @@ -769,8 +769,9 @@ public void upload(final InputStream sourceStream, final long length, final Acce * If a storage service error occurred. */ @DoesServiceRequest - public void upload(final InputStream sourceStream, final long length, final StandardBlobTier standardBlobTier, final AccessCondition accessCondition, - BlobRequestOptions options, OperationContext opContext) throws StorageException, IOException { + public void upload(final InputStream sourceStream, final long length, final StandardBlobTier standardBlobTier, + final AccessCondition accessCondition, BlobRequestOptions options, + OperationContext opContext) throws StorageException, IOException { if (length < -1) { throw new IllegalArgumentException(SR.STREAM_LENGTH_NEGATIVE); } @@ -892,11 +893,20 @@ public byte[] getByteArray() { useOpenWrite = true; if (useOpenWrite) { final BlobOutputStream writeStream = this.openOutputStream(accessCondition, options, opContext); - try { - writeStream.write(inputDataStream, length); - } - finally { - writeStream.close(); + if (options.getCommitWriteOnInputStreamException()) { + try { + writeStream.write(inputDataStream, length); + } finally { + writeStream.close(); + } + } else { + try { + writeStream.write(inputDataStream, length); + writeStream.close(); + } catch (Exception e) { + writeStream.abortAndClose(); + throw e; + } } } else { diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LengthLimitingStream.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LengthLimitingStream.java index deaa8140d..c1b9ba30f 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LengthLimitingStream.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LengthLimitingStream.java @@ -81,4 +81,9 @@ public void close() throws IOException { // no op } + @Override + void abortAndClose() throws IOException { + // no op + } + } diff --git a/pom.xml b/pom.xml index bf2d9df47..eadb1fb34 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ 4.0.0 com.microsoft.azure azure-storage - 8.6.2 + 8.6.3-commitOnFail jar Microsoft Azure Storage Client SDK From 41980d47f837349b2debbcfe853129bbdb03b790 Mon Sep 17 00:00:00 2001 From: rickle-msft Date: Wed, 25 Mar 2020 09:41:05 -0700 Subject: [PATCH 2/5] Switched to just abort --- .../azure/storage/blob/BlobDecryptStream.java | 4 +-- .../azure/storage/blob/BlobEncryptStream.java | 9 ++--- .../azure/storage/blob/BlobOutputStream.java | 6 ++-- .../blob/BlobOutputStreamInternal.java | 34 +++++++++---------- .../azure/storage/blob/CloudBlockBlob.java | 27 ++++++++------- .../storage/blob/LengthLimitingStream.java | 4 +-- 6 files changed, 42 insertions(+), 42 deletions(-) diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobDecryptStream.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobDecryptStream.java index 9ede15ceb..b588a117c 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobDecryptStream.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobDecryptStream.java @@ -60,8 +60,8 @@ public void close() throws IOException } @Override - void abortAndClose() throws IOException { - this.cryptoStream.close(); + void abort() throws IOException { + // no-op. This method is used in the case of aborting uploads, and decrypt streams are on downloads. } @Override diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobEncryptStream.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobEncryptStream.java index 3c9241a09..d9aa2dc97 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobEncryptStream.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobEncryptStream.java @@ -45,6 +45,8 @@ final class BlobEncryptStream extends BlobOutputStream { * Holds the cipher stream. */ private CipherOutputStream cipherStream; + + private BlobOutputStreamInternal blobStream; /** * Initializes a new instance of the BlobEncryptStream class for a CloudBlockBlob @@ -70,8 +72,7 @@ protected BlobEncryptStream(final CloudBlockBlob blockBlob, final AccessConditio this.options = options; this.options.setValidateEncryptionPolicy(false); - BlobOutputStreamInternal blobStream = - new BlobOutputStreamInternal(blockBlob, accessCondition, options, opContext); + blobStream = new BlobOutputStreamInternal(blockBlob, accessCondition, options, opContext); this.cipherStream = new CipherOutputStream(blobStream, cipher); } @@ -160,8 +161,8 @@ public void close() throws IOException { } @Override - void abortAndClose() throws IOException { - this.cipherStream.close(); + void abort() throws IOException { + this.blobStream.abort(); } } diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStream.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStream.java index 157003899..0e9a480be 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStream.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStream.java @@ -113,8 +113,8 @@ public void write(final byte[] data) throws IOException { public abstract void close() throws IOException; /** - * Closes the output stream without committing the data to the service, typically to be used in cases of errors or - * exceptions in the data source. + * Signals to the BlobOutputStream that it is being aborted and should not commit the data to the service on + * closing, typically to be used in cases of errors or exceptions in the data source. */ - abstract void abortAndClose() throws IOException; + abstract void abort() throws IOException; } \ No newline at end of file diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStreamInternal.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStreamInternal.java index 1cc423bc2..5129db4f5 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStreamInternal.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobOutputStreamInternal.java @@ -144,6 +144,11 @@ public Thread newThread(Runnable r) { */ private final ThreadPoolExecutor threadExecutor; + /** + * Indicates whether the stream has been aborted and therefore closing will skip committing data. + */ + private boolean aborted; + /** * Initializes a new instance of the BlobOutputStream class. * @@ -314,17 +319,20 @@ public synchronized void close() throws IOException { this.checkStreamState(); // flush any remaining data - this.flush(); + if (!this.aborted) { + this.flush(); + } // shut down the ExecutorService. this.threadExecutor.shutdown(); // try to commit the blob - try { - this.commit(); - } - catch (final StorageException e) { - throw Utility.initIOException(e); + if (!this.aborted) { + try { + this.commit(); + } catch (final StorageException e) { + throw Utility.initIOException(e); + } } } finally { @@ -340,18 +348,8 @@ public synchronized void close() throws IOException { } @Override - public void abortAndClose() throws IOException { - try { - this.checkStreamState(); - - this.threadExecutor.shutdown(); - } finally { - this.lastError = new IOException(SR.STREAM_CLOSED); - - if (!this.threadExecutor.isShutdown()) { - this.threadExecutor.shutdown(); - } - } + public void abort() throws IOException { + this.aborted = true; } /** diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java index 08a3ba125..8d268f73f 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/CloudBlockBlob.java @@ -893,20 +893,21 @@ public byte[] getByteArray() { useOpenWrite = true; if (useOpenWrite) { final BlobOutputStream writeStream = this.openOutputStream(accessCondition, options, opContext); - if (options.getCommitWriteOnInputStreamException()) { - try { - writeStream.write(inputDataStream, length); - } finally { - writeStream.close(); - } - } else { - try { - writeStream.write(inputDataStream, length); - writeStream.close(); - } catch (Exception e) { - writeStream.abortAndClose(); - throw e; + /* + We want to give the customer the option to skip the commit on close in case of input stream failures. + While we catch all exceptions here, both from reading the IS and writing to the service, any write which + fails in such a way as to throw effectively aborts the upload anyway, so calling abort in all cases + achieves the intended behavior. + */ + try { + writeStream.write(inputDataStream, length); + } catch (Exception e) { + if (!options.getCommitWriteOnInputStreamException()) { + writeStream.abort(); } + throw e; + } finally { + writeStream.close(); } } else { diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LengthLimitingStream.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LengthLimitingStream.java index c1b9ba30f..b36652c57 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LengthLimitingStream.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/LengthLimitingStream.java @@ -82,8 +82,8 @@ public void close() throws IOException { } @Override - void abortAndClose() throws IOException { - // no op + void abort() throws IOException { + // no op. Abort is only used to abort uploads and this type is only used on download paths. } } From de6919fa1b9416263369d53977912637cc229281 Mon Sep 17 00:00:00 2001 From: rickle-msft Date: Mon, 30 Mar 2020 11:53:35 -0700 Subject: [PATCH 3/5] Release prep --- README.md | 2 +- microsoft-azure-storage-samples/pom.xml | 2 +- .../src/com/microsoft/azure/storage/logging/pom.xml | 2 +- .../src/com/microsoft/azure/storage/Constants.java | 2 +- pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e04561e3b..e68be2436 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ To get the binaries of this library as distributed by Microsoft, ready for use w com.microsoft.azure azure-storage - 8.6.2 + 8.6.3 ``` diff --git a/microsoft-azure-storage-samples/pom.xml b/microsoft-azure-storage-samples/pom.xml index bb0127b13..027319870 100644 --- a/microsoft-azure-storage-samples/pom.xml +++ b/microsoft-azure-storage-samples/pom.xml @@ -26,7 +26,7 @@ com.microsoft.azure azure-storage - 8.6.2 + 8.6.3 com.microsoft.azure diff --git a/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/logging/pom.xml b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/logging/pom.xml index 1f24b9e02..51ae2c68a 100644 --- a/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/logging/pom.xml +++ b/microsoft-azure-storage-samples/src/com/microsoft/azure/storage/logging/pom.xml @@ -26,7 +26,7 @@ com.microsoft.azure azure-storage - 8.6.2 + 8.6.3 com.microsoft.azure diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/Constants.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/Constants.java index 85967e678..f9dfd503f 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/Constants.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/Constants.java @@ -765,7 +765,7 @@ public static class HeaderConstants { /** * Specifies the value to use for UserAgent header. */ - public static final String USER_AGENT_VERSION = "8.6.2"; + public static final String USER_AGENT_VERSION = "8.6.3"; /** * The default type for content-type and accept diff --git a/pom.xml b/pom.xml index eadb1fb34..f771ae3eb 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ 4.0.0 com.microsoft.azure azure-storage - 8.6.3-commitOnFail + 8.6.3 jar Microsoft Azure Storage Client SDK From 074671368692326966337b7a31f22b5d9b85eaf3 Mon Sep 17 00:00:00 2001 From: rickle-msft Date: Mon, 30 Mar 2020 15:26:28 -0700 Subject: [PATCH 4/5] Disabled https keep alive by default. --- ChangeLog.txt | 3 ++- .../microsoft/azure/storage/RequestOptions.java | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 921ce20ec..eee3b4fc5 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,5 +1,6 @@ -2020.03.25 Version 8.6.3 +2020.03.30 Version 8.6.3 * Added the commitWriteOnInputStreamException option to BlobRequestOptions, which will allow the user to configure whether any data staged through openWrite when using the upload(InputStream, long) method will be committed upon failures in the InputStream. + * Disabled httpsKeepAlive by default as it can introduce some perf issues. 2020.03.18 Version 8.6.2 * Fixed a bug in the pom that disrupted the ability to download from maven central. diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/RequestOptions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/RequestOptions.java index 6cee08217..101c94986 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/RequestOptions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/RequestOptions.java @@ -108,7 +108,7 @@ protected static void applyBaseDefaultsInternal(final RequestOptions modifiedOpt } if (modifiedOptions.disableHttpsSocketKeepAlive() == null) { - modifiedOptions.setDisableHttpsSocketKeepAlive(false); + modifiedOptions.setDisableHttpsSocketKeepAlive(true); } } @@ -209,7 +209,7 @@ public Boolean requireEncryption() { * keep-alive; otherwise, false. For more information about disableHttpsSocketKeepAlive defaults, see * {@link ServiceClient#getDefaultRequestOptions()} * - * @return A value to indicate whther https socket keep-alive should be disabled. + * @return A value to indicate whether https socket keep-alive should be disabled. */ public Boolean disableHttpsSocketKeepAlive() { return this.disableHttpsSocketKeepAlive; @@ -322,16 +322,16 @@ public void setRequireEncryption(Boolean requireEncryption) { * Sets a value to indicate whether https socket keep-alive should be disabled. Use true to disable * keep-alive; otherwise, false *

- * The default is set in the client and is by default false, indicating that https socket keep-alive will be - * enabled. You can change the value on this request by setting this property. You can also change the value on + * The default is set in the client and is by default true, indicating that https socket keep-alive will be + * disabled. You can change the value on this request by setting this property. You can also change the value on * on the {@link ServiceClient#getDefaultRequestOptions()} object so that all subsequent requests made via the * service client will use the appropriate value. *

* Setting keep-alive on https sockets is to work around a bug in the JVM where connection timeouts are not honored - * on retried requests. In those cases, we use socket keep-alive as a fallback. Unfortunately, the timeout value - * must be taken from a JVM property rather than configured locally. Therefore, in rare cases the JVM has configured - * aggressively short keep-alive times, it may be beneficial to disable the use of keep-alives lest they interfere - * with long running data transfer operations. + * on retried requests. In those cases, you may choose to use socket keep-alive as a fallback. Unfortunately, the + * timeout value must be taken from a JVM property rather than configured locally. Therefore, in rare cases the JVM + * has configured aggressively short keep-alive times, it may not be beneficial to enable the use of keep-alives + * lest they interfere with long running data transfer operations. * * @param disableHttpsSocketKeepAlive * A value to indicate whether https socket keep-alive should be disabled. From e7064fbb33088cdce539388ed3f85b869bfeeebf Mon Sep 17 00:00:00 2001 From: rickle-msft Date: Mon, 30 Mar 2020 15:55:22 -0700 Subject: [PATCH 5/5] doc updates --- .../com/microsoft/azure/storage/blob/BlobRequestOptions.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequestOptions.java b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequestOptions.java index 67012db73..80d5678a4 100644 --- a/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequestOptions.java +++ b/microsoft-azure-storage/src/com/microsoft/azure/storage/blob/BlobRequestOptions.java @@ -377,6 +377,8 @@ public boolean getSkipEtagLocking() { * the stream up to the point of the exception will be flushed and a new blob will be committed with that data. * Otherwise, the upload will be aborted and no data will be committed. * + * For more information about defaults, see {@link #setCommitWriteOnInputStreamException(boolean)}. + * * @return true if data will be committed upon an exception; otherwise, false. */ public boolean getCommitWriteOnInputStreamException() { @@ -555,6 +557,8 @@ public void setSkipEtagLocking(boolean skipEtagLocking) { * the stream up to the point of the exception will be flushed and a new blob will be committed with that data. * Otherwise, the upload will be aborted and no data will be committed. * + * The default value is true. + * * @param commitWriteOnInputStreamException * Use true if data will be committed upon an exception; otherwise, false. */