Commit 5fe6d830 by Ashutosh Mestry

ATLAS-2897: Elegant handling of empty zip files.

parent 84c6fb2b
...@@ -153,6 +153,7 @@ public enum AtlasErrorCode { ...@@ -153,6 +153,7 @@ public enum AtlasErrorCode {
INVALID_TIMEBOUNDRY_END_TIME(400, "ATLAS-400-00-87C", "Invalid endTime {0}"), INVALID_TIMEBOUNDRY_END_TIME(400, "ATLAS-400-00-87C", "Invalid endTime {0}"),
INVALID_TIMEBOUNDRY_DATERANGE(400, "ATLAS-400-00-87D", "Invalid dateRange: startTime {0} must be before endTime {1}"), INVALID_TIMEBOUNDRY_DATERANGE(400, "ATLAS-400-00-87D", "Invalid dateRange: startTime {0} must be before endTime {1}"),
PROPAGATED_CLASSIFICATION_REMOVAL_NOT_SUPPORTED(400, "ATLAS-400-00-87E", "Removal of classification {0}, which is propagated from entity {1}, is not supported"), PROPAGATED_CLASSIFICATION_REMOVAL_NOT_SUPPORTED(400, "ATLAS-400-00-87E", "Removal of classification {0}, which is propagated from entity {1}, is not supported"),
IMPORT_ATTEMPTING_EMPTY_ZIP(400, "ATLAS-400-00-87F", "Attempting to import empty ZIP file."),
UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to perform {1}"), UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to perform {1}"),
......
...@@ -40,6 +40,8 @@ import java.util.Map; ...@@ -40,6 +40,8 @@ import java.util.Map;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import static org.apache.atlas.AtlasErrorCode.IMPORT_ATTEMPTING_EMPTY_ZIP;
public class ZipSource implements EntityImportStream { public class ZipSource implements EntityImportStream {
private static final Logger LOG = LoggerFactory.getLogger(ZipSource.class); private static final Logger LOG = LoggerFactory.getLogger(ZipSource.class);
...@@ -52,16 +54,20 @@ public class ZipSource implements EntityImportStream { ...@@ -52,16 +54,20 @@ public class ZipSource implements EntityImportStream {
private List<BaseEntityHandler> entityHandlers; private List<BaseEntityHandler> entityHandlers;
private int currentPosition; private int currentPosition;
public ZipSource(InputStream inputStream) throws IOException { public ZipSource(InputStream inputStream) throws IOException, AtlasBaseException {
this(inputStream, null); this(inputStream, null);
} }
public ZipSource(InputStream inputStream, ImportTransforms importTransform) throws IOException { public ZipSource(InputStream inputStream, ImportTransforms importTransform) throws IOException, AtlasBaseException {
this.inputStream = inputStream; this.inputStream = inputStream;
this.guidEntityJsonMap = new HashMap<>(); this.guidEntityJsonMap = new HashMap<>();
this.importTransform = importTransform; this.importTransform = importTransform;
updateGuidZipEntryMap(); updateGuidZipEntryMap();
if (MapUtils.isEmpty(guidEntityJsonMap)) {
throw new AtlasBaseException(IMPORT_ATTEMPTING_EMPTY_ZIP, "Attempting to import empty ZIP.");
}
setCreationOrder(); setCreationOrder();
} }
...@@ -82,7 +88,7 @@ public class ZipSource implements EntityImportStream { ...@@ -82,7 +88,7 @@ public class ZipSource implements EntityImportStream {
public AtlasTypesDef getTypesDef() throws AtlasBaseException { public AtlasTypesDef getTypesDef() throws AtlasBaseException {
final String fileName = ZipExportFileNames.ATLAS_TYPESDEF_NAME.toString(); final String fileName = ZipExportFileNames.ATLAS_TYPESDEF_NAME.toString();
String s = (String) getFromCache(fileName); String s = getFromCache(fileName);
return convertFromJson(AtlasTypesDef.class, s); return convertFromJson(AtlasTypesDef.class, s);
} }
...@@ -185,7 +191,12 @@ public class ZipSource implements EntityImportStream { ...@@ -185,7 +191,12 @@ public class ZipSource implements EntityImportStream {
} }
private String getFromCache(String entryName) { private String getFromCache(String entryName) {
return guidEntityJsonMap.get(entryName); String s = guidEntityJsonMap.get(entryName);
if (StringUtils.isEmpty(s)) {
LOG.warn("Could not fetch requested contents of file: {}", entryName);
}
return s;
} }
public void close() { public void close() {
...@@ -288,6 +299,4 @@ public class ZipSource implements EntityImportStream { ...@@ -288,6 +299,4 @@ public class ZipSource implements EntityImportStream {
public int getPosition() { public int getPosition() {
return currentPosition; return currentPosition;
} }
} }
...@@ -113,7 +113,7 @@ public class ImportServiceTest extends ExportImportTestBase { ...@@ -113,7 +113,7 @@ public class ImportServiceTest extends ExportImportTestBase {
} }
@DataProvider(name = "sales") @DataProvider(name = "sales")
public static Object[][] getDataFromQuickStart_v1_Sales(ITestContext context) throws IOException { public static Object[][] getDataFromQuickStart_v1_Sales(ITestContext context) throws IOException, AtlasBaseException {
return getZipSource("sales-v1-full.zip"); return getZipSource("sales-v1-full.zip");
} }
...@@ -130,7 +130,7 @@ public class ImportServiceTest extends ExportImportTestBase { ...@@ -130,7 +130,7 @@ public class ImportServiceTest extends ExportImportTestBase {
} }
@DataProvider(name = "reporting") @DataProvider(name = "reporting")
public static Object[][] getDataFromReporting() throws IOException { public static Object[][] getDataFromReporting() throws IOException, AtlasBaseException {
return getZipSource("reporting-v1-full.zip"); return getZipSource("reporting-v1-full.zip");
} }
...@@ -141,7 +141,7 @@ public class ImportServiceTest extends ExportImportTestBase { ...@@ -141,7 +141,7 @@ public class ImportServiceTest extends ExportImportTestBase {
} }
@DataProvider(name = "logging") @DataProvider(name = "logging")
public static Object[][] getDataFromLogging(ITestContext context) throws IOException { public static Object[][] getDataFromLogging(ITestContext context) throws IOException, AtlasBaseException {
return getZipSource("logging-v1-full.zip"); return getZipSource("logging-v1-full.zip");
} }
...@@ -152,7 +152,7 @@ public class ImportServiceTest extends ExportImportTestBase { ...@@ -152,7 +152,7 @@ public class ImportServiceTest extends ExportImportTestBase {
} }
@DataProvider(name = "salesNewTypeAttrs") @DataProvider(name = "salesNewTypeAttrs")
public static Object[][] getDataFromSalesNewTypeAttrs(ITestContext context) throws IOException { public static Object[][] getDataFromSalesNewTypeAttrs(ITestContext context) throws IOException, AtlasBaseException {
return getZipSource("salesNewTypeAttrs.zip"); return getZipSource("salesNewTypeAttrs.zip");
} }
...@@ -163,7 +163,7 @@ public class ImportServiceTest extends ExportImportTestBase { ...@@ -163,7 +163,7 @@ public class ImportServiceTest extends ExportImportTestBase {
} }
@DataProvider(name = "salesNewTypeAttrs-next") @DataProvider(name = "salesNewTypeAttrs-next")
public static Object[][] getDataFromSalesNewTypeAttrsNext(ITestContext context) throws IOException { public static Object[][] getDataFromSalesNewTypeAttrsNext(ITestContext context) throws IOException, AtlasBaseException {
return getZipSource("salesNewTypeAttrs-next.zip"); return getZipSource("salesNewTypeAttrs-next.zip");
} }
...@@ -200,7 +200,7 @@ public class ImportServiceTest extends ExportImportTestBase { ...@@ -200,7 +200,7 @@ public class ImportServiceTest extends ExportImportTestBase {
} }
@DataProvider(name = "ctas") @DataProvider(name = "ctas")
public static Object[][] getDataFromCtas(ITestContext context) throws IOException { public static Object[][] getDataFromCtas(ITestContext context) throws IOException, AtlasBaseException {
return getZipSource("ctas.zip"); return getZipSource("ctas.zip");
} }
...@@ -276,7 +276,7 @@ public class ImportServiceTest extends ExportImportTestBase { ...@@ -276,7 +276,7 @@ public class ImportServiceTest extends ExportImportTestBase {
} }
@DataProvider(name = "hdfs_path1") @DataProvider(name = "hdfs_path1")
public static Object[][] getDataFromHdfsPath1(ITestContext context) throws IOException { public static Object[][] getDataFromHdfsPath1(ITestContext context) throws IOException, AtlasBaseException {
return getZipSource("hdfs_path1.zip"); return getZipSource("hdfs_path1.zip");
} }
...@@ -421,4 +421,14 @@ public class ImportServiceTest extends ExportImportTestBase { ...@@ -421,4 +421,14 @@ public class ImportServiceTest extends ExportImportTestBase {
assertTrue(importTransforms.getTransforms().containsKey("hive_column")); assertTrue(importTransforms.getTransforms().containsKey("hive_column"));
assertEquals(importTransforms.getTransforms().get("hive_table").get("qualifiedName").size(), 2); assertEquals(importTransforms.getTransforms().get("hive_table").get("qualifiedName").size(), 2);
} }
@Test(dataProvider = "empty-zip", expectedExceptions = AtlasBaseException.class)
public void importEmptyZip(ZipSource zipSource) {
}
@Test(expectedExceptions = AtlasBaseException.class)
public void importEmptyZip() throws IOException, AtlasBaseException {
getZipSource("empty.zip");
}
} }
...@@ -150,17 +150,17 @@ public class ZipFileResourceTestUtils { ...@@ -150,17 +150,17 @@ public class ZipFileResourceTestUtils {
return s; return s;
} }
public static Object[][] getZipSource(String fileName) throws IOException { public static Object[][] getZipSource(String fileName) throws IOException, AtlasBaseException {
return new Object[][]{{getZipSourceFrom(fileName)}}; return new Object[][]{{getZipSourceFrom(fileName)}};
} }
public static ZipSource getZipSourceFrom(String fileName) throws IOException { public static ZipSource getZipSourceFrom(String fileName) throws IOException, AtlasBaseException {
FileInputStream fs = ZipFileResourceTestUtils.getFileInputStream(fileName); FileInputStream fs = ZipFileResourceTestUtils.getFileInputStream(fileName);
return new ZipSource(fs); return new ZipSource(fs);
} }
private static ZipSource getZipSourceFrom(ByteArrayOutputStream baos) throws IOException { private static ZipSource getZipSourceFrom(ByteArrayOutputStream baos) throws IOException, AtlasBaseException {
ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray()); ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
ZipSource zipSource = new ZipSource(bis); ZipSource zipSource = new ZipSource(bis);
return zipSource; return zipSource;
......
...@@ -38,21 +38,21 @@ import static org.testng.AssertJUnit.assertTrue; ...@@ -38,21 +38,21 @@ import static org.testng.AssertJUnit.assertTrue;
public class ZipSourceTest { public class ZipSourceTest {
@DataProvider(name = "zipFileStocks") @DataProvider(name = "zipFileStocks")
public static Object[][] getDataFromZipFile() throws IOException { public static Object[][] getDataFromZipFile() throws IOException, AtlasBaseException {
FileInputStream fs = ZipFileResourceTestUtils.getFileInputStream("stocks.zip"); FileInputStream fs = ZipFileResourceTestUtils.getFileInputStream("stocks.zip");
return new Object[][] {{ new ZipSource(fs) }}; return new Object[][] {{ new ZipSource(fs) }};
} }
@DataProvider(name = "zipFileStocksFloat") @DataProvider(name = "zipFileStocksFloat")
public static Object[][] getDataFromZipFileWithLongFloats() throws IOException { public static Object[][] getDataFromZipFileWithLongFloats() throws IOException, AtlasBaseException {
FileInputStream fs = ZipFileResourceTestUtils.getFileInputStream("stocks-float.zip"); FileInputStream fs = ZipFileResourceTestUtils.getFileInputStream("stocks-float.zip");
return new Object[][] {{ new ZipSource(fs) }}; return new Object[][] {{ new ZipSource(fs) }};
} }
@DataProvider(name = "sales") @DataProvider(name = "sales")
public static Object[][] getDataFromQuickStart_v1_Sales(ITestContext context) throws IOException { public static Object[][] getDataFromQuickStart_v1_Sales(ITestContext context) throws IOException, AtlasBaseException {
return getZipSource("sales-v1-full.zip"); return getZipSource("sales-v1-full.zip");
} }
...@@ -66,7 +66,7 @@ public class ZipSourceTest { ...@@ -66,7 +66,7 @@ public class ZipSourceTest {
} }
@Test(dataProvider = "zipFileStocks") @Test(dataProvider = "zipFileStocks")
public void examineContents_BehavesAsExpected(ZipSource zipSource) throws IOException, AtlasBaseException { public void examineContents_BehavesAsExpected(ZipSource zipSource) throws AtlasBaseException {
List<String> creationOrder = zipSource.getCreationOrder(); List<String> creationOrder = zipSource.getCreationOrder();
assertNotNull(creationOrder); assertNotNull(creationOrder);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment