/******************************************************************************* * Copyright (c) 2011 The Board of Trustees of the Leland Stanford Junior University * as Operator of the SLAC National Accelerator Laboratory. * Copyright (c) 2011 Brookhaven National Laboratory. * EPICS archiver appliance is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. *******************************************************************************/ package edu.stanford.slac.archiverappliance.PlainPB.utils; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.BasicFileAttributes; import java.util.LinkedList; import org.apache.log4j.Logger; import org.epics.archiverappliance.Event; import org.epics.archiverappliance.common.TimeUtils; import edu.stanford.slac.archiverappliance.PlainPB.FileBackedPBEventStream; import edu.stanford.slac.archiverappliance.PlainPB.PBFileInfo; /** * Various validations for a PB file. * 1) Checks that the times in the PB file are sequential. * * @author mshankar * */ public class ValidatePBFile { private static Logger logger = Logger.getLogger(ValidatePBFile.class.getName()); public static boolean validatePBFile(Path path, boolean verboseMode) throws IOException { PBFileInfo info = new PBFileInfo(path); long previousEpochSeconds = Long.MIN_VALUE; long eventnum = 0; try(FileBackedPBEventStream strm = new FileBackedPBEventStream(info.getPVName(), path, info.getType())) { Event firstEvent = null; Event lastEvent = null; for(Event ev : strm) { long epochSeconds = ev.getEpochSeconds(); if(epochSeconds >= previousEpochSeconds) { previousEpochSeconds = epochSeconds; } else { throw new IOException("We expect to see monotonically increasing timestamps in a PB file" + ". This is not true at " + eventnum + ". The previous time stamp is " + TimeUtils.convertToISO8601String(TimeUtils.convertFromEpochSeconds(previousEpochSeconds, 0)) + ". The current time stamp is " + TimeUtils.convertToISO8601String(TimeUtils.convertFromEpochSeconds(epochSeconds, 0)) ); } if(firstEvent == null) firstEvent = ev; lastEvent = ev; eventnum++; } if(verboseMode) { logger.info("File " + path.getFileName().toString() + " appears to be valid. It has data ranging from " + TimeUtils.convertToISO8601String(TimeUtils.convertFromEpochSeconds(firstEvent.getEpochSeconds(),0)) + " to " + TimeUtils.convertToISO8601String(TimeUtils.convertFromEpochSeconds(lastEvent.getEpochSeconds(),0)) ); } if(verboseMode) { System.out.println(path + " seems to be a valid PB file."); } return true; } catch(Exception ex) { if(verboseMode) { logger.error("Exception parsing file " + path.toAbsolutePath().toString() + "; eventnum=" + eventnum, ex); } System.out.println(path + " is an invalid PB file."); return false; } } /** * @param args   * @throws Exception   */ public static void main(String[] args) throws Exception { if(args == null || args.length <= 0) { printHelpMsg(); return; } boolean verboseMode = false; LinkedList<String> argsAfterOptions = new LinkedList<String>(); for(String arg : args) { if(arg.equals("-v")) { verboseMode = true; } else if(arg.equals("-h")) { printHelpMsg(); return; } else { argsAfterOptions.add(arg); } } for(String fileName : argsAfterOptions) { Path path = Paths.get(fileName); if(Files.isDirectory(path)) { Files.walkFileTree(path, new FileVisitor<Path>() { private boolean verboseMode = false; FileVisitor<Path> init(boolean verboseMode) { this.verboseMode = verboseMode; return this; } @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { validatePBFile(file, verboseMode); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { return FileVisitResult.CONTINUE; } }.init(verboseMode)); } else { validatePBFile(path, verboseMode); } } } private static void printHelpMsg() { System.out.println(); System.out.println("Usage: validate.sh <options> <Any number of file or folder names>"); System.out.println(); System.out.println("\t-h Prints this help"); System.out.println("\t-v Turns on verbose logging."); System.out.println(); System.out.println(); System.out.println(); } }