From 9e367f958e6a4e2340961783732bf49a16c528e2 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 23 Oct 2017 14:50:54 +0200 Subject: [PATCH] fixed stream handling during wind import; close outside of importFixes to allow for ZIP files Change-Id: I84ad6234ff51e3738c70df0f48e41d6a4fd73881 --- .../bravo/BravoWindImportServlet.java | 13 ++--- .../test/AbstractBravoDataImportTest.java | 20 +++---- .../test/BravoExtendedDataImportTest.java | 54 ++++++++++--------- .../impl/BaseBravoDataImporterImpl.java | 52 +++++++++--------- 4 files changed, 73 insertions(+), 66 deletions(-) diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/windimport/bravo/BravoWindImportServlet.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/windimport/bravo/BravoWindImportServlet.java index 4a9c04af898..bae48e5b24a 100755 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/windimport/bravo/BravoWindImportServlet.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/windimport/bravo/BravoWindImportServlet.java @@ -93,12 +93,13 @@ public class BravoWindImportServlet extends AbstractWindImportServlet { }; if (filename.toLowerCase().endsWith("zip")) { logger.info("Bravo file "+filename+" is a ZIP file"); - final ZipInputStream zipInputStream = new ZipInputStream(inputStream); - ZipEntry entry; - while ((entry=zipInputStream.getNextEntry()) != null) { - if (entry.getName().toLowerCase().endsWith(".txt")) { - logger.info("Reading Bravo wind data from "+filename+"'s ZIP entry "+entry.getName()); - importer.importFixes(zipInputStream, callback, filename, filename, /* downsample */ false); + try (final ZipInputStream zipInputStream = new ZipInputStream(inputStream)) { + ZipEntry entry; + while ((entry=zipInputStream.getNextEntry()) != null) { + if (entry.getName().toLowerCase().endsWith(".txt")) { + logger.info("Reading Bravo wind data from "+filename+"'s ZIP entry "+entry.getName()); + importer.importFixes(zipInputStream, callback, filename, filename, /* downsample */ false); + } } } } else { diff --git a/java/com.sap.sailing.server.trackfiles.test/src/com/sap/sailing/server/trackfiles/test/AbstractBravoDataImportTest.java b/java/com.sap.sailing.server.trackfiles.test/src/com/sap/sailing/server/trackfiles/test/AbstractBravoDataImportTest.java index 64e3c2edf9f..bfc8b789456 100644 --- a/java/com.sap.sailing.server.trackfiles.test/src/com/sap/sailing/server/trackfiles/test/AbstractBravoDataImportTest.java +++ b/java/com.sap.sailing.server.trackfiles.test/src/com/sap/sailing/server/trackfiles/test/AbstractBravoDataImportTest.java @@ -51,15 +51,17 @@ public abstract class AbstractBravoDataImportTest { } protected void testImport(ImportDataDefinition importData) throws FormatNotSupportedException, IOException { - bravoDataImporter.importFixes(importData.getInputStream(), (fixes, device) -> { - for (DoubleVectorFix fix : fixes) { - callbackCallCount++; - sumRideHeightInMeters += new BravoFixImpl(fix).getRideHeight().getMeters(); - } - }, "filename", "source", /* downsample */ true); - Assert.assertEquals(importData.getExpectedFixesCount(), downsampler.getCountSourceTtl()); - Assert.assertEquals(importData.getExpectedFixesConsolidated(), downsampler.getCountImportedTtl()); - Assert.assertEquals(importData.getExpectedFixesConsolidated(), callbackCallCount); + try (final InputStream is = importData.getInputStream()) { + bravoDataImporter.importFixes(is, (fixes, device) -> { + for (DoubleVectorFix fix : fixes) { + callbackCallCount++; + sumRideHeightInMeters += new BravoFixImpl(fix).getRideHeight().getMeters(); + } + }, "filename", "source", /* downsample */ true); + Assert.assertEquals(importData.getExpectedFixesCount(), downsampler.getCountSourceTtl()); + Assert.assertEquals(importData.getExpectedFixesConsolidated(), downsampler.getCountImportedTtl()); + Assert.assertEquals(importData.getExpectedFixesConsolidated(), callbackCallCount); + } } } diff --git a/java/com.sap.sailing.server.trackfiles.test/src/com/sap/sailing/server/trackfiles/test/BravoExtendedDataImportTest.java b/java/com.sap.sailing.server.trackfiles.test/src/com/sap/sailing/server/trackfiles/test/BravoExtendedDataImportTest.java index 25880eb07f0..c000be82511 100644 --- a/java/com.sap.sailing.server.trackfiles.test/src/com/sap/sailing/server/trackfiles/test/BravoExtendedDataImportTest.java +++ b/java/com.sap.sailing.server.trackfiles.test/src/com/sap/sailing/server/trackfiles/test/BravoExtendedDataImportTest.java @@ -54,34 +54,36 @@ public class BravoExtendedDataImportTest extends AbstractBravoDataImportTest { @Test public void testReadingTwoLinesAndInterpolating() throws FormatNotSupportedException, IOException { DynamicBravoFixTrack track = new BravoFixTrackImpl<>(null, "Test Track", /* hasExtendedFixes */ true); - bravoDataImporter.importFixes(new ByteArrayInputStream(( - HEADER_ORDER_DEFAULT+DUMMY_CONTENT+DUMMY_CONTENT2).getBytes(StandardCharsets.UTF_8)), - (fixes, device) -> { - for (DoubleVectorFix fix : fixes) { - track.add(new BravoExtendedFixImpl(fix)); + try (final ByteArrayInputStream inputStream = new ByteArrayInputStream(( + HEADER_ORDER_DEFAULT+DUMMY_CONTENT+DUMMY_CONTENT2).getBytes(StandardCharsets.UTF_8))) { + bravoDataImporter.importFixes(inputStream, + (fixes, device) -> { + for (DoubleVectorFix fix : fixes) { + track.add(new BravoExtendedFixImpl(fix)); + } + }, "filename", "source", /* downsample */ true); + final TimePoint t1 = new MillisecondsTimePoint(1500648308500l); + final TimePoint t2 = new MillisecondsTimePoint(1500648309500l); + final BravoExtendedFix bef1, bef2; + track.lockForRead(); + try { + final Iterator i = track.getFixes().iterator(); + bef1 = (BravoExtendedFix) i.next(); + bef2 = (BravoExtendedFix) i.next(); + } finally { + track.unlockAfterRead(); } - }, "filename", "source", /* downsample */ true); - final TimePoint t1 = new MillisecondsTimePoint(1500648308500l); - final TimePoint t2 = new MillisecondsTimePoint(1500648309500l); - final BravoExtendedFix bef1, bef2; - track.lockForRead(); - try { - final Iterator i = track.getFixes().iterator(); - bef1 = (BravoExtendedFix) i.next(); - bef2 = (BravoExtendedFix) i.next(); - } finally { - track.unlockAfterRead(); + assertEquals(t1, bef1.getTimePoint()); + assertEquals(t2, bef2.getTimePoint()); + assertEquals(0.915471, bef1.getPortRudderRake(), 0.00001); + assertEquals(0.913729, bef2.getPortRudderRake(), 0.00001); + assertEquals(0.915471, track.getPortRudderRakeIfAvailable(t1), 0.00001); + assertEquals(0.913729, track.getPortRudderRakeIfAvailable(t2), 0.00001); + assertEquals((0.915471+0.913729)/2., track.getPortRudderRakeIfAvailable(t1.plus(t1.until(t2).divide(2.))), 0.00001); + assertEquals(new DegreeBearingImpl(-46.507845).getDegrees(), track.getMastRotationIfAvailable(t1).getDegrees(), 0.00001); + assertEquals(new DegreeBearingImpl(-46.845317).getDegrees(), track.getMastRotationIfAvailable(t2).getDegrees(), 0.00001); + assertEquals(new DegreeBearingImpl((-46.507845-46.845317)/2.).getDegrees(), track.getMastRotationIfAvailable(t1.plus(t1.until(t2).divide(2.))).getDegrees(), 0.00001); } - assertEquals(t1, bef1.getTimePoint()); - assertEquals(t2, bef2.getTimePoint()); - assertEquals(0.915471, bef1.getPortRudderRake(), 0.00001); - assertEquals(0.913729, bef2.getPortRudderRake(), 0.00001); - assertEquals(0.915471, track.getPortRudderRakeIfAvailable(t1), 0.00001); - assertEquals(0.913729, track.getPortRudderRakeIfAvailable(t2), 0.00001); - assertEquals((0.915471+0.913729)/2., track.getPortRudderRakeIfAvailable(t1.plus(t1.until(t2).divide(2.))), 0.00001); - assertEquals(new DegreeBearingImpl(-46.507845).getDegrees(), track.getMastRotationIfAvailable(t1).getDegrees(), 0.00001); - assertEquals(new DegreeBearingImpl(-46.845317).getDegrees(), track.getMastRotationIfAvailable(t2).getDegrees(), 0.00001); - assertEquals(new DegreeBearingImpl((-46.507845-46.845317)/2.).getDegrees(), track.getMastRotationIfAvailable(t1.plus(t1.until(t2).divide(2.))).getDegrees(), 0.00001); } private enum ImportData implements ImportDataDefinition { diff --git a/java/com.sap.sailing.server.trackfiles/src/com/sap/sailing/server/trackfiles/impl/BaseBravoDataImporterImpl.java b/java/com.sap.sailing.server.trackfiles/src/com/sap/sailing/server/trackfiles/impl/BaseBravoDataImporterImpl.java index 7827854b863..402bca0252f 100644 --- a/java/com.sap.sailing.server.trackfiles/src/com/sap/sailing/server/trackfiles/impl/BaseBravoDataImporterImpl.java +++ b/java/com.sap.sailing.server.trackfiles/src/com/sap/sailing/server/trackfiles/impl/BaseBravoDataImporterImpl.java @@ -54,6 +54,10 @@ public class BaseBravoDataImporterImpl extends AbstractDoubleVectorFixImporter { } /** + * @param inputStream + * the stream from which to read the fixes; this method will not close the stream; it's the + * caller who is responsible for closing it. This, in particular, allows for usages with ZIP files + * that would suffer from closing the stream here * @param downsample * if {@code true}, fixes will be down-sampled to a 1Hz frequency before being emitted to the * {@code callback}. Otherwise, all fixes read will be forwarded straight to the {@link Callback}. @@ -73,33 +77,31 @@ public class BaseBravoDataImporterImpl extends AbstractDoubleVectorFixImporter { } LOG.fine("Start parsing bravo file"); AtomicLong lineNr = new AtomicLong(); - try (BufferedReader buffer = new BufferedReader(isr)) { - String headerLine = null; - headerSearch: while (headerLine == null) { - LOG.fine("Searching for header in bravo file"); - String headerCandidate = buffer.readLine(); - lineNr.incrementAndGet(); - if (headerCandidate == null) { - throw new RuntimeException("Missing required header in file " + filename); - } - if (headerCandidate.startsWith(BOF)) { - LOG.fine("Found header"); - headerLine = headerCandidate; - break headerSearch; - } + BufferedReader buffer = new BufferedReader(isr); + String headerLine = null; + headerSearch: while (headerLine == null) { + LOG.fine("Searching for header in bravo file"); + String headerCandidate = buffer.readLine(); + lineNr.incrementAndGet(); + if (headerCandidate == null) { + throw new RuntimeException("Missing required header in file " + filename); + } + if (headerCandidate.startsWith(BOF)) { + LOG.fine("Found header"); + headerLine = headerCandidate; + break headerSearch; } - LOG.fine("Validate and parse header columns"); - final Map colIndices = validateAndParseHeader(headerLine); - DoubleFixProcessor downsampler = downsample ? - createDownsamplingProcessor(callback, trackIdentifier) : - fix->callback.addFixes(Collections.singleton(new DoubleVectorFixImpl(fix.getTimepoint(), fix.getFix())), trackIdentifier); - buffer.lines().forEach(line -> { - lineNr.incrementAndGet(); - downsampler.accept(parseLine(lineNr.get(), filename, line, colIndices)); - }); - downsampler.finish(); - buffer.close(); } + LOG.fine("Validate and parse header columns"); + final Map colIndices = validateAndParseHeader(headerLine); + DoubleFixProcessor downsampler = downsample ? + createDownsamplingProcessor(callback, trackIdentifier) : + fix->callback.addFixes(Collections.singleton(new DoubleVectorFixImpl(fix.getTimepoint(), fix.getFix())), trackIdentifier); + buffer.lines().forEach(line -> { + lineNr.incrementAndGet(); + downsampler.accept(parseLine(lineNr.get(), filename, line, colIndices)); + }); + downsampler.finish(); } catch (Exception e) { LOG.log(Level.SEVERE, "Exception parsing bravo CSV file " + filename, e); }