HADOOP-17934. ABFS: Make sure the AbfsHttpOperation is non-null before using it (#3477)

Contributed by: Josh Elser

Change-Id: I24a2e0322d8cae2d72d65c7f3d8a74580a418317
This commit is contained in:
Josh Elser 2021-09-30 08:38:13 -04:00 committed by Steve Loughran
parent 31b44c519c
commit feeaebeb84
No known key found for this signature in database
GPG Key ID: D22CF846DBB162A0
2 changed files with 29 additions and 2 deletions

View File

@ -39,6 +39,7 @@
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting;
import org.apache.hadoop.thirdparty.com.google.common.base.Preconditions;
import org.apache.hadoop.thirdparty.com.google.common.base.Strings; import org.apache.hadoop.thirdparty.com.google.common.base.Strings;
import org.apache.hadoop.thirdparty.com.google.common.util.concurrent.FutureCallback; import org.apache.hadoop.thirdparty.com.google.common.util.concurrent.FutureCallback;
import org.apache.hadoop.thirdparty.com.google.common.util.concurrent.Futures; import org.apache.hadoop.thirdparty.com.google.common.util.concurrent.Futures;
@ -383,6 +384,10 @@ public AbfsRestOperation createPath(final String path, final boolean isFile, fin
try { try {
op.execute(tracingContext); op.execute(tracingContext);
} catch (AzureBlobFileSystemException ex) { } catch (AzureBlobFileSystemException ex) {
// If we have no HTTP response, throw the original exception.
if (!op.hasResult()) {
throw ex;
}
if (!isFile && op.getResult().getStatusCode() == HttpURLConnection.HTTP_CONFLICT) { if (!isFile && op.getResult().getStatusCode() == HttpURLConnection.HTTP_CONFLICT) {
String existingResource = String existingResource =
op.getResult().getResponseHeader(X_MS_EXISTING_RESOURCE_TYPE); op.getResult().getResponseHeader(X_MS_EXISTING_RESOURCE_TYPE);
@ -506,6 +511,10 @@ public AbfsRestOperation renamePath(String source, final String destination,
try { try {
op.execute(tracingContext); op.execute(tracingContext);
} catch (AzureBlobFileSystemException e) { } catch (AzureBlobFileSystemException e) {
// If we have no HTTP response, throw the original exception.
if (!op.hasResult()) {
throw e;
}
final AbfsRestOperation idempotencyOp = renameIdempotencyCheckOp( final AbfsRestOperation idempotencyOp = renameIdempotencyCheckOp(
renameRequestStartTime, op, destination, tracingContext); renameRequestStartTime, op, destination, tracingContext);
if (idempotencyOp.getResult().getStatusCode() if (idempotencyOp.getResult().getStatusCode()
@ -530,7 +539,7 @@ public AbfsRestOperation renamePath(String source, final String destination,
* the one initiated from this ABFS filesytem instance as it was retried. This * the one initiated from this ABFS filesytem instance as it was retried. This
* should be a corner case hence going ahead with LMT check. * should be a corner case hence going ahead with LMT check.
* @param renameRequestStartTime startTime for the rename request * @param renameRequestStartTime startTime for the rename request
* @param op Rename request REST operation response * @param op Rename request REST operation response with non-null HTTP response
* @param destination rename destination path * @param destination rename destination path
* @param tracingContext Tracks identifiers for request header * @param tracingContext Tracks identifiers for request header
* @return REST operation response post idempotency check * @return REST operation response post idempotency check
@ -541,6 +550,7 @@ public AbfsRestOperation renameIdempotencyCheckOp(
final AbfsRestOperation op, final AbfsRestOperation op,
final String destination, final String destination,
TracingContext tracingContext) throws AzureBlobFileSystemException { TracingContext tracingContext) throws AzureBlobFileSystemException {
Preconditions.checkArgument(op.hasResult(), "Operations has null HTTP response");
if ((op.isARetriedRequest()) if ((op.isARetriedRequest())
&& (op.getResult().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND)) { && (op.getResult().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND)) {
// Server has returned HTTP 404, which means rename source no longer // Server has returned HTTP 404, which means rename source no longer
@ -612,6 +622,10 @@ public AbfsRestOperation append(final String path, final byte[] buffer,
try { try {
op.execute(tracingContext); op.execute(tracingContext);
} catch (AzureBlobFileSystemException e) { } catch (AzureBlobFileSystemException e) {
// If we have no HTTP response, throw the original exception.
if (!op.hasResult()) {
throw e;
}
if (reqParams.isAppendBlob() if (reqParams.isAppendBlob()
&& appendSuccessCheckOp(op, path, && appendSuccessCheckOp(op, path,
(reqParams.getPosition() + reqParams.getLength()), tracingContext)) { (reqParams.getPosition() + reqParams.getLength()), tracingContext)) {
@ -796,6 +810,10 @@ public AbfsRestOperation deletePath(final String path, final boolean recursive,
try { try {
op.execute(tracingContext); op.execute(tracingContext);
} catch (AzureBlobFileSystemException e) { } catch (AzureBlobFileSystemException e) {
// If we have no HTTP response, throw the original exception.
if (!op.hasResult()) {
throw e;
}
final AbfsRestOperation idempotencyOp = deleteIdempotencyCheckOp(op); final AbfsRestOperation idempotencyOp = deleteIdempotencyCheckOp(op);
if (idempotencyOp.getResult().getStatusCode() if (idempotencyOp.getResult().getStatusCode()
== op.getResult().getStatusCode()) { == op.getResult().getStatusCode()) {
@ -822,10 +840,11 @@ public AbfsRestOperation deletePath(final String path, final boolean recursive,
* delete issued from this filesystem instance. * delete issued from this filesystem instance.
* These are few corner cases and usually returning a success at this stage * These are few corner cases and usually returning a success at this stage
* should help the job to continue. * should help the job to continue.
* @param op Delete request REST operation response * @param op Delete request REST operation response with non-null HTTP response
* @return REST operation response post idempotency check * @return REST operation response post idempotency check
*/ */
public AbfsRestOperation deleteIdempotencyCheckOp(final AbfsRestOperation op) { public AbfsRestOperation deleteIdempotencyCheckOp(final AbfsRestOperation op) {
Preconditions.checkArgument(op.hasResult(), "Operations has null HTTP response");
if ((op.isARetriedRequest()) if ((op.isARetriedRequest())
&& (op.getResult().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) && (op.getResult().getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND)
&& DEFAULT_DELETE_CONSIDERED_IDEMPOTENT) { && DEFAULT_DELETE_CONSIDERED_IDEMPOTENT) {

View File

@ -71,6 +71,14 @@ public class AbfsRestOperation {
private AbfsHttpOperation result; private AbfsHttpOperation result;
private AbfsCounters abfsCounters; private AbfsCounters abfsCounters;
/**
* Checks if there is non-null HTTP response.
* @return true if there is a non-null HTTP response from the ABFS call.
*/
public boolean hasResult() {
return result != null;
}
public AbfsHttpOperation getResult() { public AbfsHttpOperation getResult() {
return result; return result;
} }