-
Notifications
You must be signed in to change notification settings - Fork 1
Features/6270 add download api #110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
30207c5
new customized process files
HavierD d4f9095
change the location of the api implementation
HavierD 4f1bb34
add aws batch dependencies
HavierD cdd87f1
use environment variables to instead parameters
HavierD c326767
Merge branch 'main' into features/6270-add-download-api
HavierD 8bce5e1
add enums for downloading data
HavierD e3f5c7e
correct an error in the enum
HavierD fa98f7c
update aws batch service
HavierD a8d9641
add test cases
HavierD 16504a2
add test cases for process rest api
HavierD 57729bc
minor fix
HavierD f85728c
Merge branch 'main' into features/6270-add-download-api
HavierD 2a24741
fix for failure test about aws
HavierD d832709
pre-commit fix
HavierD a5cc368
pre-commit fix
HavierD f5dd352
minor fixing
HavierD 29f8e4f
make process api to implement necessary interface
HavierD 7b9d0a3
test fixing
HavierD 6ebec88
move api functions
HavierD 2b04d66
change scope of downloaddata function
HavierD c983341
fix test cases
HavierD b09b435
fix pre-commit
HavierD b3d2409
change functions location
HavierD b204513
fix pre-commit errors
HavierD 015ec8d
relocate aws services
HavierD File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
31 changes: 31 additions & 0 deletions
31
server/src/main/java/au/org/aodn/ogcapi/server/core/configuration/AwsConfig.java
This file contains hidden or 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,31 @@ | ||
| package au.org.aodn.ogcapi.server.core.configuration; | ||
|
|
||
| import au.org.aodn.ogcapi.server.processes.RestServices; | ||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||
| import org.springframework.beans.factory.annotation.Value; | ||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; | ||
| import software.amazon.awssdk.regions.Region; | ||
| import software.amazon.awssdk.services.batch.BatchClient; | ||
|
|
||
| @Configuration | ||
| public class AwsConfig { | ||
|
|
||
| @Value("${aws.region}") | ||
| private String awsRegion; | ||
|
|
||
| @Bean | ||
| public BatchClient batchClient() { | ||
| return BatchClient | ||
| .builder() | ||
| .region(Region.of(awsRegion)) | ||
| .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) | ||
| .build(); | ||
| } | ||
|
|
||
| @Bean | ||
| public RestServices awsBatchService(BatchClient batchClient, ObjectMapper objectMapper) { | ||
| return new RestServices(batchClient, objectMapper); | ||
| } | ||
| } |
5 changes: 5 additions & 0 deletions
5
server/src/main/java/au/org/aodn/ogcapi/server/core/model/InlineValue.java
This file contains hidden or 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,5 @@ | ||
| package au.org.aodn.ogcapi.server.core.model; | ||
|
|
||
| import au.org.aodn.ogcapi.processes.model.InlineOrRefData; | ||
|
|
||
| public record InlineValue(String message) implements InlineOrRefData {} |
49 changes: 49 additions & 0 deletions
49
.../src/main/java/au/org/aodn/ogcapi/server/core/model/enumeration/DatasetDownloadEnums.java
This file contains hidden or 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.ogcapi.server.core.model.enumeration; | ||
|
|
||
| import lombok.Getter; | ||
|
|
||
| /** | ||
| * the values are used for aws batch's environment variables | ||
| */ | ||
| public class DatasetDownloadEnums { | ||
|
|
||
| @Getter | ||
| public enum Condition { | ||
| UUID("UUID"), | ||
| START_DATE("START_DATE"), | ||
| END_DATE("END_DATE"), | ||
| MIN_LATITUDE("MIN_LAT"), | ||
| MAX_LATITUDE("MAX_LAT"), | ||
| MIN_LONGITUDE("MIN_LON"), | ||
| MAX_LONGITUDE("MAX_LON"), | ||
| RECIPIENT("RECIPIENT"); | ||
|
|
||
| private final String value; | ||
|
|
||
| Condition(String value) { | ||
| this.value = value; | ||
| } | ||
| } | ||
|
|
||
| @Getter | ||
| public enum JobDefinition { | ||
| GENERATE_CSV_DATA_FILE("generate-csv-data-file"); | ||
|
|
||
| private final String value; | ||
|
|
||
| JobDefinition(String value) { | ||
| this.value = value; | ||
| } | ||
| } | ||
|
|
||
| @Getter | ||
| public enum JobQueue { | ||
| GENERATING_CSV_DATA_FILE("generate-csv-data-file"); | ||
|
|
||
| private final String value; | ||
|
|
||
| JobQueue(String value) { | ||
| this.value = value; | ||
| } | ||
| } | ||
| } | ||
15 changes: 15 additions & 0 deletions
15
server/src/main/java/au/org/aodn/ogcapi/server/core/model/enumeration/ProcessIdEnum.java
This file contains hidden or 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,15 @@ | ||
| package au.org.aodn.ogcapi.server.core.model.enumeration; | ||
|
|
||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public enum ProcessIdEnum { | ||
| DOWNLOAD_DATASET("download"), | ||
| ; | ||
|
|
||
| private final String value; | ||
|
|
||
| ProcessIdEnum(String value) { | ||
| this.value = value; | ||
| } | ||
| } |
90 changes: 90 additions & 0 deletions
90
server/src/main/java/au/org/aodn/ogcapi/server/processes/RestApi.java
This file contains hidden or 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,90 @@ | ||
| package au.org.aodn.ogcapi.server.processes; | ||
|
|
||
|
|
||
| import au.org.aodn.ogcapi.processes.api.ProcessesApi; | ||
| import au.org.aodn.ogcapi.processes.model.Execute; | ||
| import au.org.aodn.ogcapi.processes.model.InlineResponse200; | ||
| import au.org.aodn.ogcapi.processes.model.ProcessList; | ||
| import au.org.aodn.ogcapi.processes.model.Results; | ||
| import au.org.aodn.ogcapi.server.core.model.InlineValue; | ||
| import au.org.aodn.ogcapi.server.core.model.enumeration.ProcessIdEnum; | ||
| import io.swagger.v3.oas.annotations.Parameter; | ||
| import io.swagger.v3.oas.annotations.enums.ParameterIn; | ||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import jakarta.validation.Valid; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.springframework.beans.factory.annotation.Autowired; | ||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| @Slf4j | ||
| @RestController("ProcessesRestApi") | ||
| @RequestMapping(value = "/api/v1/ogc") | ||
| public class RestApi implements ProcessesApi { | ||
|
|
||
| @Autowired | ||
| private RestServices restServices; | ||
|
|
||
| @Override | ||
| // because the produces value in the interface declaration includes "/_" which may | ||
| // cause exception thrown sometimes. So i re-declared the produces value here | ||
| @RequestMapping(value = "/processes/{processID}/execution", | ||
HavierD marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| produces = { "application/json", "text/html" }, | ||
| consumes = { "application/json" }, | ||
| method = RequestMethod.POST) | ||
| public ResponseEntity<InlineResponse200> execute( | ||
| @Parameter(in = ParameterIn.PATH, required=true, schema=@Schema()) | ||
| @PathVariable("processID") | ||
| String processID, | ||
| @Parameter(in = ParameterIn.DEFAULT, description = "Mandatory execute request JSON", required=true, schema=@Schema()) | ||
| @Valid | ||
| @RequestBody Execute body){ | ||
|
|
||
| if (processID.equals(ProcessIdEnum.DOWNLOAD_DATASET.getValue())) { | ||
| try { | ||
| var response = restServices.downloadData( | ||
| (String) body.getInputs().get("collectionId"), | ||
| (String) body.getInputs().get("start_date"), | ||
| (String) body.getInputs().get("end_date"), | ||
| (String) body.getInputs().get("min_lat"), | ||
| (String) body.getInputs().get("min_lon"), | ||
| (String) body.getInputs().get("max_lat"), | ||
| (String) body.getInputs().get("max_lon"), | ||
| (String) body.getInputs().get("recipient") | ||
| ); | ||
|
|
||
| var value = new InlineValue(response.getBody()); | ||
| var results = new Results(); | ||
| results.put("message", value); | ||
|
|
||
| return ResponseEntity.ok(results); | ||
|
|
||
| } catch (Exception e) { | ||
| log.error(e.getMessage()); | ||
| var response = new Results(); | ||
| var value = new InlineValue("Error while getting dataset"); | ||
| response.put("error", value); | ||
|
|
||
| return ResponseEntity.badRequest().body(response); | ||
| } | ||
| } | ||
|
|
||
| var response = new Results(); | ||
| var value = new InlineValue("Unknown process ID: " + processID); | ||
| response.put("error", value); | ||
|
|
||
| return ResponseEntity.badRequest().body(response); | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| public ResponseEntity<au.org.aodn.ogcapi.processes.model.Process> getProcessDescription(String processID) { | ||
| return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build(); | ||
| } | ||
|
|
||
| @Override | ||
| public ResponseEntity<ProcessList> getProcesses() { | ||
| return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED).build(); | ||
| } | ||
| } | ||
121 changes: 121 additions & 0 deletions
121
server/src/main/java/au/org/aodn/ogcapi/server/processes/RestServices.java
This file contains hidden or 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,121 @@ | ||
| package au.org.aodn.ogcapi.server.processes; | ||
|
|
||
| import au.org.aodn.ogcapi.server.core.model.enumeration.DatasetDownloadEnums; | ||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.springframework.http.ResponseEntity; | ||
| import software.amazon.awssdk.services.batch.BatchClient; | ||
| import software.amazon.awssdk.services.batch.model.*; | ||
|
|
||
| import java.io.File; | ||
| import java.io.IOException; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
||
| @Slf4j | ||
| public class RestServices { | ||
|
|
||
| private final BatchClient batchClient; | ||
| private final ObjectMapper objectMapper; | ||
|
|
||
| public RestServices(BatchClient batchClient, ObjectMapper objectMapper) { | ||
| this.batchClient = batchClient; | ||
| this.objectMapper = objectMapper; | ||
| } | ||
|
|
||
| public ResponseEntity<String> downloadData( | ||
| String id, | ||
| String startDate, | ||
| String endDate, | ||
| String minLat, | ||
| String minLon, | ||
| String maxLat, | ||
| String maxLon, | ||
| String recipient | ||
| ) { | ||
| try { | ||
|
|
||
| Map<String, String> parameters = new HashMap<>(); | ||
| parameters.put(DatasetDownloadEnums.Condition.UUID.getValue(), id); | ||
| parameters.put(DatasetDownloadEnums.Condition.START_DATE.getValue(), startDate); | ||
| parameters.put(DatasetDownloadEnums.Condition.END_DATE.getValue(), endDate); | ||
| parameters.put(DatasetDownloadEnums.Condition.MIN_LATITUDE.getValue(), minLat); | ||
| parameters.put(DatasetDownloadEnums.Condition.MIN_LONGITUDE.getValue(), minLon); | ||
| parameters.put(DatasetDownloadEnums.Condition.MAX_LATITUDE.getValue(), maxLat); | ||
| parameters.put(DatasetDownloadEnums.Condition.MAX_LONGITUDE.getValue(), maxLon); | ||
| parameters.put(DatasetDownloadEnums.Condition.RECIPIENT.getValue(), recipient); | ||
|
|
||
|
|
||
| String jobId = submitJob( | ||
| "generating-data-file-for-" + recipient.replaceAll("[^a-zA-Z0-9-_]", "-"), | ||
| DatasetDownloadEnums.JobQueue.GENERATING_CSV_DATA_FILE.getValue(), | ||
| DatasetDownloadEnums.JobDefinition.GENERATE_CSV_DATA_FILE.getValue(), | ||
| parameters); | ||
| log.info("Job submitted with ID: " + jobId); | ||
| return ResponseEntity.ok("Job submitted with ID: " + jobId); | ||
| } catch (Exception e) { | ||
|
|
||
| log.error("Error while getting dataset"); | ||
| log.error(e.getMessage()); | ||
| return ResponseEntity.badRequest().body("Error while getting dataset"); | ||
| } | ||
| } | ||
|
|
||
| private String submitJob(String jobName, String jobQueue, String jobDefinition, Map<String, String> parameters) { | ||
|
|
||
| List<KeyValuePair> environmentVariables = parameters.entrySet().stream() | ||
| .map(entry -> | ||
| KeyValuePair | ||
| .builder() | ||
| .name(entry.getKey()) | ||
| .value(entry.getValue()) | ||
| .build() | ||
| ) | ||
| .toList(); | ||
|
|
||
| SubmitJobRequest submitJobRequest = SubmitJobRequest.builder() | ||
| .jobName(jobName) | ||
| .jobQueue(jobQueue) | ||
| .jobDefinition(jobDefinition) | ||
| .parameters(parameters) | ||
| .containerOverrides(co -> co.environment(environmentVariables)) | ||
| .build(); | ||
|
|
||
| SubmitJobResponse submitJobResponse = batchClient.submitJob(submitJobRequest); | ||
| return submitJobResponse.jobId(); | ||
| } | ||
|
|
||
|
|
||
|
|
||
| // TODO: This feature doesn't work yet. Will be implemented in the future as this one is not urgent | ||
| public boolean isJobQueueValid(String jobQueueName) throws IOException { | ||
|
|
||
| var remoteJobQueueDetail = getRemoteJobQueueBy(jobQueueName); | ||
| var localJobQueueDetail = getLocalJobQueueDetailBy(jobQueueName); | ||
|
|
||
| return remoteJobQueueDetail.equals(localJobQueueDetail); | ||
| } | ||
|
|
||
| public JobQueueDetail getRemoteJobQueueBy(String name) { | ||
| var request = DescribeJobQueuesRequest | ||
| .builder() | ||
| .jobQueues(name) | ||
| .build(); | ||
|
|
||
| var jobQueues = batchClient.describeJobQueues(request).jobQueues(); | ||
|
|
||
| if (jobQueues != null && jobQueues.size() == 1) { | ||
| return jobQueues.get(0); | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| public JobQueueDetail getLocalJobQueueDetailBy(String jobQueueName) throws IOException { | ||
| var configJsonPath = "server/src/main/java/au/org/aodn/ogcapi/server/processes/config/" + jobQueueName + ".json"; | ||
| var jsonFile = new File(configJsonPath); | ||
| var jsonStr = objectMapper.writeValueAsString(objectMapper.readValue(jsonFile, Object.class)); | ||
| return objectMapper.readValue(jsonStr, JobQueueDetail.class); | ||
| } | ||
|
|
||
| } |
18 changes: 18 additions & 0 deletions
18
server/src/main/java/au/org/aodn/ogcapi/server/processes/config/generate-csv-data-file.json
This file contains hidden or 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,18 @@ | ||
| { | ||
| "jobQueueName": "generate-csv-data-file", | ||
| "jobQueueArn": "arn:aws:batch:ap-southeast-2:704910415367:job-queue/generate-csv-data-file", | ||
| "state": "ENABLED", | ||
| "status": "VALID", | ||
| "statusReason": "JobQueue Healthy", | ||
| "priority": 1, | ||
| "computeEnvironmentOrder": [ | ||
| { | ||
| "order": 1, | ||
| "computeEnvironment": "arn:aws:batch:ap-southeast-2:704910415367:compute-environment/generate-csv-data-file" | ||
| } | ||
| ], | ||
| "serviceEnvironmentOrder": [], | ||
| "jobQueueType": "ECS_FARGATE", | ||
| "tags": {}, | ||
| "jobStateTimeLimitActions": [] | ||
| } |
This file contains hidden or 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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.