Exception handling

Exception handling and warning messages on Tethys transactions
This commit is contained in:
Douglas Gillespie 2023-05-07 19:00:37 +01:00
parent 71c8415bc8
commit 00410d2017
11 changed files with 326 additions and 154 deletions

View File

@ -23,6 +23,7 @@ import PamController.PamControllerInterface;
import PamController.PamSettingManager;
import PamController.PamSettings;
import PamView.PamTabPanel;
import PamView.dialog.warn.WarnOnce;
import PamguardMVC.PamDataBlock;
import metadata.MetaDataContol;
import metadata.deployment.DeploymentData;
@ -30,6 +31,7 @@ import tethys.TethysState.StateType;
import tethys.dbxml.DBXMLConnect;
import tethys.dbxml.DBXMLQueries;
import tethys.dbxml.ServerStatus;
import tethys.dbxml.TethysException;
import tethys.deployment.DeploymentHandler;
import tethys.detection.DetectionsHandler;
import tethys.niluswraps.PDeployment;
@ -507,4 +509,26 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
return detectionsHandler;
}
public void showException(TethysException tethysException) {
String title = tethysException.getMessage();
StackTraceElement[] stack = tethysException.getStackTrace();
String msg = "";
if (stack != null) {
msg = "Caused in";
for (int i = 0; i < Math.min(stack.length, 2); i++) {
msg += "<br>" + stack[i].getClassName() + "." + stack[i].getMethodName();
}
}
String xml = tethysException.getXmlError();
if (xml != null) {
// msg += "<textarea rows=\"6\" cols=\"80\" style=\"border:none;\">" + xml + "</textarea>";
xml = xml.replace("<", "&lt;");
xml = xml.replace(">", "&gt;");
xml = xml.replace("\n", "<br>");
// msg += xml;
msg += "<pre>"+xml+"</pre>";
}
WarnOnce.showWarning(title, msg, WarnOnce.WARNING_MESSAGE);
}
}

View File

@ -9,6 +9,7 @@ import java.util.ArrayList;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import tethys.dbxml.TethysException;
import tethys.niluswraps.PDeployment;
/*
@ -36,7 +37,11 @@ public class TethysMenuActions {
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
deleteDeployment(pDeployment);
} catch (TethysException e1) {
tethysControl.showException(e1);
}
}
});
menu.add(menuItem);
@ -47,7 +52,11 @@ public class TethysMenuActions {
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
deleteDeployment(pDeployment);
} catch (TethysException e1) {
tethysControl.showException(e1);
}
}
});
menu.add(menuItem);
@ -55,7 +64,7 @@ public class TethysMenuActions {
menu.show(e.getComponent(), e.getX(), e.getY());
}
protected void deleteDeployment(PDeployment pDeployment) {
protected void deleteDeployment(PDeployment pDeployment) throws TethysException {
tethysControl.getDbxmlConnect().deleteDeployment(pDeployment.deployment.getId());
}
}

View File

@ -85,6 +85,54 @@ public class DBXMLConnect {
return queries;
}
/**
* take a nilus object loaded with PamGuard data and post it to the Tethys database
*
* @param pamGuardObjs a nilus object loaded with PamGuard data
* @return error string, null string means there are no errors
* @throws TethysException
*/
public boolean postToTethys(Object nilusObject) throws TethysException
{
Class objClass = nilusObject.getClass();
String collection = getTethysCollection(objClass.getName());
TethysExportParams params = new TethysExportParams();
String importReturn = null;
String tempName = getTempFileName(nilusObject);
tempName = tempDirectory.getAbsolutePath() + File.separator + tempName + ".xml";
File tempFile = new File(tempName);
String bodgeName = tempName;//"C:\\Users\\dg50\\AppData\\Local\\Temp\\PAMGuardTethys\\Meygen2022_10a.xml";
try {
MarshalXML marshal = new MarshalXML();
marshal.createInstance(objClass);
marshal.marshal(nilusObject, tempFile.toString());
// tempFile = stripXMLHeader(tempFile);
importReturn = Importer.ImportFiles(params.getFullServerName(), collection,
new String[] { bodgeName }, "", "", false);
tempFile.deleteOnExit();
} catch(IllegalArgumentException e) {
throw new TethysException("IllegalArgumentException posting to Tethys: " + e.getMessage(), null);
} catch (IOException e) {
throw new TethysException("IOException posting to Tethys: " + e.getMessage(), null);
} catch (JAXBException e) {
throw new TethysException("JAXBException posting to Tethys: " + e.getMessage(), null);
}
/*
* The returned string consists of the file name, then an XML report.
* Quite hard to see much common structure in this, so just look for
* two words, <Success> and <Error>
*/
boolean error = importReturn.contains("<Error>");
boolean success = importReturn.contains("<Success>");
if (error) {
throw new TethysException("Error posting to Tethys", importReturn);
}
return success;
}
/**
* Update a document within Tethys. We're assuming that a
* document with the same name in the same collection already
@ -92,8 +140,9 @@ public class DBXMLConnect {
* the removedocument function
* @param nilusDocument
* @return
* @throws TethysException
*/
public String updateDocument(Object nilusDocument) {
public boolean updateDocument(Object nilusDocument) throws TethysException {
deleteDocument(nilusDocument);
return postToTethys(nilusDocument);
}
@ -104,15 +153,16 @@ public class DBXMLConnect {
* class to identify the correct collection.
* @param nilusDocument
* @return
* @throws TethysException
*/
public boolean deleteDocument(Object nilusDocument) {
public boolean deleteDocument(Object nilusDocument) throws TethysException {
Class objClass = nilusDocument.getClass();
String collection = getTethysCollection(objClass.getName());
String docId = getDocumentId(nilusDocument);
String result = null;
try {
result = jerseyClient.removeDocument(collection, docId );
result = jerseyClient.removeDocument(collection+" uio", docId );
/**
* Return from a sucessful delete is something like
*
@ -120,57 +170,73 @@ public class DBXMLConnect {
<DELETE>
<ITEM> ['ECoastNARW0'] </ITEM>
</DELETE>
An error will throw an exception.
*/
}
catch (Exception e) {
System.out.printf("Error deleting %s %s: %s\n", collection, docId, e.getMessage());
// System.out.printf("Error deleting %s %s: %s\n", collection, docId, e.getMessage());
String msg = String.format("Error deleting %s:%s", collection, docId);
throw new TethysException(msg, e.getLocalizedMessage());
}
// forceFlush();
return result == null;
return true;
}
/**
* take a nilus object loaded with PamGuard data and post it to the Tethys database
*
* @param pamGuardObjs a nilus object loaded with PamGuard data
* @return error string, null string means there are no errors
* Delete a Deploymnet and any contained Detections document. Doesn't work !
* @param deploymentId
* @return
* @throws TethysException
*/
public String postToTethys(Object nilusObject)
{
Class objClass = nilusObject.getClass();
String collection = getTethysCollection(objClass.getName());
TethysExportParams params = new TethysExportParams();
String fileError = null;
String tempName = getTempFileName(nilusObject);
tempName = tempDirectory.getAbsolutePath() + File.separator + tempName + ".xml";
File tempFile = new File(tempName);
String bodgeName = tempName;//"C:\\Users\\dg50\\AppData\\Local\\Temp\\PAMGuardTethys\\Meygen2022_10a.xml";
public boolean deleteDeployment(String deploymentId) throws TethysException {
ArrayList<String> detDocNames = tethysControl.getDbxmlQueries().getDetectionsDocuments(deploymentId);
JerseyClient jerseyClient = getJerseyClient();
Queries queries = null;
String result = null;
try {
MarshalXML marshal = new MarshalXML();
marshal.createInstance(objClass);
// Path tempFile = Files.createTempFile("pamGuardToTethys", ".xml");
marshal.marshal(nilusObject, tempFile.toString());
// tempFile = stripXMLHeader(tempFile);
fileError = Importer.ImportFiles(params.getFullServerName(), collection,
new String[] { bodgeName }, "", "", false);
// System.out.println(fileError);
tempFile.deleteOnExit();
} catch(IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
result = jerseyClient.removeDocument("Deployments", deploymentId );
}
System.out.println(fileError);
return fileError;
catch (Exception e) {
throw new TethysException("Error deleting deployment document " + deploymentId, e.getMessage());
}
return true;
}
/**
* check the return string from importFiles and if it's an
* error, throw an exception. Otherwise do nothing.
* @param fileError
*/
private void checkReturnString(String fileError) {
/**
* Example good string is
*
C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xml: 7360 bytes
<?xml version="1.0" encoding="iso-8859-1"?>
<Import>
<Document name="20080311_2DSimplex_0">added</Document>
<SummaryReport>
<Success>
<Document>20080311_2DSimplex_0</Document>
</Success>
</SummaryReport>
</Import>
Example error (file not existing)
C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xmlnot: 0 bytes
<Error>
<File>
<Name>C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xmlnot</Name>
<Cause> does not exist </Cause>
</File>
</Error>
*/
}
/**
* Seems we have to get rid of the line <?xml version="1.0" encoding="UTF-8"?>
@ -332,40 +398,6 @@ public class DBXMLConnect {
}
}
/**
* Delete a Deploymnet and any contained Detections document. Doesn't work !
* @param deploymentId
* @return
*/
public boolean deleteDeployment(String deploymentId) {
ArrayList<String> detDocNames = tethysControl.getDbxmlQueries().getDetectionsDocuments(deploymentId);
JerseyClient jerseyClient = getJerseyClient();
Queries queries = null;
String result;
// for (int i = 0; i < detDocNames.size(); i++) {
// try {
// System.out.println("Delete " + detDocNames.get(i));
// result = jerseyClient.removeDocument("Detections", detDocNames.get(i));
// }
// catch (Exception e) {
// e.printStackTrace();
//// return false;
//// break;
// }
// }
try {
// String doc = queries.getDocument("Deployments", deploymentId);
// queries.
result = jerseyClient.removeDocument("Deployments", deploymentId );
}
catch (Exception e) {
// e.printStackTrace();
return false;
}
return true;
}
public synchronized boolean openConnections() {
TethysExportParams params = tethysControl.getTethysExportParams();
currentSiteURL = params.getFullServerName();

View File

@ -54,8 +54,9 @@ public class DBXMLQueries {
* Or will return null if the server is not connected
* @param jsonQueryString
* @return query result
* @throws TethysQueryException
*/
private DBQueryResult executeQuery(String jsonQueryString) {
private DBQueryResult executeQuery(String jsonQueryString) throws TethysQueryException {
long t1 = System.currentTimeMillis();
@ -73,14 +74,15 @@ public class DBXMLQueries {
JerseyClient jerseyClient = dbxmlConnect.getJerseyClient();
// String url = jerseyClient.getURL();
Queries queries = new Queries(jerseyClient);
// Queries queries = new Queries(jerseyClient);
queryResult = jerseyClient.queryJSON(jsonQueryString, 0);
schemaPlan = jerseyClient.queryJSON(jsonQueryString, 1);
}
catch (Exception e) {
return new DBQueryResult(System.currentTimeMillis()-t1, e);
// return new DBQueryResult(System.currentTimeMillis()-t1, e);
throw new TethysQueryException("Error running JSON query", jsonQueryString);
}
return new DBQueryResult(System.currentTimeMillis()-t1, queryResult, schemaPlan);
@ -90,7 +92,13 @@ public class DBXMLQueries {
String projectQuery = "{\"return\":[\"Deployment/Project\"],\"select\":[],\"enclose\":1}";
DBQueryResult result = executeQuery(projectQuery);
DBQueryResult result;
try {
result = executeQuery(projectQuery);
} catch (TethysQueryException e) {
tethysControl.showException(e);
return null;
}
if (result == null || result.queryResult == null) {
return null;
@ -161,7 +169,12 @@ public class DBXMLQueries {
String qBase = "{\"return\":[\"Deployment\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/Project\",\"%s\"],\"optype\":\"binary\"}],\"enclose\":1}";
String qStr = String.format(qBase, projectName);
DBQueryResult result = executeQuery(qStr);
DBQueryResult result = null;
try {
result = executeQuery(qStr);
} catch (TethysQueryException e1) {
tethysControl.showException(e1);
}
if (result == null) {
return null;
}
@ -253,7 +266,13 @@ public class DBXMLQueries {
query = queryWithDepl.replace("TheDeploymentId", deploymentId);
}
query = query.replace("LongDataName", dataBlock.getLongDataName());
DBQueryResult queryResult = executeQuery(query);
DBQueryResult queryResult = null;
try {
queryResult = executeQuery(query);
} catch (TethysQueryException e1) {
tethysControl.showException(e1);
return null;
}
if (queryResult ==null) {
return null;
}
@ -289,7 +308,13 @@ public class DBXMLQueries {
public ArrayList<String> getDetectionsDocuments(String deploymentId) {
String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"SomeDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}";
String queryStr = queryBase.replace("SomeDeploymentId", deploymentId);
DBQueryResult queryResult = executeQuery(queryStr);
DBQueryResult queryResult = null;
try {
queryResult = executeQuery(queryStr);
} catch (TethysQueryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (queryResult == null || queryResult.queryException != null) {
return null;
}
@ -461,7 +486,13 @@ public class DBXMLQueries {
private int[] countDataForDeployment(String projectId, String deploymentId, String[] dataPrefixes) {
String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\",\"Detections/OnEffort/Detection/Start\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"ReplaceDeploymentIdString\"],\"optype\":\"binary\"}],\"enclose\":1}";
String queryString = queryBase.replace("ReplaceDeploymentIdString", deploymentId);
DBQueryResult result = executeQuery(queryString);
DBQueryResult result;
try {
result = executeQuery(queryString);
} catch (TethysQueryException e) {
tethysControl.showException(e);
return null;
}
if (result == null || result.queryResult == null) {
return null;
}
@ -560,7 +591,13 @@ public class DBXMLQueries {
public Detections getDetectionsDocInfo(String detectionsDocName) {
String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\",\"Detections/Description\",\"Detections/DataSource\",\"Detections/Algorithm\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Id\",\"DetectionsDocName\"],\"optype\":\"binary\"}],\"enclose\":1}";
String query = queryBase.replace("DetectionsDocName", detectionsDocName);
DBQueryResult queryResult = executeQuery(query);
DBQueryResult queryResult;
try {
queryResult = executeQuery(query);
} catch (TethysQueryException e) {
tethysControl.showException(e);
return null;
}
Document doc;
try {
doc = queryResult.getDocument();

View File

@ -0,0 +1,18 @@
package tethys.dbxml;
public class TethysException extends Exception {
private static final long serialVersionUID = 1L;
private String xmlError;
public TethysException(String message, String xmlError) {
super(message);
this.xmlError = xmlError;
}
public String getXmlError() {
return xmlError;
}
}

View File

@ -0,0 +1,16 @@
package tethys.dbxml;
public class TethysQueryException extends TethysException {
private String queryString;
public TethysQueryException(String message, String queryString) {
super(message, null);
this.queryString = queryString;
}
public String getQueryString() {
return queryString;
}
}

View File

@ -27,6 +27,7 @@ import PamController.PamControlledUnit;
import PamController.PamController;
import PamUtils.LatLong;
import PamUtils.PamUtils;
import PamView.dialog.warn.WarnOnce;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamRawDataBlock;
import binaryFileStorage.BinaryStore;
@ -59,6 +60,7 @@ import tethys.TethysStateObserver;
import tethys.TethysTimeFuncs;
import tethys.TethysState.StateType;
import tethys.dbxml.DBXMLConnect;
import tethys.dbxml.TethysException;
import tethys.niluswraps.PDeployment;
import tethys.output.TethysExportParams;
@ -311,6 +313,7 @@ public class DeploymentHandler implements TethysStateObserver {
}
DBXMLConnect dbxmlConnect = getTethysControl().getDbxmlConnect();
PDeployment exDeploymnet = onePeriod.getMatchedTethysDeployment();
try {
if (exDeploymnet != null) {
deployment.setId(exDeploymnet.deployment.getId());
dbxmlConnect.updateDocument(deployment);
@ -318,6 +321,10 @@ public class DeploymentHandler implements TethysStateObserver {
else {
dbxmlConnect.postToTethys(deployment);
}
}
catch (TethysException e) {
getTethysControl().showException(e);
}
getTethysControl().sendStateUpdate(new TethysState(StateType.UPDATESERVER));
}
@ -344,6 +351,7 @@ public class DeploymentHandler implements TethysStateObserver {
deployment.setSite(globalMeta.getSite());
// also need to sort out track data here, etc.
DBXMLConnect dbxmlConnect = getTethysControl().getDbxmlConnect();
try {
if (exDeploymnet != null) {
dbxmlConnect.updateDocument(deployment);
}
@ -351,6 +359,10 @@ public class DeploymentHandler implements TethysStateObserver {
dbxmlConnect.postToTethys(deployment);
}
}
catch (TethysException e) {
getTethysControl().showException(e);
}
}
getTethysControl().sendStateUpdate(new TethysState(StateType.UPDATESERVER));
}

View File

@ -34,6 +34,7 @@ import tethys.deployment.DeploymentHandler;
import tethys.TethysStateObserver;
import tethys.TethysTimeFuncs;
import tethys.dbxml.DBXMLConnect;
import tethys.dbxml.TethysException;
import tethys.detection.DetectionGranularity.GRANULARITY;
import tethys.niluswraps.PDeployment;
import tethys.niluswraps.PDetections;
@ -434,7 +435,11 @@ public class DetectionsHandler {
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_WRITING);
exportObserver.update(prog);
closeDetectionsDocument(currentDetections, mapPoint.getEndTime());
try {
dbxmlConnect.postToTethys(currentDetections);
} catch (TethysException e) {
tethysControl.showException(e);
}
currentDetections = null;
}
}
@ -443,7 +448,11 @@ public class DetectionsHandler {
prog = new DetectionExportProgress(deployment, currentDetections,
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_WRITING);
closeDetectionsDocument(currentDetections, deployment.getAudioEnd());
try {
dbxmlConnect.postToTethys(currentDetections);
} catch (TethysException e) {
tethysControl.showException(e);
}
currentDetections = null;
}
}

View File

@ -32,6 +32,7 @@ import metadata.deployment.DeploymentData;
import nilus.Deployment;
import tethys.TethysControl;
import tethys.dbxml.DBXMLConnect;
import tethys.dbxml.TethysException;
import tethys.deployment.DeploymentHandler;
import tethys.deployment.DeploymentOverview;
import tethys.deployment.DeploymentRecoveryPair;
@ -189,7 +190,11 @@ public class TethysExporter {
Deployment deployment = deploymentHandler.createDeploymentDocument(i++, recordingPeriod);
// System.out.println(deployment.toString());
deploymentDocs.add(deployment);
try {
tethysControl.getDbxmlConnect().postToTethys(deployment);
} catch (TethysException e) {
tethysControl.showException(e);
}
}

View File

@ -20,6 +20,7 @@ import PamView.tables.SwingTableColumnWidths;
import PamguardMVC.PamDataBlock;
import nilus.Detections;
import tethys.TethysControl;
import tethys.dbxml.TethysException;
import tethys.detection.StreamDetectionsSummary;
import tethys.niluswraps.PDetections;
@ -117,7 +118,11 @@ public class DatablockDetectionsPanel extends TethysGUIPanel implements StreamTa
}
protected void deleteDocument(PDetections pDets) {
try {
getTethysControl().getDbxmlConnect().deleteDocument(pDets.detections);
} catch (TethysException e) {
getTethysControl().showException(e);
}
selectDataBlock(dataBlock); // force table update.
}

View File

@ -28,6 +28,7 @@ import nilus.Deployment;
import tethys.TethysControl;
import tethys.TethysState;
import tethys.TethysState.StateType;
import tethys.dbxml.TethysException;
import tethys.deployment.DeploymentHandler;
import tethys.deployment.DeploymentOverview;
import tethys.deployment.RecordingPeriod;
@ -164,7 +165,11 @@ public class PAMGuardDeploymentsTable extends TethysGUIPanel {
if (ans == WarnOnce.CANCEL_OPTION) {
return;
}
try {
boolean gone = getTethysControl().getDbxmlConnect().deleteDocument(dep);
} catch (TethysException e) {
getTethysControl().showException(e);
}
getTethysControl().sendStateUpdate(new TethysState(StateType.UPDATESERVER));
}