Skip to content

Commit bc4df2f

Browse files
Test case 2
1 parent f5e5293 commit bc4df2f

3 files changed

Lines changed: 87 additions & 20 deletions

File tree

server/src/main/java/au/org/aodn/ogcapi/server/core/service/geoserver/wfs/DownloadWfsDataService.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@
33
import au.org.aodn.ogcapi.server.core.model.ogc.FeatureRequest;
44
import au.org.aodn.ogcapi.server.core.util.DatetimeUtils;
55
import lombok.extern.slf4j.Slf4j;
6+
import net.opengis.ows10.ExceptionReportType;
67
import net.opengis.wfs.FeatureCollectionType;
78
import org.geotools.wfs.v1_1.WFSConfiguration;
89
import org.geotools.xsd.Parser;
910
import org.springframework.http.*;
1011
import org.springframework.web.client.RestTemplate;
1112
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
13+
import org.xml.sax.SAXException;
1214

15+
import javax.xml.parsers.ParserConfigurationException;
1316
import java.io.ByteArrayOutputStream;
17+
import java.io.IOException;
1418
import java.io.InputStream;
1519
import java.io.StringReader;
1620
import java.math.BigInteger;
@@ -23,7 +27,7 @@ public class DownloadWfsDataService {
2327
protected final RestTemplate restTemplate;
2428
protected final HttpEntity<?> pretendUserEntity;
2529
protected final int chunkSize;
26-
protected static final WFSConfiguration CONFIG = new WFSConfiguration();
30+
protected static final WFSConfiguration WFS_CONFIG = new WFSConfiguration();
2731
protected static final int SAMPLES_SIZE = 500; // A not too small sample for download size estimation
2832

2933
public DownloadWfsDataService(
@@ -95,7 +99,7 @@ public BigInteger estimateDownloadSize(
9599
String endDate,
96100
Object multiPolygon,
97101
List<String> fields,
98-
String outputFormat) {
102+
String outputFormat) throws IllegalArgumentException {
99103

100104
// Just get number of record, the reply will always in XML
101105
String wfsRequestUrl = prepareWfsRequestUrl(
@@ -105,7 +109,7 @@ public BigInteger estimateDownloadSize(
105109
ResponseEntity<String> response = restTemplate.exchange(wfsRequestUrl, HttpMethod.GET, pretendUserEntity, String.class);
106110

107111
if(response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
108-
Parser parser = new Parser(CONFIG);
112+
Parser parser = new Parser(WFS_CONFIG);
109113
parser.setValidating(false);
110114
parser.setFailOnValidationError(false);
111115

@@ -126,8 +130,11 @@ public BigInteger estimateDownloadSize(
126130
.divide(BigInteger.valueOf(SAMPLES_SIZE));
127131
}
128132
}
133+
else if(o instanceof ExceptionReportType report) {
134+
throw new IllegalArgumentException(String.join(",", report.getException().stream().map(ex -> ex.getExceptionText().toString()).toList()));
135+
}
129136
}
130-
catch(Exception e) {
137+
catch(IOException | SAXException | ParserConfigurationException e) {
131138
log.error("Fail to convert wfs hits result", e);
132139
}
133140
}

server/src/main/java/au/org/aodn/ogcapi/server/processes/RestServices.java

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -288,22 +288,34 @@ public SseEmitter downloadWfsDataWithSse(String uuid,
288288
);
289289
}
290290
else {
291-
BigInteger est = downloadWfsDataService.estimateDownloadSize(
292-
uuid,
293-
layerName,
294-
startDate,
295-
endDate,
296-
multiPolygon,
297-
fields,
298-
outputFormat
299-
);
300-
emitter.send(SseEmitter.event()
301-
.name(est != null ? "estimate-complete" : "estimate-failed")
302-
.data(Map.of(
303-
"size", est != null ? est : "",
304-
"timestamp", System.currentTimeMillis()
305-
)));
306-
emitter.complete();
291+
try {
292+
BigInteger est = downloadWfsDataService.estimateDownloadSize(
293+
uuid,
294+
layerName,
295+
startDate,
296+
endDate,
297+
multiPolygon,
298+
fields,
299+
outputFormat
300+
);
301+
emitter.send(SseEmitter.event()
302+
.name(est != null ? "estimate-complete" : "estimate-failed")
303+
.data(Map.of(
304+
"size", est != null ? est : "",
305+
"timestamp", System.currentTimeMillis()
306+
)));
307+
}
308+
catch(IllegalArgumentException iae) {
309+
emitter.send(SseEmitter.event()
310+
.name("estimate-failed")
311+
.data(Map.of(
312+
"message", iae.getMessage(),
313+
"timestamp", System.currentTimeMillis()
314+
)));
315+
}
316+
finally {
317+
emitter.complete();
318+
}
307319
}
308320
} catch (Exception e) {
309321
WfsErrorHandler.handleError(e, uuid, emitter, cleanupWfsResources);

server/src/test/java/au/org/aodn/ogcapi/server/core/service/geoserver/wfs/DownloadWfsDataServiceTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,4 +384,52 @@ void shouldReturnEstimatedSizeWhenBothRequestsSucceed() {
384384
long expected = 227193L * sampleBytes.length / DownloadWfsDataService.SAMPLES_SIZE;
385385
assertEquals(BigInteger.valueOf(expected), size, "Size match");
386386
}
387+
/**
388+
* Expect illegal exception when param is wrong
389+
*/
390+
@Test
391+
void throwExceptionWhenHitsRequestFails() {
392+
393+
String uuid = "lyr-123";
394+
String layer = "imos:aatams_sattag_dm_profile_map1";
395+
String start = "2024-01-01";
396+
String end = "2024-12-31";
397+
Object multiPolygon = new Object(); // or real geometry
398+
List<String> fields = List.of("name", "area");
399+
String format = "application/json";
400+
401+
// 1. Hits response (XML), indicate error
402+
String hitsXml = """
403+
<?xml version="1.0" encoding="UTF-8"?>
404+
<ows:ExceptionReport xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ows="http://www.opengis.net/ows" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/ows https://geoserver-123.aodn.org.au/geoserver/schemas/ows/1.0.0/owsExceptionReport.xsd">
405+
<ows:Exception exceptionCode="InvalidParameterValue" locator="typeName">
406+
<ows:ExceptionText>Feature type imos:aatams_sattag_dm_profile_map1 unknown</ows:ExceptionText>
407+
</ows:Exception>
408+
</ows:ExceptionReport>
409+
""";
410+
ResponseEntity<String> hitsResponse = new ResponseEntity<>(hitsXml, HttpStatus.OK);
411+
doReturn(hitsResponse)
412+
.when(restTemplate).exchange(
413+
argThat((String url) -> url != null && url.contains("resultType=hits")),
414+
eq(HttpMethod.GET),
415+
any(HttpEntity.class),
416+
eq(String.class));
417+
418+
doReturn(Optional.of("http://dummy.com/wfs"))
419+
.when(wfsServer).getFeatureServerUrl(eq(uuid), anyString());
420+
421+
WfsFields fs = WfsFields.builder()
422+
.fields(List.of(
423+
WfsField.builder().type("dateTime").name("time").build()
424+
))
425+
.build();
426+
427+
doReturn(fs)
428+
.when(wfsServer).getDownloadableFields(eq(uuid), any(WfsServer.WfsFeatureRequest.class));
429+
430+
assertThrows(IllegalArgumentException.class,
431+
() -> downloadWfsDataService.estimateDownloadSize(
432+
uuid, layer, start, end, multiPolygon, fields, format)
433+
);
434+
}
387435
}

0 commit comments

Comments
 (0)