thredds.inventory.CollectionManager Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata
* See LICENSE for license information.
*/
package thredds.inventory;
import ucar.nc2.units.TimeDuration;
import java.io.IOException;
/**
* Manages a dynamic collection of MFile objects.
* You must call scan() first.
* This is the older stuff used by FMRC. GRIB uses lighter weight MCollection.
*
* An MFile must have the property that
*
*
* NetcdfDatasets.open(MFile.getPath, ...);
*
*
* should work.
*
*
* A CollectionManager implements the element.
*
* collection element
*
* A collection element defines the collection of datasets.
*
*
*
* <collection spec="/data/ldm/pub/native/satellite/3.9/WEST-CONUS_4km/WEST-CONUS_4km_3.9_#yyyyMMdd_HHmm#.gini$"
name="WEST-CONUS_4km" olderThan="1 min" olderThan="15 min" />
*
*
* The XML Schema:
*
*
<xsd:complexType name="collectionType">
1) <xsd:attribute name="spec" type="xsd:string" use="required"/>
2) <xsd:attribute name="name" type="xsd:token"/>
3) <xsd:attribute name="olderThan" type="xsd:string" />
5) <xsd:attribute name="dateFormatMark" type="xsd:string"/>
6) <xsd:attribute name="timePartition" type="xsd:string"/>
</xsd:complexType>
*
*
* where
*
*
* - spec: collection specification string
* (required).
* - name: collection name must be unique in all of your TDS catalogs.
* This is used for external triggers and as an easy to read identifier for indexing, logging and debugging.
* If missing, the spec string is used (not a good idea in the context of the TDS).
* - olderThan (optional): Only files whose lastModified date is older than this are included.
* This excludes files that are in the process of being written. However, it only applies to newly found files, that is,
* once a file is in the collection it is not removed because it got updated.
* - dateFormatMark (optional): the collection specification string can only extract dates from the
* file name,
* as opposed to the file path, which includes all of the parent directory names. Use the dateFormatMark in
* order to extract
* the date from the full path. Use this OR a date extrator in the specification string, but not both.
* - timePartition (optional):: experimental, not complete yet.
*
*
* @author caron
* @since Jan 19, 2010
*/
public interface CollectionManager extends MCollection {
/**
* static means doesnt need to be monitored for changes; can be externally triggered, or read in at startup.
* true if no recheckAfter and no update.rescan
*
* @return if static
*/
boolean isStatic();
/**
* Get the last time scanned
*
* @return msecs since 1970
*/
long getLastScanned();
/**
* Get the last time the collection changed
*
* @return msecs since 1970
*/
long getLastChanged();
/**
* Get how often to rescan
*
* @return time duration of rescan period, or null if none.
*/
TimeDuration getRecheck();
/**
* Compute whether rescan is needed, based on getRecheck(), and the LastScanned value.
*
* @return true if rescan is needed.
*/
boolean isScanNeeded();
/**
* If isScanNeeded(), do a scan. Do not send an event.
*
* @return true if scan was done, and anything changed.
* @throws IOException on io error
*/
boolean scanIfNeeded() throws IOException;
/**
* Scan the collection. Files may have been deleted or added since last time.
* If the MFile already exists in the current list, leave it in the list.
* If anything changes, send TriggerEvent(TriggerType.update) and return true
* Get the results from getFiles()
*
* @return true if anything actually changed.
* @throws IOException on I/O error
*/
boolean scan(boolean sendEvent) throws IOException;
/**
* Register to get Trigger events
*
* @param l listener
*/
void addEventListener(TriggerListener l);
void removeEventListener(TriggerListener l);
////////////////////////////////////////////////////
// set Strategy for checking if MFile has changed
interface ChangeChecker {
boolean hasChangedSince(MFile file, long when);
boolean hasntChangedSince(MFile file, long when);
}
/**
* A TriggerEvent.proto is sent if protoDataset.change = "cron" has been specified
* A TriggerEvent.update is sent if a scan has happened and a change in the list of MFiles has occurred,
* or an MFile has been updated
*/
interface TriggerListener {
void handleCollectionEvent(TriggerEvent event);
}
class TriggerEvent extends java.util.EventObject {
private final CollectionUpdateType type;
TriggerEvent(Object source, CollectionUpdateType type) {
super(source);
this.type = type;
}
public CollectionUpdateType getType() {
return type;
}
@Override
public String toString() {
return "TriggerEvent{" + "type='" + type + '\'' + '}';
}
}
}