-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #162 from aodn/feature/5972-index-downloaded-data
Feature/5972 index downloaded data
- Loading branch information
Showing
13 changed files
with
392 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
indexer/src/main/java/au/org/aodn/esindexer/configuration/DatasetAccessConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package au.org.aodn.esindexer.configuration; | ||
|
||
import au.org.aodn.esindexer.service.DataAccessServiceImpl; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
public class DatasetAccessConfig { | ||
|
||
@Bean(name = "DataAccessService") | ||
public DataAccessServiceImpl createDataAccessService( | ||
@Value("${dataaccess.host:defaultForTesting}") String serverUrl | ||
){ | ||
return new DataAccessServiceImpl(serverUrl); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
indexer/src/main/java/au/org/aodn/esindexer/model/Dataset.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package au.org.aodn.esindexer.model; | ||
|
||
import java.time.YearMonth; | ||
import java.util.List; | ||
|
||
public record Dataset( | ||
String uuid, | ||
YearMonth yearMonth, | ||
List<Datum> data | ||
) {} |
49 changes: 49 additions & 0 deletions
49
indexer/src/main/java/au/org/aodn/esindexer/model/Datum.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package au.org.aodn.esindexer.model; | ||
|
||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
import java.time.LocalDate; | ||
|
||
// If more fields are needed to be filtered, please add more columns here | ||
// and don't forget updating the override equals() method | ||
@Getter | ||
@Setter | ||
public class Datum { | ||
|
||
|
||
private final LocalDate time; | ||
private final double longitude; | ||
private final double latitude; | ||
private final double depth; | ||
|
||
private long count = 1; | ||
|
||
public Datum(LocalDate time, double longitude, double latitude, double depth) { | ||
this.time = time; | ||
this.longitude = longitude; | ||
this.latitude = latitude; | ||
this.depth = depth; | ||
} | ||
|
||
// putting all same record into one instance and increment the count is more efficient | ||
public void incrementCount() { | ||
count++; | ||
} | ||
|
||
// Don't include variable "count" in the equals() method. | ||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} | ||
if (obj == null || getClass() != obj.getClass()) { | ||
return false; | ||
} | ||
Datum that = (Datum) obj; | ||
return Double.compare(that.longitude, longitude) == 0 && | ||
Double.compare(that.latitude, latitude) == 0 && | ||
Double.compare(that.depth, depth) == 0 && | ||
time.equals(that.time); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
indexer/src/main/java/au/org/aodn/esindexer/service/DataAccessService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package au.org.aodn.esindexer.service; | ||
|
||
import au.org.aodn.esindexer.model.Dataset; | ||
|
||
import java.time.LocalDate; | ||
|
||
public interface DataAccessService { | ||
Dataset getIndexingDatasetBy(String uuid, LocalDate startDate, LocalDate endDate); | ||
boolean doesDataExist(String uuid, LocalDate startDate, LocalDate endDate); | ||
String getServiceUrl(); | ||
void setServiceUrl(String url); | ||
} |
154 changes: 154 additions & 0 deletions
154
indexer/src/main/java/au/org/aodn/esindexer/service/DataAccessServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package au.org.aodn.esindexer.service; | ||
|
||
import au.org.aodn.esindexer.exception.MetadataNotFoundException; | ||
import au.org.aodn.esindexer.model.Datum; | ||
import au.org.aodn.esindexer.model.Dataset; | ||
import org.springframework.http.*; | ||
import org.springframework.web.client.HttpClientErrorException; | ||
import org.springframework.web.client.RestTemplate; | ||
import org.springframework.web.util.UriComponentsBuilder; | ||
|
||
import java.time.LocalDate; | ||
import java.time.YearMonth; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class DataAccessServiceImpl implements DataAccessService { | ||
|
||
private String serverUrl; | ||
|
||
@Override | ||
public String getServiceUrl() { | ||
return serverUrl; | ||
} | ||
|
||
@Override | ||
public void setServiceUrl(String url) { | ||
this.serverUrl = url; | ||
} | ||
|
||
public DataAccessServiceImpl(String serverUrl) { | ||
setServiceUrl(serverUrl); | ||
} | ||
|
||
private final RestTemplate restTemplate = new RestTemplate(); | ||
@Override | ||
public Dataset getIndexingDatasetBy(String uuid, LocalDate startDate, LocalDate endDate) { | ||
|
||
// currently, we force to get data in the same month and year to simplify the logic | ||
if (startDate.getMonth() != endDate.getMonth() || startDate.getYear() != endDate.getYear()) { | ||
throw new IllegalArgumentException("Start date and end date must be in the same month and year"); | ||
} | ||
|
||
try { | ||
HttpEntity<String> request = getRequestEntity(null, null); | ||
|
||
Map<String, Object> params = new HashMap<>(); | ||
params.put("uuid", uuid); | ||
|
||
String url = UriComponentsBuilder.fromHttpUrl(getDataAccessEndpoint() + "/data/{uuid}") | ||
.queryParam("is_to_index", "true") | ||
.queryParam("start_date", startDate) | ||
.queryParam("end_date", endDate) | ||
.buildAndExpand(uuid) | ||
.toUriString(); | ||
|
||
ResponseEntity<Datum[]> responseEntity = restTemplate.exchange( | ||
url, | ||
HttpMethod.GET, | ||
request, | ||
Datum[].class, | ||
params | ||
); | ||
|
||
|
||
|
||
if (responseEntity.getStatusCode().is2xxSuccessful()) { | ||
List<Datum> data = new ArrayList<>(); | ||
if (responseEntity.getBody() != null) { | ||
data = List.of(responseEntity.getBody()); | ||
} | ||
var dataToIndex = aggregateData(data); | ||
return new Dataset( | ||
uuid, | ||
YearMonth.of(startDate.getYear(), startDate.getMonth()), | ||
dataToIndex | ||
); | ||
} | ||
throw new RuntimeException("Unable to retrieve dataset with UUID: " + uuid ); | ||
|
||
} catch (HttpClientErrorException.NotFound e) { | ||
throw new MetadataNotFoundException("Unable to find dataset with UUID: " + uuid + " in GeoNetwork"); | ||
} catch (Exception e) { | ||
throw new RuntimeException("Exception thrown while retrieving dataset with UUID: " + uuid + e.getMessage(), e); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean doesDataExist(String uuid, LocalDate startDate, LocalDate endDate) { | ||
try { | ||
HttpEntity<String> request = getRequestEntity(null, null); | ||
|
||
Map<String, Object> params = new HashMap<>(); | ||
params.put("uuid", uuid); | ||
|
||
String url = UriComponentsBuilder.fromHttpUrl(getDataAccessEndpoint() + "/data/{uuid}/has_data") | ||
.queryParam("start_date", startDate) | ||
.queryParam("end_date", endDate) | ||
.buildAndExpand(uuid) | ||
.toUriString(); | ||
|
||
ResponseEntity<Boolean> responseEntity = restTemplate.exchange( | ||
url, | ||
HttpMethod.GET, | ||
request, | ||
Boolean.class, | ||
params | ||
); | ||
|
||
return Boolean.TRUE.equals(responseEntity.getBody()); | ||
|
||
} catch (HttpClientErrorException.NotFound e) { | ||
throw new MetadataNotFoundException("Unable to find dataset with UUID: " + uuid + " in GeoNetwork"); | ||
} catch (Exception e) { | ||
throw new RuntimeException("Exception thrown while retrieving dataset with UUID: " + uuid + e.getMessage(), e); | ||
} | ||
} | ||
|
||
/** | ||
* Summarize the data by counting the number if all the concerned fields are the same | ||
* @param data the data to summarize | ||
* @return the summarized data | ||
*/ | ||
private List<Datum> aggregateData(List<Datum> data) { | ||
var aggregatedData = new ArrayList<Datum>(); | ||
for (var datum: data) { | ||
if (aggregatedData.contains(datum)) { | ||
var existingDatum = aggregatedData.get(aggregatedData.indexOf(datum)); | ||
existingDatum.incrementCount(); | ||
} else { | ||
aggregatedData.add(datum); | ||
} | ||
} | ||
return aggregatedData; | ||
} | ||
|
||
private String getDataAccessEndpoint() { | ||
return getServiceUrl() + "/api/v1/das/"; | ||
} | ||
|
||
|
||
// parameters are not in use for now. May be useful in the future so just keep it | ||
protected HttpEntity<String> getRequestEntity(MediaType accept, String body) { | ||
HttpHeaders headers = new HttpHeaders(); | ||
headers.setAccept(List.of( | ||
MediaType.TEXT_PLAIN, | ||
MediaType.APPLICATION_JSON, | ||
MediaType.valueOf("application/*+json"), | ||
MediaType.ALL | ||
)); | ||
return body == null ? new org.springframework.http.HttpEntity<>(headers) : new org.springframework.http.HttpEntity<>(body, headers); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.