use of ca.corefacility.bioinformatics.irida.exceptions.NcbiXmlParseException in project irida by phac-nml.
the class ExportUploadService method updateRunningUploads.
/**
* Check local database for submissions which may have updates on the NCBI
* server and update them as necessary.
*/
public synchronized void updateRunningUploads() {
logger.trace("Getting running exports");
List<NcbiExportSubmission> submissionsWithState = exportSubmissionService.getSubmissionsWithState(updateableStates);
FTPClient client = null;
try {
for (NcbiExportSubmission submission : submissionsWithState) {
// connect to FTP site
client = getFtpClient();
try {
logger.trace("Getting report for submission " + submission.getId());
InputStream xmlStream = getLatestXMLStream(client, submission);
if (xmlStream != null) {
NcbiExportSubmission updateSubmissionForXml = updateSubmissionForXml(submission, xmlStream);
exportSubmissionService.update(updateSubmissionForXml);
xmlStream.close();
}
} catch (NcbiXmlParseException e) {
logger.error("Error getting response", e);
submission.setUploadState(ExportUploadState.UPLOAD_ERROR);
submission = exportSubmissionService.update(submission);
emailController.sendNCBIUploadExceptionEmail(notificationAdminEmail, e, submission.getId());
} catch (IOException e) {
logger.error("Error closing XML stream", e);
}
}
disconnectFtpCient(client);
} catch (Exception e) {
logger.error("Couldn't connect to FTP site", e);
} finally {
disconnectFtpCient(client);
}
}
use of ca.corefacility.bioinformatics.irida.exceptions.NcbiXmlParseException in project irida by phac-nml.
the class ExportUploadService method updateSubmissionForXml.
/**
* Get the updates from the result.#.xml file for the given submission and
* update the object. XML will look like the following:
*
* <pre>
* <?xml version='1.0' encoding='utf-8'?>
* <SubmissionStatus submission_id="SUB1234" status="processed-ok">
* <Action action_id="SUB1234-submission12345" target_db="SRA" status="processed-ok" notify_submitter="true">
* <Response status="processed-ok">
* <Object target_db="SRA" object_id="RUN:4567" spuid_namespace="NML" spuid="submission12345" accession="SRR6789" status="updated">
* <Meta>
* <SRAStudy>SRP012345</SRAStudy>
* </Meta>
* </Object>
* </Response>
* </Action>
* </SubmissionStatus>
* </pre>
*
* @param submission
* {@link NcbiExportSubmission} to update
* @param xml
* {@link InputStream} of xml
* @return Updated {@link NcbiExportSubmission}
* @throws NcbiXmlParseException
* if the xml couldn't be parsed
*/
private NcbiExportSubmission updateSubmissionForXml(NcbiExportSubmission submission, InputStream xml) throws NcbiXmlParseException {
try {
// read the incoming xml file
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(xml);
XPath xPath = XPathFactory.newInstance().newXPath();
// get the submission status and set it in the submission
String submissionStatusString = xPath.compile("SubmissionStatus/@status").evaluate(doc);
if (submissionStatusString == null) {
throw new NcbiXmlParseException("result file should have 1 SubmissionStatus element with a status");
}
ExportUploadState submissionStatus = ExportUploadState.fromString(submissionStatusString);
submission.setUploadState(submissionStatus);
logger.trace("Root export state is " + submissionStatus);
// get all the sample files objects by name
Map<String, NcbiBioSampleFiles> sampleMap = getSampleNameMap(submission);
// get the actions
NodeList actions = (NodeList) xPath.compile("SubmissionStatus/Action").evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < actions.getLength(); i++) {
if (actions.item(i).getNodeType() == Node.ELEMENT_NODE) {
Element action = (Element) actions.item(i);
// get the status and action id
String status = action.getAttribute("status");
String actionId = action.getAttribute("action_id");
// action id is of the form SUBMISSIONID-sampleid
String sampleId = actionId.substring(actionId.indexOf("-") + 1);
// get the sample for this action
NcbiBioSampleFiles ncbiBioSampleFiles = sampleMap.get(sampleId);
ExportUploadState sampleStatus = ExportUploadState.fromString(status);
ncbiBioSampleFiles.setSubmissionStatus(sampleStatus);
logger.trace("Sample export state for sample " + ncbiBioSampleFiles.getId() + " is " + sampleStatus);
String accession = xPath.compile("Response/Object/@accession").evaluate(action);
if (accession != null && !accession.isEmpty()) {
logger.trace("Found accession " + accession);
ncbiBioSampleFiles.setAccession(accession);
}
}
}
} catch (XPathExpressionException | ParserConfigurationException | SAXException | IOException e) {
logger.error("Couldn't parse response XML", e);
throw new NcbiXmlParseException("Error parsing NCBI response", e);
}
return submission;
}
use of ca.corefacility.bioinformatics.irida.exceptions.NcbiXmlParseException in project irida by phac-nml.
the class ExportUploadService method getLatestXMLStream.
/**
* Get the latest result.#.xml file for the given submission
*
* @param client
* {@link FTPClient} to use for the connection
* @param submission
* {@link NcbiExportSubmission} to get results for
* @return {@link InputStream} for the newest file if found. null if no file
* was found
* @throws NcbiXmlParseException
* if the file couldn't be found
*/
private InputStream getLatestXMLStream(FTPClient client, NcbiExportSubmission submission) throws NcbiXmlParseException {
InputStream retrieveFileStream = null;
try {
String directoryPath = submission.getDirectoryPath();
// cd to submission base directory
if (!client.changeWorkingDirectory(directoryPath)) {
throw new NcbiXmlParseException("Couldn't change to base directory " + baseDirectory + " : " + client.getReplyString());
}
Pattern regex = Pattern.compile("report.(\\d+).xml");
String latestFile = null;
int highestNumber = 0;
// search for the highest number in the report.#.xml files
FTPFile[] listFiles = client.listFiles();
for (FTPFile file : listFiles) {
String fileName = file.getName();
Matcher matcher = regex.matcher(fileName);
if (matcher.matches()) {
int reportNumber = Integer.parseInt(matcher.group(1));
if (reportNumber > highestNumber) {
highestNumber = reportNumber;
latestFile = fileName;
}
}
}
if (latestFile != null) {
logger.trace("newest file is " + latestFile);
retrieveFileStream = client.retrieveFileStream(latestFile);
}
} catch (IOException e) {
throw new NcbiXmlParseException("Couldn't get response xml", e);
}
return retrieveFileStream;
}
Aggregations