HADOOP-16186. S3Guard: NPE in DynamoDBMetadataStore.lambda$listChildren.

Author:    Gabor Bota
This commit is contained in:
Gabor Bota 2019-03-28 15:49:56 +00:00 committed by Steve Loughran
parent 15d38b1bf9
commit cfb0186903
No known key found for this signature in database
GPG Key ID: D22CF846DBB162A0
2 changed files with 49 additions and 11 deletions

View File

@ -638,7 +638,18 @@ public DirListingMetadata listChildren(final Path path) throws IOException {
metas.add(meta);
}
// Minor race condition here - if the path is deleted between
// getting the list of items and the directory metadata we might
// get a null in DDBPathMetadata.
DDBPathMetadata dirPathMeta = get(path);
return getDirListingMetadataFromDirMetaAndList(path, metas,
dirPathMeta);
});
}
DirListingMetadata getDirListingMetadataFromDirMetaAndList(Path path,
List<PathMetadata> metas, DDBPathMetadata dirPathMeta) {
boolean isAuthoritative = false;
if (dirPathMeta != null) {
isAuthoritative = dirPathMeta.isAuthoritativeDir();
@ -647,11 +658,20 @@ public DirListingMetadata listChildren(final Path path) throws IOException {
LOG.trace("Listing table {} in region {} for {} returning {}",
tableName, region, path, metas);
return (metas.isEmpty() && dirPathMeta == null)
? null
: new DirListingMetadata(path, metas, isAuthoritative,
if (!metas.isEmpty() && dirPathMeta == null) {
// We handle this case as the directory is deleted.
LOG.warn("Directory marker is deleted, but the list of the directory "
+ "elements is not empty: {}. This case is handled as if the "
+ "directory was deleted.", metas);
return null;
}
if(metas.isEmpty() && dirPathMeta == null) {
return null;
}
return new DirListingMetadata(path, metas, isAuthoritative,
dirPathMeta.getLastUpdated());
});
}
/**

View File

@ -20,6 +20,7 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException;
import com.amazonaws.waiters.WaiterTimedOutException;
@ -27,6 +28,10 @@
import org.apache.hadoop.fs.s3a.AWSClientIOException;
import org.apache.hadoop.test.HadoopTestBase;
import org.apache.hadoop.fs.Path;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.apache.hadoop.fs.s3a.s3guard.DynamoDBMetadataStore.translateTableWaitFailure;
import static org.apache.hadoop.test.LambdaTestUtils.intercept;
@ -91,4 +96,17 @@ public void testTranslateWrappedOtherException() throws Throwable {
assertEquals(e, ex.getCause());
}
@Test
public void testInnerListChildrenDirectoryNpe() throws Exception {
DynamoDBMetadataStore ddbms = new DynamoDBMetadataStore();
Path p = mock(Path.class);
List<PathMetadata> metas = mock(List.class);
when(metas.isEmpty()).thenReturn(false);
DDBPathMetadata dirPathMeta = null;
assertNull("The return value should be null.",
ddbms.getDirListingMetadataFromDirMetaAndList(p, metas, dirPathMeta));
}
}