Skip to content

Commit c54e269

Browse files
authored
Merge pull request #267 from AtlasOfLivingAustralia/various
Various
2 parents 7a69091 + 69394a4 commit c54e269

File tree

9 files changed

+112
-84
lines changed

9 files changed

+112
-84
lines changed

grails-app/controllers/au/org/ala/spatial/ShapesController.groovy

+4-20
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,9 @@ class ShapesController {
10341034
WKTReader wktReader = new WKTReader()
10351035
Geometry geom = wktReader.read(wkt.toString())
10361036

1037+
// union all the polygons in a MULTIPOLYGON, if any
1038+
geom = geom.union()
1039+
10371040
// Use CCW for exterior rings. Normalizing will use the JTS default (CW). Reverse makes it CCW.
10381041
Geometry validGeom = GeomMakeValid.makeValid(geom)
10391042
validGeom.normalize()
@@ -1059,27 +1062,8 @@ class ShapesController {
10591062
return filename.replaceAll("[^a-zA-Z0-9\\(\\)\\[\\]\\-]", "_")
10601063
}
10611064

1062-
private static cleanObjectId(String id) {
1065+
private static String cleanObjectId(String id) {
10631066
String.valueOf(Long.valueOf(id))
10641067
}
1065-
1066-
// requestBody schemas
1067-
// class UploadWkt {
1068-
// String wkt
1069-
// String name
1070-
// String description
1071-
// String user_id
1072-
// }
1073-
//
1074-
// class UploadGeoJSON {
1075-
// String name
1076-
// String description
1077-
// String user_id
1078-
// Map geojson
1079-
// }
1080-
//
1081-
// class UploadFeatures {
1082-
// List<String> featureIndex
1083-
// }
10841068
}
10851069

grails-app/controllers/au/org/ala/spatial/WorkflowController.groovy

+10-42
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
package au.org.ala.spatial
1717

18+
import au.ala.org.ws.security.RequireApiKey
1819
import au.org.ala.web.AuthService
1920
import grails.converters.JSON
2021

@@ -41,6 +42,7 @@ class WorkflowController {
4142
* @param id
4243
* @return
4344
*/
45+
@RequireApiKey
4446
def save(Long id) {
4547
String user_id = authService.getUserId()
4648
def data = request.JSON
@@ -49,57 +51,25 @@ class WorkflowController {
4951
def description = data['description']?.toString()
5052
def metadata = data['metadata']?.toString()
5153

52-
def header
53-
54-
String errorMsg
55-
if ("true".equalsIgnoreCase(data['doi']?.toString())) {
56-
// test for minimum data for a DOI
57-
errorMsg = getErrorForDoi(data)
58-
59-
if (!errorMsg) {
60-
// analysis_id is used to hold the minted value. This makes it readonly.
61-
header = userDataService.put(user_id, RECORD_TYPE, description, metadata, isPublic, null)
62-
if (header?.ud_header_id) {
63-
userDataService.update(header.ud_header_id, user_id, RECORD_TYPE, description, metadata, isPublic, header.ud_header_id.toString())
64-
}
65-
}
66-
} else {
67-
header = userDataService.put(user_id, RECORD_TYPE, description, metadata, isPublic, null)
68-
}
69-
70-
header = mapping(header)
54+
def header = mapping(userDataService.put(user_id, RECORD_TYPE, description, metadata, isPublic, null))
7155

7256
def result
73-
if (errorMsg) {
74-
result = false
75-
def map = [successful: result, message: errorMsg]
76-
render map as JSON
77-
} else if (header) {
57+
if (header) {
7858
result = true
7959
def map = [successful: result, data: header]
8060
render map as JSON
8161
} else {
8262
result = false
83-
errorMsg = "Failed to save workflow"
84-
def map = [successful: result, message: errorMsg]
63+
def map = [successful: result, message: "Failed to save workflow"]
8564
render map as JSON
8665
}
8766
}
8867

89-
def doi(String id) {
90-
List list = userDataService.searchDescAndTypeOr(null, RECORD_TYPE, null, null, id, 0, 1)
91-
92-
if (list.size() > 0) {
93-
show(list.get(0).ud_header_id)
94-
} else {
95-
render status: HttpURLConnection.HTTP_NOT_FOUND
96-
}
97-
}
98-
68+
@RequireApiKey
9969
def show(Long id) {
10070
String user_id = authService.getUserId()
10171

102-
def item = userDataService.get(id)
72+
def item = UDHeader.get(id)
10373

10474
if (!item) {
10575
render status: 404
@@ -128,10 +98,11 @@ class WorkflowController {
12898
}
12999
}
130100

101+
@RequireApiKey
131102
def delete(Long id) {
132103
String user_id = authService.getUserId()
133104

134-
def metadata = userDataService.get(id)
105+
def metadata = UDHeader.get(id)
135106

136107
// check authorisation and that it is not minted (no analysis_id)
137108
if ((metadata.user_id == user_id ||
@@ -148,6 +119,7 @@ class WorkflowController {
148119
}
149120
}
150121

122+
@RequireApiKey
151123
def search() {
152124
String user_id = authService.getUserId()
153125

@@ -161,10 +133,6 @@ class WorkflowController {
161133
render formattedList as JSON
162134
}
163135

164-
private def getErrorForDoi(data) {
165-
return ""
166-
}
167-
168136
private def mapping(header) {
169137
return [id : header.ud_header_id, mintId: header.analysis_id, name: header.description,
170138
userId : header.user_id, isPrivate: !PUBLIC.equalsIgnoreCase(header.data_path),

grails-app/services/au/org/ala/spatial/TabulationService.groovy

+4
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,10 @@ class TabulationService {
479479
//is it grid as contextual layer?
480480
IntersectionFile f = layerService.getIntersectionFile(fid)
481481

482+
if (f == null) {
483+
return []
484+
}
485+
482486
if (f.getType().equalsIgnoreCase("c")) {
483487
if (wkt.length() > 0) {
484488
String sql

grails-app/services/au/org/ala/spatial/UserDataService.groovy

+71-20
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,85 @@ package au.org.ala.spatial
33
* A small cache for data resource attribution.
44
* This should be revisited if this cache grows or needs regular refreshing.
55
*/
6-
//@CompileStatic
76
class UserDataService {
87

9-
void put(String s1, String s2, String s3, String s4, String s5, String o) {
10-
11-
12-
13-
14-
15-
16-
8+
UDHeader put(String user_id, String record_type, String description, String metadata, String data_path, String analysis_id) {
9+
Date upload_dt = new Date(System.currentTimeMillis())
10+
UDHeader udHeader = new UDHeader(
11+
user_id: user_id,
12+
record_type: record_type,
13+
description: description,
14+
metadata: metadata,
15+
data_path: data_path,
16+
analysis_id: analysis_id,
17+
upload_dt: upload_dt
18+
)
19+
20+
UDHeader.withTransaction {
21+
if (!udHeader.save(flush: true)) {
22+
udHeader.errors.allErrors.each { error ->
23+
log.error("Error saving UDHeader: ${error}")
24+
}
25+
return null
26+
}
27+
}
28+
29+
return udHeader
1730
}
1831

19-
20-
void update(Object o, String s1, String s2, String s3, String s4, String s5, String s6) {
21-
22-
23-
24-
32+
UDHeader update(Long ud_header_id, String user_id, String record_type, String description, String metadata, String data_path, String analysis_id) {
33+
UDHeader.withTransaction {
34+
UDHeader udHeader = UDHeader.get(ud_header_id)
35+
if (udHeader != null) {
36+
udHeader.user_id = user_id
37+
udHeader.record_type = record_type
38+
udHeader.description = description
39+
udHeader.metadata = metadata
40+
udHeader.data_path = data_path
41+
udHeader.analysis_id = analysis_id
42+
udHeader.upload_dt = new Date(System.currentTimeMillis())
43+
44+
if (!udHeader.save(flush: true)) {
45+
udHeader.errors.allErrors.each { error ->
46+
log.error("Error saving UDHeader: ${error}")
47+
}
48+
return null
49+
}
50+
}
51+
52+
return udHeader
53+
}
2554
}
2655

27-
Object searchDescAndTypeOr(String o1, String s1, String o2, String o3, String s2, int integer1, int integer2) {}
56+
boolean delete(Long ud_header_id) {
57+
UDHeader.withTransaction {
58+
UDHeader.get(ud_header_id).delete()
59+
}
2860

29-
Object get(long aLong) {
30-
null
61+
return true
3162
}
3263

33-
void delete(long aLong) {
34-
64+
List<UDHeader> searchDescAndTypeOr(String desc, String record_type, String user_id, String data_path, String analysis_id, int start, int limit) {
65+
def criteria = UDHeader.createCriteria()
66+
def results = criteria.list(max: limit, offset: start) {
67+
if (desc) {
68+
ilike('description', desc)
69+
}
70+
if (record_type) {
71+
eq('record_type', record_type)
72+
}
73+
or {
74+
if (user_id) {
75+
eq('user_id', user_id)
76+
}
77+
if (data_path) {
78+
eq('data_path', data_path)
79+
}
80+
if (analysis_id) {
81+
eq('analysis_id', analysis_id)
82+
}
83+
}
84+
}
85+
return results
3586
}
3687
}

src/main/groovy/au/org/ala/spatial/StreamGobbler.groovy

+11-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,17 @@ class StreamGobbler extends Thread {
4141
String line
4242
while ((line = br.readLine()) != null) {
4343
if (taskWrapper != null) {
44-
taskWrapper.task.history.put(System.currentTimeMillis() as String, logPrefix + ": " + line)
44+
// surpress some JDK logging
45+
if (!line.startsWith('INFO:') && !line.startsWith('NOTE:') && !line.contains('java.')) {
46+
String str = logPrefix + ": " + line
47+
48+
// trim str to max 250 characters
49+
if (str.length() > 250) {
50+
str = str.substring(0, 250)
51+
}
52+
53+
taskWrapper.task.history.put(System.currentTimeMillis() as String, str)
54+
}
4555
}
4656
if (stringBuffer != null) {
4757
stringBuffer.append(line).append('\n');

src/main/groovy/au/org/ala/spatial/Util.groovy

+2
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ class Util {
249249
s.q.addAll(json.fq)
250250
}
251251
s.wkt = json.wkt
252+
253+
return s;
252254
}
253255

254256
static String[] getDistributionsOrChecklists(List<Distributions> ja) {

src/main/groovy/au/org/ala/spatial/process/Classification.groovy

+5
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,11 @@ class Classification extends SlaveProcess {
5252
taskLog("Cutting Grids")
5353
def cutDataPath = cutGrid(envnameslist, resolution as String, regionEnvelope.region, regionEnvelope.envelope, null)
5454

55+
File tmpDir = new File(getTaskPath() + "/tmp/")
56+
5557
taskLog("Running aloc process")
5658
String[] cmd = ["java", "-Xmx" + String.valueOf(spatialConfig.aloc.xmx),
59+
"-Djava.util.prefs.userRoot=" + getTaskPath() + "/tmp/",
5760
"-jar", spatialConfig.data.dir + '/modelling/aloc/aloc.jar',
5861
cutDataPath, String.valueOf(groups), String.valueOf(spatialConfig.aloc.threads), getTaskPath()]
5962

@@ -130,5 +133,7 @@ class Classification extends SlaveProcess {
130133
Util.replaceTextInFile(getTaskPath() + "classification.html", replaceMap)
131134
addOutput("metadata", "classification.html", true)
132135
}
136+
137+
tmpDir.delete()
133138
}
134139
}

src/main/groovy/au/org/ala/spatial/process/Maxent.groovy

+4
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class Maxent extends SlaveProcess {
6868
}
6969
taskLog("Run Maxent model")
7070
def cmd = ["java", "-mx" + String.valueOf(spatialConfig.maxent.mx),
71+
"-Djava.util.prefs.userRoot=" + getTaskPath() + "/tmp/",
7172
"-jar", spatialConfig.data.dir + '/modelling/maxent/maxent.jar',
7273
"-e", cutDataPath, "-s", speciesPath.get(0), "-a", "tooltips=false",
7374
"nowarnings", "noprefixes", "-z",
@@ -212,6 +213,9 @@ class Maxent extends SlaveProcess {
212213
FileUtils.moveFile(new File(getTaskPath() + "_species.gri"), target)
213214
addOutput("layers", "/layer/" + taskWrapper.id + "_species.gri")
214215
}
216+
217+
File tmpDir = new File(getTaskPath() + "/tmp/")
218+
FileUtils.deleteDirectory(tmpDir)
215219
}
216220

217221
static def writeMaxentsld(filename) {

src/main/groovy/au/org/ala/spatial/process/SlaveProcess.groovy

+1-1
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ class SlaveProcess {
10821082
runCmd(cmd.toArray(new String[cmd.size()]), false, spatialConfig.admin.timeout)
10831083

10841084
} catch (Exception e) {
1085-
e.printStackTrace()
1085+
log.error("Failed to convert asc to grd: " + e.getMessage(), e)
10861086
}
10871087
}
10881088

0 commit comments

Comments
 (0)