Issue #1965 added File filtering by file date extension in archive purge.

Amend: updated purge cron time to once every hour.
       moved archive.purge.cron to cron.properties.
       removed purge code from DataArchiver.
       added back isHoursToKeep in DataArchiver.
       updated CategoryFileDateHelper for CategoryConfig dirPattern lists.
       updates from peer review.
       updated test cases to work with Roger's refactoring.
       fixes for ArchiveConfigManager createArchive.
       clean up of ArchiveConfigManager purgeFile.

Change-Id: I096c2a103211caab7b7ec00f18111077cfe3e519

Former-commit-id: 2094b7f9fde97873c759da217498bcf62254a287
This commit is contained in:
Brad Gonzales 2013-06-19 15:38:58 -05:00 committed by Gerrit Code Review
parent f66681f62b
commit 276f05233f
13 changed files with 622 additions and 231 deletions

View file

@ -14,6 +14,8 @@ gfe.cron=0+15+*+*+*+?
repack.cron=0+20+*+*+*+?
# runs database and hdf5 archive for archive server to pull data from
archive.cron=0+40+*+*+*+?
# purge archives
archive.purge.cron=0+0+*+*+*+?
###purge configuration
# Interval at which the purge job kicks off

View file

@ -107,7 +107,7 @@
<includes
id="com.raytheon.uf.edex.npp.feature"
version="0.0.0"/>
<includes
id="com.raytheon.uf.edex.datadelivery.client.feature"
version="0.0.0"/>
@ -124,4 +124,8 @@
id="com.raytheon.uf.edex.registry.feature"
version="0.0.0"/>
<includes
id="com.raytheon.uf.edex.archive.feature"
version="0.0.0"/>
</feature>

View file

@ -29,6 +29,7 @@ import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
@ -71,6 +72,8 @@ import com.raytheon.uf.common.util.FileUtil;
* ------------ ---------- ----------- --------------------------
* May 1, 2013 1966 rferrel Initial creation
* May 29, 2013 1965 bgonzale Added archive creation, purge, and save methods.
* Updated purgeExpiredFromArchive to check time of files in
* directory before purging them.
*
* </pre>
*
@ -203,23 +206,18 @@ public class ArchiveConfigManager {
public Collection<File> createArchive(File archiveDir,
Collection<DisplayData> displaysSelectedForArchive, Calendar start,
Calendar end) throws IOException, ArchiveException {
Collection<File> archivedFiles = null;
Collection<File> archivedFiles = new ArrayList<File>();
FileUtils.forceMkdir(archiveDir);
if (archiveDir.exists()) {
Collection<File> filesToArchive = new ArrayList<File>();
for (DisplayData display : displaysSelectedForArchive) {
List<File> files = getDisplayFiles(display, start, end);
filesToArchive.addAll(files);
String rootDirString = display.archiveConfig.getRootDir();
String archiveDirString = archiveDir.getAbsolutePath();
String rootDirString = display.archiveConfig.getRootDir();
archivedFiles = new ArrayList<File>(filesToArchive.size());
rootDirString = (rootDirString.endsWith(File.separator) ? rootDirString
.substring(0,
rootDirString.lastIndexOf(File.separatorChar))
: rootDirString);
for (File srcFile : filesToArchive) {
for (File srcFile : getDisplayFiles(display, start, end)) {
String fileAbsPath = srcFile.getAbsolutePath();
File newArchiveDir = getDirRelativeToArchiveDirFromRoot(
srcFile.isDirectory(), fileAbsPath, rootDirString,
@ -269,33 +267,84 @@ public class ArchiveConfigManager {
*/
public Collection<File> purgeExpiredFromArchive(ArchiveConfig archive) {
Collection<File> filesPurged = new ArrayList<File>();
String archiveRootDirPath = archive.getRootDir();
File archiveRootDir = new File(archiveRootDirPath);
List<String> topLevelDirsNotPurged = new ArrayList<String>(
Arrays.asList(archiveRootDir.list()));
for (CategoryConfig category : archive.getCategoryList()) {
Calendar purgeTime = calculateExpiration(archive, category);
CategoryFileDateHelper helper = new CategoryFileDateHelper(
category, archive.getRootDir());
IOFileFilter fileDateFilter = FileFilterUtils.and(
FileFilterUtils.fileFileFilter(),
new FileDateFilter(null, purgeTime, helper));
// Remove the directory associated with this category from the not
// purged list since it is being purged.
for (Iterator<String> iter = topLevelDirsNotPurged.iterator(); iter
.hasNext();) {
String dirName = iter.next();
if (helper.isCategoryDirectory(dirName)) {
iter.remove();
break;
}
}
for (DisplayData display : getDisplayData(archive.getName(),
category.getName(), true)) {
List<File> displayFiles = getDisplayFiles(display, null,
purgeTime);
for (File file : displayFiles) {
if (file.isFile()) {
filesPurged.add(file);
} else if (file.isDirectory()) {
filesPurged.addAll(FileUtils.listFiles(file,
FileFilterUtils.fileFileFilter(),
FileFilterUtils.trueFileFilter()));
}
FileUtils.deleteQuietly(file);
filesPurged.addAll(purgeFile(file, fileDateFilter,
archiveRootDirPath));
}
}
}
// check for other expired in top level directories not covered
// by the categories in the archives
Calendar defaultPurgeTime = calculateExpiration(archive, null);
for (String topDirName : topLevelDirsNotPurged) {
IOFileFilter fileDateFilter = FileFilterUtils.and(FileFilterUtils
.fileFileFilter(), new FileDateFilter(null,
defaultPurgeTime));
File topLevelDir = new File(archiveRootDir, topDirName);
filesPurged.addAll(purgeFile(topLevelDir, fileDateFilter,
archiveRootDirPath));
}
return filesPurged;
}
private Collection<File> purgeFile(File fileToPurge,
IOFileFilter filter, final String archiveRootDir) {
Collection<File> filesPurged = new ArrayList<File>();
if (fileToPurge.isFile() && filter.accept(fileToPurge)) {
filesPurged.add(fileToPurge);
FileUtils.deleteQuietly(fileToPurge);
} else if (fileToPurge.isDirectory()) {
Collection<File> expiredFilesInDir = FileUtils.listFiles(
fileToPurge, filter, FileFilterUtils.trueFileFilter());
for (File dirFile : expiredFilesInDir) {
filesPurged.addAll(purgeFile(dirFile, filter, archiveRootDir));
}
// if the directory is empty and not the archive root dir, then
// delete it
if (fileToPurge.list().length == 0
&& !fileToPurge.getAbsolutePath().equals(archiveRootDir)) {
FileUtils.deleteQuietly(fileToPurge);
}
}
return filesPurged;
}
private Calendar calculateExpiration(ArchiveConfig archive,
CategoryConfig category) {
Calendar newCal = TimeUtil.newGmtCalendar();
int retHours = category.getRetentionHours() == 0 ? archive
int retHours = category == null || category.getRetentionHours() == 0 ? archive
.getRetentionHours() : category.getRetentionHours();
if (retHours != 0) {
newCal.add(Calendar.HOUR, (-1) * retHours);

View file

@ -287,7 +287,7 @@ public class CategoryConfig implements Comparable<CategoryConfig> {
public int compareTo(CategoryConfig o) {
return getDisplay().compareToIgnoreCase(o.getDisplay());
}
/*
* (non-Javadoc)
*

View file

@ -0,0 +1,196 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.archive.config;
import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FilenameUtils;
import com.raytheon.uf.common.time.util.TimeUtil;
/**
* File date helper for CategoryConfig objects.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 21, 2013 1965 bgonzale Initial creation
*
* </pre>
*
* @author bgonzale
* @version 1.0
*/
public class CategoryFileDateHelper implements IFileDateHelper {
/**
* Date information derived from each of a Category's dirPatterns.
*/
private static class CategoryDateInfo {
private final Pattern datePattern;
private final Pattern categoryTopLevelDirPattern;
private final int yearIndex;
private final int monthIndex;
private final int dayIndex;
private final int hourIndex;
/**
* Initialization constructor.
*
* @param datePattern
* @param categoryTopLevelDirPattern
* @param yearIndex
* @param monthIndex
* @param dayIndex
* @param hourIndex
*/
public CategoryDateInfo(Pattern datePattern,
Pattern categoryTopLevelDirPattern,
int yearIndex, int monthIndex, int dayIndex, int hourIndex) {
this.datePattern = datePattern;
this.categoryTopLevelDirPattern = categoryTopLevelDirPattern;
this.yearIndex = yearIndex;
this.monthIndex = monthIndex;
this.dayIndex = dayIndex;
this.hourIndex = hourIndex;
}
}
private final List<CategoryDateInfo> dateInfoList;
private final String rootDir;
private final boolean isDirOnly;
/**
* Initialization constructor.
*
* @param config
* @param rootDirPattern
* categoryTopLevelDirPattern
*/
public CategoryFileDateHelper(CategoryConfig config, String rootDir) {
List<String> categoryDirPatternList = config.getDirPatternList();
this.dateInfoList = new ArrayList<CategoryFileDateHelper.CategoryDateInfo>(
categoryDirPatternList.size());
String filePatternStr = config.getFilePattern();
this.rootDir = rootDir;
this.isDirOnly = (filePatternStr == null)
|| ".*".equals(filePatternStr);
for (String patternString : categoryDirPatternList) {
Pattern datePattern = null;
if (isDirOnly) {
datePattern = Pattern.compile(patternString);
} else {
datePattern = Pattern.compile(patternString + File.separator
+ config.getFilePattern());
}
int dirSeparatorIndex = patternString.indexOf(File.separatorChar);
patternString = dirSeparatorIndex > patternString.length()
|| dirSeparatorIndex < 0 ? patternString : patternString
.substring(0, dirSeparatorIndex);
Pattern categoryTopLevelDirPattern = Pattern.compile(patternString);
String[] indexValues = config.getDateGroupIndices().split(
"\\s*,\\s*");
int yearIndex = Integer.parseInt(indexValues[0]);
int monthIndex = Integer.parseInt(indexValues[1]);
int dayIndex = Integer.parseInt(indexValues[2]);
int hourIndex = Integer.parseInt(indexValues[3]);
dateInfoList.add(new CategoryDateInfo(datePattern,
categoryTopLevelDirPattern, yearIndex, monthIndex,
dayIndex, hourIndex));
}
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.archive.config.IFileDateHelper#getFileDate(java
* .lang.String)
*/
@Override
public Calendar getFileDate(String filenamePath) {
String pathForPatternCheck = filenamePath.substring(rootDir.length());
pathForPatternCheck = isDirOnly ? FilenameUtils
.getFullPathNoEndSeparator(pathForPatternCheck)
: pathForPatternCheck;
Calendar result = null;
for (CategoryDateInfo dateInfo : dateInfoList) {
Matcher matcher = dateInfo.datePattern.matcher(pathForPatternCheck);
if (matcher.matches()) {
int year = Integer.parseInt(matcher.group(dateInfo.yearIndex));
// Adjust month value to Calendar's 0 - 11
int month = Integer
.parseInt(matcher.group(dateInfo.monthIndex)) - 1;
int day = Integer.parseInt(matcher.group(dateInfo.dayIndex));
int hour = Integer.parseInt(matcher.group(dateInfo.hourIndex));
result = TimeUtil.newGmtCalendar();
result.set(year, month, day, hour, 0, 0);
break;
}
}
if (result == null) {
// no matching pattern, use file last modified date
File file = new File(filenamePath);
long lastModifiedMillis = file.lastModified();
result = TimeUtil.newGmtCalendar();
result.setTimeInMillis(lastModifiedMillis);
}
return result;
}
/**
* Check if this directory is a category directory. i.e. if the category is
* satellite, is the directory satellite.
*
* @param dirName
* @return true if category directory; false otherwise.
*/
public boolean isCategoryDirectory(String dirName) {
for (CategoryDateInfo dateInfo : dateInfoList) {
if (dateInfo.categoryTopLevelDirPattern.matcher(dirName).matches()) {
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,125 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.archive.config;
import java.io.File;
import java.util.Calendar;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import com.raytheon.uf.common.time.util.TimeUtil;
/**
* Filter files based on a file date parsed using the given file date helper.
* Accept returns true for files that fall between the Start and End times. If
* start is null, then all after start checks will return true. If end is null,
* then all before end checks will return true.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 18, 2013 1965 bgonzale Initial creation
*
* </pre>
*
* @author bgonzale
* @version 1.0
*/
public class FileDateFilter implements IOFileFilter {
private IFileDateHelper helper;
private final Calendar start;
private final Calendar end;
/**
* Initialization constructor. This filter uses file last modified time as
* the filter time.
*
* @param startDate
* @param endDate
*/
public FileDateFilter(Calendar start, Calendar end) {
this(start, end, DEFAULT_FILE_DATE_HELPER);
}
/**
* Initialization constructor.
*
* @param startDate
* @param endDate
* @param helper
*/
public FileDateFilter(Calendar start, Calendar end, IFileDateHelper helper) {
this.helper = helper == null ? DEFAULT_FILE_DATE_HELPER : helper;
this.start = start;
this.end = end;
}
/* (non-Javadoc)
* @see org.apache.commons.io.filefilter.IOFileFilter#accept(java.io.File)
*/
@Override
public boolean accept(File file) {
String filePath = file.getAbsolutePath();
String dirName = FilenameUtils.getFullPath(filePath);
String fileName = FilenameUtils.getName(filePath);
return accept(new File(dirName), fileName);
}
/* (non-Javadoc)
* @see org.apache.commons.io.filefilter.IOFileFilter#accept(java.io.File, java.lang.String)
*/
@Override
public boolean accept(File dir, String name) {
String dirPath = dir.getAbsolutePath();
boolean endsWithSeparator = dirPath.endsWith(File.separator);
dirPath = endsWithSeparator ? dirPath : dirPath + File.separator;
String fileFullPath = dirPath + name;
Calendar fileDate = helper.getFileDate(fileFullPath);
boolean isAfterEqualsStart = start == null || fileDate.after(start)
|| fileDate.equals(start);
boolean isBeforeEqualsEnd = end == null || fileDate.before(end)
|| fileDate.equals(end);
return isAfterEqualsStart && isBeforeEqualsEnd;
}
/**
* This File Date helper returns a file's last modified time.
*/
private static final IFileDateHelper DEFAULT_FILE_DATE_HELPER = new IFileDateHelper() {
@Override
public Calendar getFileDate(String filenamePath) {
// use file last modified date
File file = new File(filenamePath);
long lastModifiedMillis = file.lastModified();
Calendar result = TimeUtil.newGmtCalendar();
result.setTimeInMillis(lastModifiedMillis);
return result;
}
};
}

View file

@ -0,0 +1,45 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.archive.config;
import java.util.Calendar;
/**
* Helper to get a file last modification date.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 21, 2013 bgonzale Initial creation
*
* </pre>
*
* @author bgonzale
* @version 1.0
*/
public interface IFileDateHelper {
public Calendar getFileDate(String filenamePath);
}

View file

@ -9,7 +9,7 @@
xmlns="http://camel.apache.org/schema/spring" errorHandlerRef="errorHandler">
<endpoint id="archivePurgeCron"
uri="clusteredquartz://archive/archivePurgeScheduled/?cron=${archivePurge.cron}" />
uri="clusteredquartz://archive/archivePurgeScheduled/?cron=${archive.purge.cron}" />
<!-- Run archivePurge on Scheduled timer -->
<route id="archivePurgeScheduled">

View file

@ -1,2 +0,0 @@
# purge every half hour
archivePurge.cron=0+0/30,*,*,*,*,*+*+*+*+?

View file

@ -24,6 +24,7 @@ import java.util.Collection;
import com.raytheon.uf.common.archive.config.ArchiveConfig;
import com.raytheon.uf.common.archive.config.ArchiveConfigManager;
/**
* Purge task to purge archived data based on configured expiration.
*

View file

@ -94,15 +94,6 @@ public class DataArchiver {
conf = defaultConf;
}
if (conf.getHoursToKeep() > 0) {
File pluginArchive = new File(baseArchive, pluginName);
if (pluginArchive.isDirectory()) {
long purgeThreshold = System.currentTimeMillis()
- (conf.getHoursToKeep() * 60 * 60 * 1000);
purgeDirectory(pluginArchive, purgeThreshold);
}
}
if (Boolean.TRUE.equals(conf.getArchivingEnabled())) {
for (IPluginArchiver pluginArchiver : pluginArchivers) {
pluginArchiver.archivePlugin(pluginName, archivePath, conf);
@ -134,33 +125,6 @@ public class DataArchiver {
return this;
}
private boolean purgeDirectory(File directory, long purgeThreshold) {
File[] listing = directory.listFiles();
int numDeleted = 0;
for (File file : listing) {
if (file.isDirectory()) {
if (purgeDirectory(file, purgeThreshold)) {
numDeleted++;
}
} else if (file.lastModified() < purgeThreshold) {
if (file.delete()) {
numDeleted++;
}
}
}
// we deleted all files/directories, or there were no files in this
// directory
if (numDeleted == listing.length
&& !directory.getAbsolutePath().equals(archivePath)) {
if (directory.delete()) {
return true;
}
}
return false;
}
private Map<String, DataArchiveConfig> getDataArchiveConfigs() {
Map<String, DataArchiveConfig> configs = new HashMap<String, DataArchiveConfig>();
IPathManager pathMgr = PathManagerFactory.getPathManager();
@ -232,8 +196,6 @@ public class DataArchiver {
if (!defaultConf.isHoursToKeepSet()) {
defaultConf.setHoursToKeep(6);
} else if (defaultConf.getHoursToKeep() < 0) {
}
// override unset fields with default

View file

@ -32,6 +32,7 @@ import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import org.apache.commons.io.FileUtils;
@ -60,7 +61,9 @@ import com.raytheon.uf.common.util.TestUtil;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 7, 2013 1965 bgonzale Initial creation
* May 7, 2013 1965 bgonzale Initial creation.
* Added additional test data for file newer than purge
* time but in directory that is older than purge time.
*
* </pre>
*
@ -72,31 +75,29 @@ public class ArchiveConfigManagerTest {
private static final String RAW = "Raw";
private static final String SAT_CAT_NAME = "Satellite";
private static final String PROCESSED = "Processed";
private static final String satNameForArchive = "GOES-13";
private static final String SAT_CAT_NAME_RAW = "Satellite";
private static File TEST_DIR = TestUtil
.setupTestClassDir(ArchiveConfigManagerTest.class);
private final DateFormat yyyyMMFormat = new SimpleDateFormat("yyyyMM");
private final DateFormat yyyyFormat = new SimpleDateFormat("yyyy");
private final DateFormat MMFormat = new SimpleDateFormat("MM");
private final DateFormat ddFormat = new SimpleDateFormat("dd");
private final DateFormat hhFormat = new SimpleDateFormat("HH");
private final DateFormat kkFormat = new SimpleDateFormat("kk");
private final DateFormat mmFormat = new SimpleDateFormat("mm");
private ArchiveConfigManager manager;
private ArchiveConfig archive;
private Collection<File> archiveFiles = new ArrayList<File>();
private Collection<File> expiredFiles = new ArrayList<File>();
private Collection<File> purgeFiles = new ArrayList<File>();
private Collection<DisplayData> archiveSelectedDisplays = new HashSet<DisplayData>();
private Calendar referenceCalendar;
private Calendar archiveStart;
@ -134,55 +135,83 @@ public class ArchiveConfigManagerTest {
FileUtils.copyFileToDirectory(srcConfig, destDir);
}
manager = ArchiveConfigManager.getInstance();
archive = manager.getArchive(RAW);
ArchiveConfigManager manager = ArchiveConfigManager.getInstance();
// configure the test archive to use the test data dir
archive.setRootDir(TEST_DIR.getAbsolutePath() + "/data_store/");
ArchiveConfig archiveProcessed = manager.getArchive(PROCESSED);
archiveProcessed.setRootDir(TEST_DIR.getAbsolutePath() + "/archive/");
ArchiveConfig archiveRaw = manager.getArchive(RAW);
archiveRaw.setRootDir(TEST_DIR.getAbsolutePath() + "/data_store/");
// MessageFormat keys
// {0} yyyyMM {1} dd {2} hh {3} mm
// args:
// {0} dir-yyyy
// {1} dir-MM
// {2} dir-dd
// {3} dir-kk
// {4} file-yyyy
// {5} file-MM
// {6} file-dd
// {7} file-kk
// {8} file-mm
// **** grib1 ****
MessageFormat grib1Format = new MessageFormat(
"/grib/{0}{1}/18/NWS_160/GRID255/{2}{3}Z_F001_APCP-ZETA98_KSTR_{1}{2}{3}_125544891.grib.{0}{1}{2}");
CategoryConfig grib1Cat = getCategory(archive, "Model grib");
createTestFiles(grib1Format, getRetentionHours(archive, grib1Cat),
MessageFormat grib1Format_Raw = new MessageFormat(
"/grib/{0}{1}{2}/{3}/NWS_160/GRID255/{7}{8}Z_F001_APCP-ZETA98_KSTR_{6}{7}{8}_125544891.grib.{4}{5}{6}{7}");
createTestFiles(grib1Format_Raw, archiveRaw, "Model", false,
archiveStart, archiveEnd);
MessageFormat grib1Format_Processed = new MessageFormat(
"/grid/GFS160/BL/GFS160-{4}-{5}-{6}-{7}-FH-162.h5");
createTestFiles(grib1Format_Processed, archiveProcessed, "Model",
false, archiveStart, archiveEnd);
// **** sat ****
CategoryConfig satCat = getCategory(archive, SAT_CAT_NAME);
MessageFormat satFormat = new MessageFormat(
"/sat/{0}{1}/{2}/GOES-13/{2}{3}Z_SOUND-VIS_10km_EAST-CONUS-TIGE59_KNES_128453.satz.{0}{1}{2}");
createTestFiles(satFormat, getRetentionHours(archive, satCat), true,
MessageFormat satFormat_Raw = new MessageFormat(
"/sat/{0}{1}{2}/{3}/GOES-13/{7}{8}Z_SOUND-VIS_10km_EAST-CONUS-TIGE59_KNES_128453.satz.{4}{5}{6}{7}");
createTestFiles(satFormat_Raw, archiveRaw, SAT_CAT_NAME_RAW, true,
archiveStart, archiveEnd);
MessageFormat satFormat_Processed = new MessageFormat(
"/satellite/East CONUS/Sounder Visible imagery/satellite-{4}-{5}-{6}-{7}.h5");
createTestFiles(satFormat_Processed, archiveProcessed, "Satellite",
true, archiveStart, archiveEnd);
// **** acars ****
CategoryConfig otherCat = getCategory(archive, "Model other");
int otherCatRetentionHours = getRetentionHours(archive, otherCat);
MessageFormat acarsFormat = new MessageFormat(
"/acars/{0}{1}/{2}/IUAB01_CWAO_{1}{2}{3}_22714956.bufr.{0}{1}{2}");
createTestFiles(acarsFormat, otherCatRetentionHours, false,
MessageFormat acarsFormat_Raw = new MessageFormat(
"/acars/acars_encrypted/{0}{1}{2}/{3}/IUAB01_CWAO_{6}{7}{8}_22714956.bufr.{4}{5}{6}{7}");
createTestFiles(acarsFormat_Raw, archiveRaw, "Observation", false,
archiveStart, archiveEnd);
MessageFormat acarsFormat_Processed = new MessageFormat(
"/acars/acars-{4}-{5}-{6}-{7}.h5");
createTestFiles(acarsFormat_Processed, archiveProcessed, "Observation",
false, archiveStart, archiveEnd);
// **** binlightning ****
MessageFormat binlightningFormat = new MessageFormat(
"/binlightning/{0}{1}/{2}/SFUS41_KWBC_{1}{2}{3}_22725485.nldn.{0}{1}{2}");
createTestFiles(binlightningFormat, otherCatRetentionHours, false,
archiveStart, archiveEnd);
MessageFormat binlightningFormat_Raw = new MessageFormat(
"/binlightning/{0}{1}{2}/{3}/SFUS41_KWBC_{6}{7}{8}_22725485.nldn.{4}{5}{6}{7}");
createTestFiles(binlightningFormat_Raw, archiveRaw, "Misc",
false, archiveStart, archiveEnd);
MessageFormat binlightningFormat_Processed = new MessageFormat(
"/binlightning/binlightning-{4}-{5}-{6}-{7}.h5");
createTestFiles(binlightningFormat_Processed, archiveProcessed, "Misc",
false, archiveStart, archiveEnd);
// **** bufrsigwx ****
MessageFormat bufrsigwxFormat = new MessageFormat(
"/bufrsigwx/{0}{1}/{2}/JUWE96_KKCI_{1}{2}{3}_31368878.bufr.{0}{1}{2}");
createTestFiles(bufrsigwxFormat, otherCatRetentionHours, false,
MessageFormat bufrsigwxFormat_Raw = new MessageFormat(
"/bufrsigwx/{0}{1}{2}/{3}/JUWE96_KKCI_{6}{7}{8}_31368878.bufr.{4}{5}{6}{7}");
createTestFiles(bufrsigwxFormat_Raw, archiveRaw, "Observation", false,
archiveStart, archiveEnd);
MessageFormat bufrsigwxFormat_Processed = new MessageFormat(
"/bufrsigwx/SWH/sigwxCAT-{4}-{5}-{6}-{7}.h5");
createTestFiles(bufrsigwxFormat_Processed, archiveProcessed,
"Observation", false, archiveStart, archiveEnd);
// create test archive data dir
archiveDir = new File(TEST_DIR, TEST_ARCHIVE_DIR);
}
private int getRetentionHours(ArchiveConfig archive, CategoryConfig category) {
return category.getRetentionHours() == 0 ? archive.getRetentionHours()
return category == null || category.getRetentionHours() == 0 ? archive
.getRetentionHours()
: category.getRetentionHours();
}
@ -198,34 +227,83 @@ public class ArchiveConfigManagerTest {
return category;
}
private void createTestFiles(MessageFormat dataFileNameFormat,
int retentionHours, boolean isSelected, Calendar start, Calendar end)
throws IOException {
private void createTestFiles(MessageFormat fileNameFormat,
ArchiveConfig archive, String categoryName, boolean isSelected,
Calendar start, Calendar end) throws IOException {
CategoryConfig category = getCategory(archive, categoryName);
int retentionHours = getRetentionHours(archive, category);
String rootDir = archive.getRootDir();
// create data file newer than purge time, within archive time, and
// isSelected
File dataFile = createDataFile(end, dataFileNameFormat);
File dataFile = create_DataFile(end, fileNameFormat, rootDir);
if (isSelected) {
ArchiveConfigManager manager = ArchiveConfigManager.getInstance();
archiveFiles.add(dataFile);
archiveSelectedDisplays.addAll(manager.getDisplayData(
archive.getName(), categoryName, true));
}
System.out
.println("{newer than purge/within archive/isSelected}\n\tFor archive:"
+ archive.getName()
+ " category:"
+ categoryName
+ "\n\tcreated file: "
+ dataFile.getAbsolutePath()
.substring(rootDir.length()));
// create data file newer than purge time, within archive time, but not
// in selected
Calendar moreThanOneDayOld = (Calendar) referenceCalendar.clone();
moreThanOneDayOld.add(Calendar.DAY_OF_MONTH, -1);
createDataFile(moreThanOneDayOld, dataFileNameFormat);
dataFile = create_DataFile(moreThanOneDayOld, fileNameFormat, rootDir);
System.out
.println("{newer than purge/within archive/Not Selected}\nFor archive:"
+ archive.getName()
+ " category:"
+ categoryName
+ "\n\tcreated file: "
+ dataFile.getAbsolutePath()
.substring(rootDir.length()));
// create data file older than purge time
Calendar lessThanExpiredCalendar = (Calendar) referenceCalendar.clone();
lessThanExpiredCalendar.add(Calendar.HOUR, (-1 * retentionHours - 1));
dataFile = createDataFile(lessThanExpiredCalendar, dataFileNameFormat);
expiredFiles.add(dataFile);
dataFile = create_DataFile(lessThanExpiredCalendar, fileNameFormat,
rootDir);
purgeFiles.add(dataFile);
System.out.println("{older than purge}\nFor archive:"
+ archive.getName() + " category:" + categoryName
+ "\n\tcreated file: "
+ dataFile.getAbsolutePath().substring(rootDir.length()));
// // create data file newer than purge time, but in a directory that is
// // older than purge time, and outside of archive time frame
Calendar newerThanArchiveEnd = (Calendar) end.clone();
// newerThanArchiveEnd.add(Calendar.HOUR, 3);
// dataFile = create_DataFile(lessThanExpiredCalendar,
// newerThanArchiveEnd, fileNameFormat, rootDir);
// System.out
// .println("{newer than purge/in directory older than purge/outside of archive}\nFor archive:"
// + archive.getName()
// + " category:"
// + categoryName
// + "\n created file: " + dataFile.getAbsolutePath());
// create data file newer than purge time and outside of archive time
// frame
Calendar newerThanArchiveEnd = (Calendar) end.clone();
newerThanArchiveEnd = (Calendar) end.clone();
newerThanArchiveEnd.add(Calendar.HOUR, 3);
createDataFile(newerThanArchiveEnd, dataFileNameFormat);
dataFile = create_DataFile(newerThanArchiveEnd, fileNameFormat, rootDir);
System.out
.println("{newer than purge/outside of archive}\nFor archive:"
+ archive.getName()
+ " category:"
+ categoryName
+ "\n\tcreated file: "
+ dataFile.getAbsolutePath()
.substring(rootDir.length()));
}
private void setupTimes() {
@ -239,25 +317,40 @@ public class ArchiveConfigManagerTest {
archiveStart.add(Calendar.HOUR, -20);
archiveEnd.add(Calendar.HOUR, -3);
yyyyMMFormat.setCalendar(referenceCalendar);
yyyyFormat.setCalendar(referenceCalendar);
MMFormat.setCalendar(referenceCalendar);
ddFormat.setCalendar(referenceCalendar);
hhFormat.setCalendar(referenceCalendar);
kkFormat.setCalendar(referenceCalendar);
mmFormat.setCalendar(referenceCalendar);
}
private File createDataFile(Calendar referenceCalendar,
MessageFormat fileFormat) throws IOException {
Date referenceTime = referenceCalendar.getTime();
private File create_DataFile(Calendar referenceCalendar,
MessageFormat fileFormat, String rootDir) throws IOException {
return create_DataFile(referenceCalendar, referenceCalendar,
fileFormat, rootDir);
}
String yyyyMM = yyyyMMFormat.format(referenceTime);
String dd = ddFormat.format(referenceTime);
String hh = hhFormat.format(referenceTime);
String mm = mmFormat.format(referenceTime);
String[] formatArgs = new String[] { yyyyMM, dd, hh, mm };
private File create_DataFile(Calendar directoryReferenceCalendar,
Calendar fileReferenceCalendar, MessageFormat fileFormat,
String rootDir) throws IOException {
Date directoryReferenceTime = directoryReferenceCalendar.getTime();
Date fileReferenceTime = fileReferenceCalendar.getTime();
String dir_yyyy = yyyyFormat.format(directoryReferenceTime);
String dir_MM = MMFormat.format(directoryReferenceTime);
String dir_dd = ddFormat.format(directoryReferenceTime);
String dir_kk = kkFormat.format(directoryReferenceTime);
String file_yyyy = yyyyFormat.format(fileReferenceTime);
String file_MM = MMFormat.format(fileReferenceTime);
String file_dd = ddFormat.format(fileReferenceTime);
String file_kk = kkFormat.format(fileReferenceTime);
String file_mm = mmFormat.format(fileReferenceTime);
String[] formatArgs = new String[] { dir_yyyy, dir_MM, dir_dd, dir_kk,
file_yyyy, file_MM, file_dd, file_kk, file_mm };
String filename = fileFormat.format(formatArgs, new StringBuffer(),
new FieldPosition(0)).toString();
File resultFile = new File(archive.getRootDir(), filename);
File resultFile = new File(rootDir, filename);
String dirname = FilenameUtils
.getFullPath(resultFile.getAbsolutePath());
File dir = new File(dirname);
@ -267,13 +360,20 @@ public class ArchiveConfigManagerTest {
return resultFile;
}
private Collection<String> createFileNameListNoRootDir(File rootDir,
private Collection<String> createFileNameListRemoveTestDir(
Collection<File> files) {
List<String> result = new ArrayList<String>(files.size());
for (File f : files) {
String absPath = f.getAbsolutePath();
String fileRelativePath = absPath.replace(
rootDir.getAbsolutePath(), "");
String testDirPath = TEST_DIR.getAbsolutePath();
testDirPath = testDirPath.endsWith(File.separator) ? testDirPath
: testDirPath + File.separator;
// remove test directory path
String fileRelativePath = absPath.replace(testDirPath, "");
// remove one directory up
int index = fileRelativePath.indexOf(File.separator);
fileRelativePath = index >= 0 ? fileRelativePath.substring(index)
: fileRelativePath;
result.add(fileRelativePath);
}
Collections.sort(result);
@ -292,43 +392,39 @@ public class ArchiveConfigManagerTest {
@Test
public void testArchiveManagerCreateArchive() throws IOException,
ArchiveException {
CategoryConfig satCategory = getCategory(archive, SAT_CAT_NAME);
List<DisplayData> displays =
manager.getDisplayData(archive.getName(), satCategory.getName());
List<DisplayData> selectedDisplays = new ArrayList<DisplayData>();
for (DisplayData displayData : displays) {
if (displayData.getDisplayLabel().equals(satNameForArchive)) {
selectedDisplays.add(displayData);
}
}
Collection<File> archivedFiles = manager.createArchive(archiveDir,
selectedDisplays, archiveStart, archiveEnd);
ArchiveConfigManager manager = ArchiveConfigManager.getInstance();
Collection<File> filesInCreatedArchive = manager.createArchive(
archiveDir, archiveSelectedDisplays, archiveStart, archiveEnd);
assertEquals(
"The expected archive files and the archived files are not the same",
createFileNameListNoRootDir(new File(archive.getRootDir()),
archiveFiles),
createFileNameListNoRootDir(archiveDir, archivedFiles));
createFileNameListRemoveTestDir(archiveFiles),
createFileNameListRemoveTestDir(filesInCreatedArchive));
// check archive directory for files.
Collection<File> filesFoundInArchive = FileUtils.listFiles(archiveDir,
FileFilterUtils.trueFileFilter(),
FileFilterUtils.trueFileFilter());
assertEquals(
"The expected archive files in the files found in the archive are not the same",
archivedFiles, filesFoundInArchive);
"The archive files reported and the files found in the archive are not the same",
createFileNameListRemoveTestDir(filesInCreatedArchive),
createFileNameListRemoveTestDir(filesFoundInArchive));
}
@Test
public void testArchiveManagerPurge() throws IOException {
Collection<File> filesFoundInPurge = manager
.purgeExpiredFromArchive(archive);
// sort for comparison
List<File> purgeFilesList = new ArrayList<File>(purgeFiles);
Collections.sort(purgeFilesList);
List<File> foundFilesList = new ArrayList<File>(filesFoundInPurge);
Collections.sort(foundFilesList);
ArchiveConfigManager manager = ArchiveConfigManager.getInstance();
Collection<File> filesFoundInPurge = new ArrayList<File>();
for (ArchiveConfig a : manager.getArchives()) {
filesFoundInPurge.addAll(manager.purgeExpiredFromArchive(a));
}
assertEquals(
"The expected purge files and the files purged are not the same",
purgeFilesList, foundFilesList);
createFileNameListRemoveTestDir(purgeFiles),
createFileNameListRemoveTestDir(filesFoundInPurge));
}
}

View file

@ -1,87 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.archive;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
/**
* Test ArchiveManagerFactory.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 7, 2013 bgonzale Initial creation
*
* </pre>
*
* @author bgonzale
* @version 1.0
*/
public class ArchiveManagerFactoryTest {
/**
* @throws java.lang.Exception
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
}
/**
* Test method for {@link com.raytheon.uf.common.archive.ArchiveManagerFactory#getManager()}.
*/
@Ignore
@Test
public void testGetManagerNotNull() {
// IArchiveManager manager = ArchiveManagerFactory.getManager();
// Assert.assertNotNull("ArchiveManagerFactory returned a null manager",
// manager);
}
}