From 3ac31e48c67c0c42014ecf74d4549fe6dacb2ab1 Mon Sep 17 00:00:00 2001 From: Suhas Vishwanath Date: Wed, 20 Sep 2023 17:58:03 +0530 Subject: [PATCH] avniproject/avni-media#152 | Introduce end-point to create a download request on media server for all images matching a search criterion --- .../etl/controller/MediaController.java | 17 +++++++ .../avniproject/etl/dto/AddressLevelType.java | 4 ++ .../etl/dto/DownloadAllMediaRequest.java | 49 +++++++++++++++++++ .../avniproject/etl/dto/DownloadRequest.java | 9 ++++ .../org/avniproject/etl/dto/ImageData.java | 17 +++++++ .../etl/repository/MediaTableRepository.java | 19 ++++--- .../service/MediaTableRepositoryService.java | 21 ++++++++ .../avniproject/etl/service/MediaService.java | 29 ++++++++++- .../resources/main-application.properties | 3 ++ src/test/resources/application.properties | 2 + 10 files changed, 162 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/avniproject/etl/dto/AddressLevelType.java create mode 100644 src/main/java/org/avniproject/etl/dto/DownloadAllMediaRequest.java create mode 100644 src/main/java/org/avniproject/etl/dto/DownloadRequest.java create mode 100644 src/main/java/org/avniproject/etl/dto/ImageData.java diff --git a/src/main/java/org/avniproject/etl/controller/MediaController.java b/src/main/java/org/avniproject/etl/controller/MediaController.java index 7073495..86a2779 100644 --- a/src/main/java/org/avniproject/etl/controller/MediaController.java +++ b/src/main/java/org/avniproject/etl/controller/MediaController.java @@ -2,6 +2,9 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.websocket.server.PathParam; +import org.apache.log4j.Logger; +import org.avniproject.etl.dto.DownloadAllMediaRequest; +import org.avniproject.etl.dto.DownloadRequest; import org.avniproject.etl.dto.MediaSearchRequest; import org.avniproject.etl.repository.sql.Page; import org.avniproject.etl.service.MediaService; @@ -20,6 +23,8 @@ public class MediaController { this.mediaService = mediaService; } + private static final Logger log = Logger.getLogger(MediaController.class); + @PreAuthorize("hasAnyAuthority('analytics_user')") @GetMapping("/media") public ResponseEntity list(HttpServletRequest request, @@ -43,4 +48,16 @@ public ResponseEntity search(HttpServletRequest request, return ResponseEntity.badRequest().body(exception.getMessage()); } } + + @PreAuthorize("hasAnyAuthority('analytics_user')") + @PostMapping("/requestDownloadAll") + public ResponseEntity downloadAllImages(@RequestBody(required = true) DownloadAllMediaRequest downloadAllMediaRequest) { + try { + mediaService.createDownloadRequest(downloadAllMediaRequest); + return ResponseEntity.ok().body(""); + } catch (Exception exception) { + log.error("Error reading object: ", exception); + return ResponseEntity.internalServerError().body(exception.getMessage()); + } + } } diff --git a/src/main/java/org/avniproject/etl/dto/AddressLevelType.java b/src/main/java/org/avniproject/etl/dto/AddressLevelType.java new file mode 100644 index 0000000..3fd64d2 --- /dev/null +++ b/src/main/java/org/avniproject/etl/dto/AddressLevelType.java @@ -0,0 +1,4 @@ +package org.avniproject.etl.dto; + +public record AddressLevelType(String uuid, long id, String name, int level) { +} diff --git a/src/main/java/org/avniproject/etl/dto/DownloadAllMediaRequest.java b/src/main/java/org/avniproject/etl/dto/DownloadAllMediaRequest.java new file mode 100644 index 0000000..bbf09fb --- /dev/null +++ b/src/main/java/org/avniproject/etl/dto/DownloadAllMediaRequest.java @@ -0,0 +1,49 @@ +package org.avniproject.etl.dto; + +import java.util.List; + +public class DownloadAllMediaRequest { + private MediaSearchRequest mediaSearchRequest; + private String username; + private String description; + private List addressLevelTypes; + + public DownloadAllMediaRequest (MediaSearchRequest mediaSearchRequest, String username, String description, List addressLevelTypes){ + this.mediaSearchRequest = mediaSearchRequest; + this.username = username; + this.description = description; + this.addressLevelTypes = addressLevelTypes; + } + + public void setMediaSearchRequest(MediaSearchRequest mediaSearchRequest) { + this.mediaSearchRequest = mediaSearchRequest; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setAddressLevelTypes(List addressLevelTypes) { + this.addressLevelTypes = addressLevelTypes; + } + + public MediaSearchRequest getMediaSearchRequest() { + return (mediaSearchRequest == null) ? new MediaSearchRequest(): mediaSearchRequest; + } + + public String getUsername() { + return username; + } + + public String getDescription() { + return description; + } + + public List getAddressLevelTypes() { + return addressLevelTypes; + } +} diff --git a/src/main/java/org/avniproject/etl/dto/DownloadRequest.java b/src/main/java/org/avniproject/etl/dto/DownloadRequest.java new file mode 100644 index 0000000..9f865e4 --- /dev/null +++ b/src/main/java/org/avniproject/etl/dto/DownloadRequest.java @@ -0,0 +1,9 @@ +package org.avniproject.etl.dto; + +import java.util.List; + +public record DownloadRequest(String username, + String description, + List addressLevelTypes, + List data) { +} diff --git a/src/main/java/org/avniproject/etl/dto/ImageData.java b/src/main/java/org/avniproject/etl/dto/ImageData.java new file mode 100644 index 0000000..8adc208 --- /dev/null +++ b/src/main/java/org/avniproject/etl/dto/ImageData.java @@ -0,0 +1,17 @@ +package org.avniproject.etl.dto; + +public record ImageData( + String uuid, + String subjectFirstName, + String subjectLastName, + String url, + String conceptName, + String subjectTypeName, + String programEnrolment, + String encounterTypeName, + String syncConcept1Name, + String syncConcept2Name, + String syncParameterValue1, + String syncParameterValue2, + String address) { +} diff --git a/src/main/java/org/avniproject/etl/repository/MediaTableRepository.java b/src/main/java/org/avniproject/etl/repository/MediaTableRepository.java index bb58df8..1f7777b 100644 --- a/src/main/java/org/avniproject/etl/repository/MediaTableRepository.java +++ b/src/main/java/org/avniproject/etl/repository/MediaTableRepository.java @@ -3,10 +3,7 @@ import org.avniproject.etl.domain.metadata.ColumnMetadata; import org.avniproject.etl.domain.metadata.SchemaMetadata; import org.avniproject.etl.domain.metadata.TableMetadata; -import org.avniproject.etl.dto.ConceptFilter; -import org.avniproject.etl.dto.ConceptFilterSearch; -import org.avniproject.etl.dto.MediaDTO; -import org.avniproject.etl.dto.MediaSearchRequest; +import org.avniproject.etl.dto.*; import org.avniproject.etl.repository.service.MediaTableRepositoryService; import org.avniproject.etl.repository.sql.MediaSearchQueryBuilder; import org.avniproject.etl.repository.sql.Page; @@ -15,6 +12,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Repository; @@ -78,6 +76,10 @@ private List determineConceptFilterTablesAndColumns(List search(MediaSearchRequest mediaSearchRequest, Page page) { + return searchInternal(mediaSearchRequest, page, (rs, rowNum) -> mediaTableRepositoryService.setMediaDto(rs)); + } + + private List searchInternal(MediaSearchRequest mediaSearchRequest, Page page, RowMapper rowMapper) { List conceptFilterSearches = null; if (mediaSearchRequest.getConceptFilters() != null) { conceptFilterSearches = determineConceptFilterTablesAndColumns(mediaSearchRequest.getConceptFilters()); @@ -89,7 +91,12 @@ public List search(MediaSearchRequest mediaSearchRequest, Page page) { .withSearchConceptFilters(conceptFilterSearches) .build(); return runInSchemaUserContext(() -> new NamedParameterJdbcTemplate(jdbcTemplate) - .query(query.sql(), query.parameters(), - (rs, rowNum) -> mediaTableRepositoryService.setMediaDto(rs)), jdbcTemplate); + .query(query.sql(), query.parameters(), rowMapper), jdbcTemplate); + } + + + + public List getImageData(MediaSearchRequest mediaSearchRequest, Page page) { + return searchInternal(mediaSearchRequest, page, (rs, rowNum) -> mediaTableRepositoryService.setImageData(rs)); } } diff --git a/src/main/java/org/avniproject/etl/repository/service/MediaTableRepositoryService.java b/src/main/java/org/avniproject/etl/repository/service/MediaTableRepositoryService.java index accc845..4801461 100644 --- a/src/main/java/org/avniproject/etl/repository/service/MediaTableRepositoryService.java +++ b/src/main/java/org/avniproject/etl/repository/service/MediaTableRepositoryService.java @@ -1,6 +1,7 @@ package org.avniproject.etl.repository.service; import org.avniproject.etl.config.AmazonClientService; +import org.avniproject.etl.dto.ImageData; import org.avniproject.etl.dto.MediaDTO; import org.avniproject.etl.util.Utils; import org.springframework.stereotype.Service; @@ -49,4 +50,24 @@ public MediaDTO setMediaDto(ResultSet rs) { throw new Error("Error:" + e.getMessage()); } } + + public ImageData setImageData(ResultSet rs) { + try { + return new ImageData(rs.getString("uuid"), + rs.getString("subject_first_name"), + rs.getString("subject_last_name"), + rs.getString("image_url"), + rs.getString("concept_name"), + rs.getString("subject_type_name"), + rs.getString("program_name"), + rs.getString("encounter_type_name"), + rs.getString("sync_parameter_key1"), + rs.getString("sync_parameter_key2"), + rs.getString("sync_parameter_value1"), + rs.getString("sync_parameter_value2"), + rs.getString("address")); + }catch(SQLException e) { + throw new Error("Error:" + e.getMessage()); + } + } } diff --git a/src/main/java/org/avniproject/etl/service/MediaService.java b/src/main/java/org/avniproject/etl/service/MediaService.java index 5494c5d..f32562b 100644 --- a/src/main/java/org/avniproject/etl/service/MediaService.java +++ b/src/main/java/org/avniproject/etl/service/MediaService.java @@ -1,24 +1,33 @@ package org.avniproject.etl.service; -import org.avniproject.etl.dto.MediaSearchRequest; -import org.avniproject.etl.dto.ResponseDTO; +import org.avniproject.etl.dto.*; import org.avniproject.etl.repository.AddressRepository; import org.avniproject.etl.repository.MediaTableRepository; import org.avniproject.etl.repository.sql.Page; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.client.RestTemplate; + +import java.util.List; @Service public class MediaService { private final MediaTableRepository mediaTableRepository; private final AddressRepository addressRepository; + private final RestTemplate restTemplate; + + @Value("${media.server.downloadRequestURL}") + private String mediaServerDownloadRequestURL; @Autowired public MediaService(MediaTableRepository mediaTableRepository, AddressRepository addressRepository) { this.mediaTableRepository = mediaTableRepository; this.addressRepository = addressRepository; + this.restTemplate = new RestTemplate(); } @Transactional (readOnly = true) @@ -29,4 +38,20 @@ public ResponseDTO search(MediaSearchRequest mediaSearchRequest, Page page) { throw new IllegalArgumentException("Address level type names are incorrect"); } + + public void createDownloadRequest(DownloadAllMediaRequest downloadAllMediaRequest) { + MediaSearchRequest mediaSearchRequest = downloadAllMediaRequest.getMediaSearchRequest(); + if (addressRepository.doAllAddressLevelTypeNamesExist(mediaSearchRequest.getAddressLevelTypes())) { + Page page = new Page(0, 1000); + List imageData = mediaTableRepository.getImageData(mediaSearchRequest, page); + DownloadRequest downloadRequest = new DownloadRequest(downloadAllMediaRequest.getUsername(), + downloadAllMediaRequest.getDescription(), + downloadAllMediaRequest.getAddressLevelTypes(), + imageData); + HttpEntity request = new HttpEntity<>(downloadRequest); + restTemplate.postForLocation(mediaServerDownloadRequestURL, request); + return; + } + throw new IllegalArgumentException("Address level type names are incorrect"); + } } diff --git a/src/main/resources/main-application.properties b/src/main/resources/main-application.properties index 9721c2f..367aac4 100644 --- a/src/main/resources/main-application.properties +++ b/src/main/resources/main-application.properties @@ -53,3 +53,6 @@ spring.security.user.name=admin spring.security.user.password=secret avni.defaultUserName=${OPENCHS_USER_NAME:admin} + +#MediaServer +media.server.downloadRequestURL=${AVNI_MEDIA_SERVER_DOWNLOAD_URL:http://localhost:3010/media-viewer/requestDownload} \ No newline at end of file diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index e48e3fb..c393a95 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -22,3 +22,5 @@ avni.keycloak.realms=%s/realms/%s avni.keycloak.realm=dummy avni.idp.type=${AVNI_IDP_TYPE:none} + +media.server.downloadRequestURL=dummy \ No newline at end of file