package org.araqne.logstorage.dump.engine; import java.io.EOFException; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.araqne.api.Io; import org.araqne.codec.EncodingRule; import org.araqne.logstorage.Log; import org.araqne.logstorage.LogStorage; import org.araqne.logstorage.dump.DumpManifest; import org.araqne.logstorage.dump.DumpService; import org.araqne.logstorage.dump.DumpTabletEntry; import org.araqne.logstorage.dump.DumpTabletKey; import org.araqne.logstorage.dump.ImportRequest; import org.araqne.logstorage.dump.ImportTabletTask; import org.araqne.logstorage.dump.ImportTask; import org.araqne.logstorage.dump.ImportWorker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LocalImportWorker implements ImportWorker { private final Logger slog = LoggerFactory.getLogger(LocalImportWorker.class); private ImportRequest req; private ImportTask task; private DumpService dumpService; private LogStorage storage; private File path; public LocalImportWorker(ImportRequest req, DumpService dumpService, LogStorage storage) { this.req = req; this.dumpService = dumpService; this.storage = storage; this.task = new ImportTask(req); for (DumpTabletEntry e : req.getEntries()) { DumpTabletKey key = new DumpTabletKey(e.getTableName(), e.getDay()); ImportTabletTask val = new ImportTabletTask(e.getTableName(), e.getDay(), e.getCount()); task.getTabletTasks().put(key, val); } this.path = new File(req.getParams().get("path")); } @Override public ImportTask getTask() { return task; } @Override public void run() { slog.info("araqne logstorage: start import job [{}]", req.getGuid()); ZipFile zipFile = null; try { DumpManifest manifest = dumpService.readManifest("local", req.getParams()); Map<String, Integer> tables = manifest.getTables(); Set<DumpTabletKey> keys = new HashSet<DumpTabletKey>(); for (DumpTabletEntry e : manifest.getEntries()) { keys.add(new DumpTabletKey(e.getTableName(), e.getDay())); } zipFile = new ZipFile(path); for (DumpTabletKey key : task.getTabletTasks().keySet()) { if (task.isCancelled()) return; ImportTabletTask e = task.getTabletTasks().get(key); if (!keys.contains(key)) continue; Integer tableId = tables.get(e.getTableName()); if (tableId == null) continue; loadFile(zipFile, e, tableId); } } catch (InterruptedException e) { task.setCancelled(); } catch (Throwable t) { task.setFailureException(t); slog.error("araqne logstorage: import job [" + req.getGuid() + "] failed", t); } finally { if (zipFile != null) { try { zipFile.close(); } catch (IOException e) { } } slog.info("araqne logstorage: import job [{}] completed", req.getGuid()); } } @SuppressWarnings("unchecked") private void loadFile(ZipFile zipFile, ImportTabletTask dumpEntry, int tableId) throws IOException, InterruptedException { long total = 0; InputStream is = null; try { String tableName = dumpEntry.getTableName(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); ZipEntry zipEntry = new ZipEntry(tableId + "/" + df.format(dumpEntry.getDay()) + ".dmp"); is = zipFile.getInputStream(zipEntry); while (true) { if (task.isCancelled()) break; byte[] blen = new byte[4]; int readBytes = Io.ensureRead(is, blen, 4); if (readBytes <= 0) break; int len = Io.decodeInt(blen); byte[] b = new byte[len]; readBytes = Io.ensureRead(is, b, len); if (readBytes <= 0) break; if (slog.isDebugEnabled()) slog.debug("araqne logstorage: importing table [{}] block len [{}] actual len [{}]", new Object[] { tableName, len, readBytes }); Object[] arr = (Object[]) EncodingRule.decode(ByteBuffer.wrap(b)); List<Log> logs = new ArrayList<Log>(); for (Object o : arr) { Map<String, Object> m = (Map<String, Object>) o; Date d = (Date) m.get("_time"); Log log = new Log(tableName, d, m); logs.add(log); } total += logs.size(); storage.write(logs); dumpEntry.setImportCount(total); } } catch (EOFException ex) { } finally { if (is != null) { is.close(); } dumpEntry.setCompleted(true); } } }