package gov.nih.ncgc.bard.capextract;
//import gov.nih.ncgc.bard.capextract.handler.AssayHandler;
//import gov.nih.ncgc.bard.capextract.handler.AssaysHandler;
import gov.nih.ncgc.bard.capextract.CAPConstants.CapResource;
import gov.nih.ncgc.bard.capextract.handler.AssayHandler;
import gov.nih.ncgc.bard.capextract.handler.AssaysHandler;
import gov.nih.ncgc.bard.capextract.handler.BardexportHandler;
import gov.nih.ncgc.bard.capextract.handler.DictionaryHandler;
import gov.nih.ncgc.bard.capextract.handler.ExperimentHandler;
import gov.nih.ncgc.bard.capextract.handler.ExperimentResultHandler;
import gov.nih.ncgc.bard.capextract.handler.ExperimentsHandler;
import gov.nih.ncgc.bard.capextract.handler.ExternalReferenceHandler;
import gov.nih.ncgc.bard.capextract.handler.ExternalSystemHandler;
import gov.nih.ncgc.bard.capextract.handler.ProjectDocHandler;
import gov.nih.ncgc.bard.capextract.handler.ProjectHandler;
import gov.nih.ncgc.bard.capextract.handler.ProjectsHandler;
import gov.nih.ncgc.bard.capextract.handler.ResultHandler;
import gov.nih.ncgc.bard.capextract.jaxb.Link;
import gov.nih.ncgc.bard.capextract.jaxb.Projects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
/**
* Example code to play with the Broad CAP Data Export API.
* <p/>
* CAP data export API defined at <a href="https://github.com/broadinstitute/BARD/wiki/BARD-Data-Export-API">
* https://github.com/broadinstitute/BARD/wiki/BARD-Data-Export-API</a>. This class is primarily a driver
* and all the details of individual entities coming from the CAP are processed by individual handlers
* (such as {@link ProjectHandler}, {@link AssayHandler}, etc.). Depending on the nature of the entity, a
* handler may handle just the entity and invoke a different handler for its child entities, or else may
* choose to handle all the child entities.
*
* @author Rajarshi Guha
* @see CapResourceHandlerRegistry
* @see DictionaryHandler
* @see BardexportHandler
* @see AssayHandler
* @see AssaysHandler
* @see ProjectHandler
* @see ProjectsHandler
*/
public class CAPExtractor {
private CapResourceHandlerRegistry registry;
private Logger log;
public CAPExtractor() {
log = LoggerFactory.getLogger(this.getClass());
}
public <T> int getRelatedCount(Vector<T> vec) {
int count = 0;
if (vec == null) return count;
for (T t : vec) {
try {
Method getLinkList = t.getClass().getMethod("getLink", (Class<?>[]) null);
@SuppressWarnings("unchecked")
List<Link> links = (List<Link>) getLinkList.invoke(t, (Object[]) null);
for (Link link : links)
if (link.getRel().equals("related"))
count++;
} catch (Exception e) {
;
}
}
return count;
}
public void run() throws IOException, NoSuchAlgorithmException {
ICapResourceHandler bardExportHandler = registry.getHandler(CAPConstants.CapResource.BARDEXPORT);
//process all entities under the root
bardExportHandler.process(CAPConstants.getCAPRoot(), CAPConstants.CapResource.BARDEXPORT);
//set global bard update time
bardExportHandler.updateGlobalBardUpdateTime();
//signal to flush cache
bardExportHandler.signalFlushRestCache();
}
public void poll() throws IOException {
Logger log = LoggerFactory.getLogger(this.getClass());
Vector<Projects> projects = registry.getHandler(CAPConstants.CapResource.PROJECTS).
poll(CAPConstants.getCAPRoot() + "/projects", CAPConstants.CapResource.PROJECTS);
log.info("Project count: " + projects.get(0).getCount().toString());
// each project is obtained via a link
for (Projects aProjects : projects) {
List<Link> projectLinks = aProjects.getLink();
for (Link projectLink : projectLinks) {
CAPConstants.CapResource res = CAPConstants.getResource(projectLink.getType());
if (res == CAPConstants.CapResource.PROJECT) {
ICapResourceHandler handler = CapResourceHandlerRegistry.getInstance().getHandler(res);
handler.process(projectLink.getHref(), res);
}
}
}
}
// To do a test for a specific assay id, first mark it as READY
// AssayHandler h = new AssayHandler();
// h.setExtractionStatus("Ready", "https://bard.broadinstitute.org/dataExport/api/assays/1587",CAPConstants.CapResource.ASSAY);
public void setHandlers() {
registry = CapResourceHandlerRegistry.getInstance();
registry.setHandler(CAPConstants.CapResource.PROJECTS, new ProjectsHandler());
registry.setHandler(CAPConstants.CapResource.PROJECT, new ProjectHandler());
registry.setHandler(CAPConstants.CapResource.PROJECTDOC, new ProjectDocHandler());
registry.setHandler(CAPConstants.CapResource.ASSAYS, new AssaysHandler());
registry.setHandler(CAPConstants.CapResource.ASSAY, new AssayHandler());
registry.setHandler(CAPConstants.CapResource.EXPERIMENTS, new ExperimentsHandler());
registry.setHandler(CAPConstants.CapResource.EXPERIMENT, new ExperimentHandler());
registry.setHandler(CAPConstants.CapResource.RESULT, new ResultHandler());
registry.setHandler(CAPConstants.CapResource.BARDEXPORT, new BardexportHandler());
registry.setHandler(CAPConstants.CapResource.DICTIONARY, new DictionaryHandler());
registry.setHandler(CAPConstants.CapResource.EXTREF, new ExternalReferenceHandler());
registry.setHandler(CAPConstants.CapResource.EXTSYS, new ExternalSystemHandler());
registry.setHandler(CAPConstants.CapResource.RESULT_JSON, new ExperimentResultHandler());
// registry.setHandler(CAPConstants.CapResource.RESULTS, new ResultsHandler());
}
public boolean evaluateAndSetLoadLockState(String lockFilePath, boolean lock) throws IOException {
boolean load = false;
log.info("Checking and setting load lock file: "+lockFilePath);
Properties loadProps = new Properties();
FileReader fr = new FileReader(lockFilePath);
loadProps.load(fr);
fr.close();
if(loadProps.getProperty("load.state").equals("IDLE")) {
//if idle and want to set the lock, set state to LOADING
if(lock) {
loadProps.setProperty("load.state", "LOADING");
FileWriter writer = new FileWriter(lockFilePath);
loadProps.store(writer, "Load State");
writer.close();
load = true;
log.info("STARTING LOAD. Setting load state to LOADING.");
}
} else {
//load state is LOADING
//if trying to lock, return false to indicate existing load holds the lock
if(lock) {
load = false;
log.info("ABORTING LOAD, another load process is in progress.");
} else {
//if not locking, then the intention is to unlock, set state back to IDLE
loadProps.setProperty("load.state", "IDLE");
FileWriter writer = new FileWriter(lockFilePath);
loadProps.store(writer, "Load State");
writer.close();
load = true;
log.info("FINISHED LOAD, setting load state to IDLE.");
}
}
return load;
}
public void updateGlobalBardUpdateTime() {
ICapResourceHandler bardExportHandler = registry.getHandler(CAPConstants.CapResource.BARDEXPORT);
bardExportHandler.updateGlobalBardUpdateTime();
}
public CapResourceHandlerRegistry getRegistry() {
return registry;
}
public static void main(String[] args) throws Exception {
CAPExtractor c = new CAPExtractor();
// make sure we have a load state lock file path, or exit
// if(args.length == 0) {
// System.err.println("LOAD Terminatd: Process requires a load state lock file path to determine if a load is in progress.");
// System.err.println("USAGE: java -cp <lib-path> -Xmx<mem-alloc> -DCAP_API_KEY=<api-key> -DBARD_SCRATCH_DIR=<scratch-dir-path> -DBARD_DB_URL=<db-url> gov.nih.ncgc.bard.capextract.CAPExtractor <load-state-file-path>");
// System.err.println("The load state file is a text properties file with a single property load.state:<IDLE|LOADING>");
// System.exit(1);
// }
// check the load state and begin load
try {
// returns true if state was IDLE and the lock is set and state set to LOADING, Ready to load
if(c.evaluateAndSetLoadLockState(args[0], true)) {
// if (true) {
// before running the extractor, lets set our handlers
c.setHandlers();
// lets start pulling
c.run();
// set the load state back to IDLE at the end of the load
c.evaluateAndSetLoadLockState(args[0], false);
}
} catch (Exception e) {
//signal flush when fall out
c.getRegistry().getHandler(CapResource.BARDEXPORT).signalFlushRestCache();
//need to set the global update time in the DB IF we fall out of the load wit error/exception!
c.updateGlobalBardUpdateTime();
// on any terminal error set load state to IDLE
c.evaluateAndSetLoadLockState(args[0], false);
e.printStackTrace();
}
}
}