@Override public StatDetails loadDetails(String detailsId, Date from, Date to, String instance, String type){ List<String> statsIds = find(from, to, instance, type); return loadDetails(detailsId, statsIds); }
public GzipFileStorage(String dir){ this(toFile(dir)); }
public Stats load(String name) { try { return readFromGzipFile(name); } catch (Exception e) { throw new RuntimeException("Failed to read: " + name, e); } }
private GzipFileInfo safeParseName(String name) { GzipFileInfo gzipFileInfo = new GzipFileInfo(); gzipFileInfo.setName(name); DateFormat sdf = getDateFormat(); try{ String noExtension = name.substring(0, name.length() - EXTENSION.length()); String[] parts = noExtension.split(SEPARATOR); if( parts.length == 3 ){ gzipFileInfo.setFromDate(sdf.parse(parts[1])); gzipFileInfo.setToDate(sdf.parse(parts[2])); } }catch(Exception e){ log.warn("Problem parsing stats file name: {}", name, e); } return gzipFileInfo; }
@Override public Stats topLevel(Date from, Date to, String appGroup, String appType) { log.debug("Searching for top level stats from {} to {}", getDateFormat().format(from), getDateFormat().format(to)); Stats merged = new Stats(); listParts().stream() .peek( statsInfo -> log.debug("Checking {}", statsInfo.getName())) .filter(statsInfo -> statsInfo.inRange(from, to)) .peek( statsInfo -> log.debug("Matches: {}", statsInfo.getName())) .map( statsInfo -> load(statsInfo.getName())) .forEach(stats -> merged.merge(stats, false)); return merged; }
private boolean inDateRange(Date from, Date to){ return (from == null || from.getTime() <= getToDate().getTime() ) && (to == null || to.getTime() >= getFromDate().getTime() ); }
@Override public String save(Stats stats, String instance, String type) { String fileName = new GzipFileInfo(stats.getStartDate(), stats.getEndDate(), instance, type).build(); try { return writeToGzipFile(stats, fileName).getName(); } catch (IOException e) { throw new RuntimeException(e); } }
/** * * @param from if null then ignored, matches when from is lower or equal stats from date * @param to if null then ignored, matches when to is greater or equal stats to date * @param instance if null then ignored * @param type if null then ignored * @return */ @Transient public boolean match(Date from, Date to, String instance, String type){ return inDateRange(from, to) && matchType(type) && matchInstance(instance); }
/** * Returns null in case of error but doesn't throw exception; * @param name * @return */ @Transient public static GzipFileInfo safeParse(String name) { try{ return new GzipFileInfo().load(name); }catch(RuntimeException re){ return null; } } }
public List<GzipFileInfo> findParts(Date from, Date to) { if( from == null || to == null || to.before(from) ){ return Collections.emptyList(); } String[] arr = dir.list((dir, name) -> { if( NAME_PATTERN.matcher(name).matches() ){ GzipFileInfo info = safeParseName(name); return info != null && info.inRange(from, to); } return false; }); return toStatsInfo(arr); }
@Override public Histogram loadHistogram(String detailsId, Date from, Date to, String instance, String type, String lastGroupId){ List<String> statsIds = find(from, to, instance, type); Histogram result = new Histogram(detailsId); processStats(statsIds, stats -> { Stat stat = getDetailsOrEmpty(detailsId, stats); result.add(stat, stats.getStartDate(),stats.getEndDate()); }); return result; }
@Override public StatDetails loadDetails(String detailsId, List<String> statsIds){ StatDetails result = new StatDetails(detailsId, null); processStats(statsIds, stats -> { Stat stat = getDetailsOrEmpty(detailsId, stats); result.add(stat); }); return result; }
@Override public Stats load(String statsId) { try { return readFromGzipFile(statsId); } catch (Exception e) { throw new RuntimeException("Failed to read stats with ID: " + statsId, e); } }
private String buildPartName(Date dateStart, Date dateEnd) { DateFormat sdf = getDateFormat(); return PREFIX + SEPARATOR + sdf.format(dateStart) + SEPARATOR + sdf.format(dateEnd) + "." + EXTENSION; }
private String cleanupFileNameSegment(String part){ //name segments cannot contain separators and should contain "safe" characters only return NAME_SEGMENT_CLEANUP_PATTERN.matcher(wrapNull(part)).replaceAll(""); }
@Transient public String build() { return PREFIX + SEPARATOR + DATE_FORMAT.format(fromDate) + SEPARATOR + DATE_FORMAT.format(toDate) + SEPARATOR + cleanupFileNameSegment(type) + SEPARATOR + cleanupFileNameSegment(instance) + "." + EXTENSION; }
@Override public void setup(String dirName) { defaultStorage = new GzipStorage(); defaultStorage.setup(dirName); dailyStorage = new GzipStorage(); dailyStorage.setup(dirName + "/day"); weeklyStorage = new GzipStorage(); weeklyStorage.setup(dirName + "/week"); monthlyStorage = new GzipStorage(); monthlyStorage.setup(dirName + "/month"); } }
@Transient public boolean inRange(Date from, Date to){ return from != null && to != null && getFromDate() != null && getToDate() != null && from.getTime() <= getFromDate().getTime() && to.getTime() >= getFromDate().getTime(); } }