package org.lucares.pdbui; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.net.Socket; import java.net.SocketAddress; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.TimeoutException; import java.util.zip.GZIPInputStream; import org.lucares.pdbui.CsvReaderSettings.ColumnDefinitions; import org.lucares.performance.db.Entries; public final class IngestionHandler implements Callable { final Socket clientSocket; private final ArrayBlockingQueue queue; public IngestionHandler(final Socket clientSocket, final ArrayBlockingQueue queue) { this.clientSocket = clientSocket; this.queue = queue; } @Override public Void call() throws Exception { final SocketAddress clientAddress = clientSocket.getRemoteSocketAddress(); Thread.currentThread().setName("worker-" + clientAddress); TcpIngestor.LOGGER.debug("opening streams to client"); try (PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); InputStream in = new BufferedInputStream(clientSocket.getInputStream());) { TcpIngestor.LOGGER.debug("reading from stream"); handleInputStream(in); TcpIngestor.LOGGER.debug("connection closed: " + clientAddress); } catch (final Throwable e) { TcpIngestor.LOGGER.warn("Stream handling failed", e); throw e; } return null; } private void handleInputStream(final InputStream in) throws IOException, InterruptedException, TimeoutException { in.mark(1); final byte firstByte = (byte) in.read(); if (isGZIP(firstByte)) { in.reset(); final GZIPInputStream gzip = new GZIPInputStream(in); handleInputStream(gzip); } else { in.reset(); final CsvToEntryTransformer csvTransformer = new CsvToEntryTransformer(queue, CsvReaderSettings.create("@timestamp", "duration", ",", new ColumnDefinitions())); csvTransformer.readCSV(in); } } private boolean isGZIP(final byte firstByte) { // GZIP starts with 0x1f, 0x8b, see https://www.ietf.org/rfc/rfc1952.txt section // 2.3.1 // I am cheap and only check the first byte return firstByte == 0x1f; } }