Skip to content

Commit

Permalink
Further improve stability of Nahima Export
Browse files Browse the repository at this point in the history
  • Loading branch information
GenieTim committed Sep 28, 2021
1 parent 66fcd40 commit c825449
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 36 deletions.
75 changes: 51 additions & 24 deletions src/main/java/edu/harvard/mcz/imagecapture/data/NahimaManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class NahimaManager extends AbstractRestClient {
private final String username;
private final String password;
private String token;
private final Map<String, Map<String, JSONObject>> resolveCache = new HashMap<String, Map<String, JSONObject>>();
private final Map<String, Map<String, JSONObject>> resolveCache = new HashMap<>();

public NahimaManager(String url, String username, String password) throws IOException, InterruptedException, RuntimeException {
// normalize URL
Expand All @@ -44,9 +44,13 @@ public NahimaManager(String url, String username, String password) throws IOExce
this.login();
}

/**
* Start a Nahima session
*
*/
protected void startSessionAndRetrieveToken() throws RuntimeException {
String queryUrl = this.url + "session";
Collection<String> params = new HashSet<String>();
Collection<String> params = new HashSet<>();
params.add("token");
this.token = (String) this.fetchValues(queryUrl, params).get("token");

Expand All @@ -55,6 +59,10 @@ protected void startSessionAndRetrieveToken() throws RuntimeException {
}
}

/**
* Do login to Nahima
*
*/
protected void login() throws IOException, InterruptedException, RuntimeException {
String queryUrl = this.url + "session/authenticate?method=easydb&token=" + this.token;
HashMap<String, String> params = new HashMap<>();
Expand All @@ -71,6 +79,12 @@ protected void login() throws IOException, InterruptedException, RuntimeExceptio
}
}

/**
* This function loops the images in a Specimen and uploads them to Nahima
*
* @param specimen the specimen whose images to upload
* @return the created mediassets
*/
public Object[] uploadImagesForSpecimen(Specimen specimen) throws IOException, InterruptedException, RuntimeException {
// docs:
// https://docs.easydb.de/en/technical/api/eas/
Expand Down Expand Up @@ -104,6 +118,13 @@ public Object[] uploadImagesForSpecimen(Specimen specimen) throws IOException, I
return results.toArray();
}

/**
* Run the query to create an object in Nahima
*
* @param object the object to create
* @param pool the pool to create the object in
* @return the created object as it is in Nahima
*/
public JSONObject createObjectInNahima(JSONObject object, String pool) throws IOException, InterruptedException {
// docs:
// https://docs.easydb.de/en/technical/api/db/
Expand Down Expand Up @@ -132,8 +153,6 @@ public JSONObject createObjectInNahima(JSONObject object, String pool) throws IO
* @param searchMode e.g. "fulltext", "token", ...
* @param ignoreCache cache speeds things up, but is annoying when we just created a new object
* @return Nahima's response
* @throws IOException
* @throws InterruptedException
*/
public JSONObject searchForString(String searchString, String objectType, String searchMode, boolean ignoreCache) throws IOException, InterruptedException {
// check cache for results
Expand Down Expand Up @@ -161,6 +180,7 @@ public JSONObject searchForString(String searchString, String objectType, String

JSONObject superSearch = new JSONObject();
superSearch.put("search", search);
superSearch.put("type", "complex");
JSONArray superSuperSearch = new JSONArray();
superSuperSearch.put(superSearch);
JSONObject query = new JSONObject();
Expand Down Expand Up @@ -197,12 +217,19 @@ public JSONObject searchForString(String searchString, String objectType, boolea
* @param search the string to search for
* @param objectType the object type that is searched
* @return the object if there is only one, null if not
* @throws IOException
* @throws InterruptedException
*/
public JSONObject resolveStringSearchToOne(String search, String objectType) throws IOException, InterruptedException {
if (search == null || objectType == null) {
log.warn("Cannot search as search " + search + " or objectType " + objectType + " is null");
return null;
}

JSONObject results = this.searchForString(search, objectType);

if (results.has("code") && results.getString("code").startsWith("error")) {
throw new RuntimeException("Failed to resolve search. Error code: " + results.getString("code"));
}

JSONArray foundObjects = (JSONArray) results.get("objects");
if (foundObjects.length() == 1) {
return (JSONObject) foundObjects.get(0);
Expand All @@ -217,14 +244,14 @@ public JSONObject resolveStringSearchToOne(String search, String objectType) thr
* Find a person in Nahima
*
* @param personName the name to search for
* @return
* @throws IOException
* @throws InterruptedException
*/
public JSONObject resolvePerson(String personName) throws IOException, InterruptedException {
JSONObject results = this.resolveStringSearchToOne(personName, "person");
// TODO: check compliance, does it really match well? We use "must", so let's hope so, but the resolution could still go wrong.
// TODO: create / select correct
if (results == null) {
// TODO: create
}
return results;
}

Expand All @@ -233,12 +260,13 @@ public JSONObject resolvePerson(String personName) throws IOException, Interrupt
*
* @param location the search string
* @return the nahima returned object if only one
* @throws IOException
* @throws InterruptedException
*/
public JSONObject resolveLocation(String location) throws IOException, InterruptedException {
JSONObject results = this.resolveStringSearchToOne(location, "gazetteer");
// TODO: create / select correct
if (results == null) {
// TODO: create
}
return results;
}

Expand All @@ -247,12 +275,13 @@ public JSONObject resolveLocation(String location) throws IOException, Interrupt
*
* @param status the search string
* @return the nahima returned object if only one
* @throws IOException
* @throws InterruptedException
*/
public JSONObject resolveTypeStatus(String status) throws IOException, InterruptedException {
JSONObject results = this.resolveStringSearchToOne(status, "typusstatus");
// TODO: create / select correct
if (results == null) {
// TODO: create
}
return results;
}

Expand All @@ -261,13 +290,13 @@ public JSONObject resolveTypeStatus(String status) throws IOException, Interrupt
*
* @param unit the unit to find in Nahima
* @param unitSubject the unit type
* @return
* @throws IOException
* @throws InterruptedException
*/
public JSONObject resolveUnitFor(String unit, String unitSubject) throws IOException, InterruptedException {
JSONObject results = this.resolveStringSearchToOne(unit, unitSubject);
// TODO: create / select correct
if (results == null) {
// TODO: create
}
return results;
}

Expand All @@ -276,8 +305,6 @@ public JSONObject resolveUnitFor(String unit, String unitSubject) throws IOExcep
*
* @param unit the search string
* @return the nahima returned object if only one
* @throws IOException
* @throws InterruptedException
*/
public JSONObject resolveUnitForHeight(String unit) throws IOException, InterruptedException {
return resolveUnitFor(unit, "einheitenfuerhoehe");
Expand All @@ -288,8 +315,6 @@ public JSONObject resolveUnitForHeight(String unit) throws IOException, Interrup
*
* @param unit the search string
* @return the nahima returned object if only one
* @throws IOException
* @throws InterruptedException
*/
public JSONObject resolveUnitForErrorRadius(String unit) throws IOException, InterruptedException {
return resolveUnitFor(unit, "einheitenfuerdenfehlerradius");
Expand All @@ -300,8 +325,6 @@ public JSONObject resolveUnitForErrorRadius(String unit) throws IOException, Int
*
* @param format the datum to search for
* @return the nahima returned object if only one
* @throws IOException
* @throws InterruptedException
*/
public JSONObject resolveDatumFormat(String format) throws IOException, InterruptedException {
JSONObject results = this.searchForString(format, "datumsformate", "token");
Expand All @@ -321,12 +344,13 @@ public JSONObject resolveDatumFormat(String format) throws IOException, Interrup
*
* @param method the collection method to search for
* @return the nahima returned object if only one
* @throws IOException
* @throws InterruptedException
*/
public JSONObject resolveCollectionMethod(String method) throws IOException, InterruptedException {
JSONObject results = this.resolveStringSearchToOne(method, "sammlungsmethoden");
// TODO: create / select correct
if (results == null) {
// TODO: create
}
return results;
}

Expand All @@ -338,6 +362,9 @@ public JSONObject resolveCollectionMethod(String method) throws IOException, Int
* @return the reduced associate, ideal to reference on creation
*/
public JSONObject reduceAssociateForAssociation(JSONObject associate) {
if (associate == null) {
return null;
}
JSONObject reduced = new JSONObject();
String[] namesToKeep = {"_objecttype", "_mask", "_global_object_id"};
for (String name : namesToKeep) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ public void start() {
specimen.setNahimaExported(true);
try {
sls.attachDirty(specimen);
sls.persist(specimen);
} catch (SaveFailedException | SpecimenExistsException e) {
} catch (SaveFailedException e) {
lastError = e;
log.error("Failed to store Nahima export status", e);
this.status = STATUS_DATASHOT_FAILED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,18 @@ public JSONObject serialize2JSON(Object target) {
log.error("Failed to resolve unit", e);
}

try {
reverseNestedCollection.put("einheitdesfehlerradius", nahimaManager.reduceAssociateForAssociation(nahimaManager.resolveUnitForErrorRadius(georef.getMaxErrorUnits())));
} catch (IOException | InterruptedException e) {
log.error("Failed to resolve unit", e);
}
if (georef != null) {
try {
reverseNestedCollection.put("einheitdesfehlerradius", nahimaManager.reduceAssociateForAssociation(nahimaManager.resolveUnitForErrorRadius(georef.getMaxErrorUnits())));
} catch (IOException | InterruptedException e) {
log.error("Failed to resolve unit", e);
}

try {
reverseNestedCollection.put("datumsformatgeodaeischeskooordinatensystem", nahimaManager.reduceAssociateForAssociation(nahimaManager.resolveDatumFormat(georef.getDatum())));
} catch (IOException | InterruptedException e) {
log.error("Failed to resolve date format", e);
try {
reverseNestedCollection.put("datumsformatgeodaeischeskooordinatensystem", nahimaManager.reduceAssociateForAssociation(nahimaManager.resolveDatumFormat(georef.getDatum())));
} catch (IOException | InterruptedException e) {
log.error("Failed to resolve date format", e);
}
}

try {
Expand Down Expand Up @@ -203,7 +205,6 @@ public JSONObject serialize2JSON(Object target) {
}
result.put("_nested:entomologie__praeparatteile", parts);


// TODO: other fields

// finally, wrap everything in the pool (might want to do somewhere else)
Expand Down

0 comments on commit c825449

Please sign in to comment.