diff --git a/fda-citation-service/api/src/main/java/at/tuwien/api/zenodo/files/FileResponseDto.java b/fda-citation-service/api/src/main/java/at/tuwien/api/zenodo/files/FileResponseDto.java index 5ffd7b599e11014dd8d8bb89f9797b6bcc462860..78928a91a945b31780f418c3b94e12b97ba524ea 100644 --- a/fda-citation-service/api/src/main/java/at/tuwien/api/zenodo/files/FileResponseDto.java +++ b/fda-citation-service/api/src/main/java/at/tuwien/api/zenodo/files/FileResponseDto.java @@ -15,6 +15,8 @@ public class FileResponseDto { private Long filesize; + private Boolean locked; + private String id; private FileLinksDto links; diff --git a/fda-citation-service/rest-service/src/main/java/at/tuwien/endpoints/FileEndpoint.java b/fda-citation-service/rest-service/src/main/java/at/tuwien/endpoints/FileEndpoint.java index 60b58785eb4f3baa4da37f2ee7fb03c3fbe1c581..02a2983ed826439adcb65668f8a18e4da1972e3b 100644 --- a/fda-citation-service/rest-service/src/main/java/at/tuwien/endpoints/FileEndpoint.java +++ b/fda-citation-service/rest-service/src/main/java/at/tuwien/endpoints/FileEndpoint.java @@ -31,7 +31,7 @@ public class FileEndpoint { @Valid @RequestParam("tableId") Long tableId) throws MetadataDatabaseNotFoundException, ZenodoAuthenticationException, ZenodoApiException, ZenodoNotFoundException { - return fileService.listAll(databaseId, tableId); + return fileService.listResources(databaseId, tableId); } // public FileResponseDto find(@Valid @RequestParam("id") Long databaseId, diff --git a/fda-citation-service/rest-service/src/test/java/at/tuwien/service/FileServiceIntegrationTest.java b/fda-citation-service/rest-service/src/test/java/at/tuwien/service/FileServiceIntegrationTest.java index cc18b5b1a3219b669f7ea08a41ac8620982b8b1a..60ad10ce01b044b3f6a0824d04b8e9a805bdb603 100644 --- a/fda-citation-service/rest-service/src/test/java/at/tuwien/service/FileServiceIntegrationTest.java +++ b/fda-citation-service/rest-service/src/test/java/at/tuwien/service/FileServiceIntegrationTest.java @@ -8,20 +8,27 @@ import at.tuwien.config.ReadyConfig; import at.tuwien.entities.database.table.Table; import at.tuwien.exception.*; import at.tuwien.repository.jpa.TableRepository; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.util.ResourceUtils; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; +import java.util.List; import java.util.Optional; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @SpringBootTest @@ -55,7 +62,7 @@ public class FileServiceIntegrationTest extends BaseUnitTest { final Table TABLE_1 = Table.builder() .id(TABLE_1_ID) .depositId(deposit.getId()) - .build();; + .build(); when(tableRepository.findById(TABLE_1_ID)) .thenReturn(Optional.of(TABLE_1)); @@ -101,8 +108,91 @@ public class FileServiceIntegrationTest extends BaseUnitTest { /* test */ assertThrows(ZenodoNotFoundException.class, () -> { - fileService.listAll(DATABASE_1_ID, TABLE_1_ID); + fileService.listResources(DATABASE_1_ID, TABLE_1_ID); }); } + @Test + public void listAll_succeeds() throws MetadataDatabaseNotFoundException, ZenodoApiException, + ZenodoNotFoundException, ZenodoAuthenticationException, FileNotFoundException, ZenodoFileTooLargeException { + final File file = ResourceUtils.getFile("classpath:csv/testdata.csv"); + + /* request */ + final DepositChangeResponseDto deposit = metadataService.storeCitation(); + final FileUploadDto upload = FileUploadDto.builder() + .name(FILE_1_NAME) + .build(); + final Table TABLE_1 = Table.builder() + .id(TABLE_1_ID) + .depositId(deposit.getId()) + .build(); + when(tableRepository.findById(TABLE_1_ID)) + .thenReturn(Optional.of(TABLE_1)); + final FileResponseDto fileResponse = fileService.createResource(DATABASE_1_ID, TABLE_1_ID, upload, file); + + /* mock */ + when(tableRepository.findById(TABLE_1_ID)) + .thenReturn(Optional.of(TABLE_1)); + + /* test */ + final List<FileResponseDto> listResponse = fileService.listResources(DATABASE_1_ID, TABLE_1_ID); + assertEquals(1, listResponse.size()); + assertEquals(FILE_1_CHECKSUM, listResponse.get(0).getChecksum()); + assertEquals(fileResponse.getId(), listResponse.get(0).getId()); + } + + @Test + public void findResource_noContent_fails() throws MetadataDatabaseNotFoundException, ZenodoApiException, + ZenodoFileTooLargeException, ZenodoNotFoundException, ZenodoAuthenticationException, FileNotFoundException { + final File file = ResourceUtils.getFile("classpath:csv/testdata.csv"); + + /* request */ + final DepositChangeResponseDto deposit = metadataService.storeCitation(); + final FileUploadDto upload = FileUploadDto.builder() + .name(FILE_1_NAME) + .build(); + final Table TABLE_1 = Table.builder() + .id(TABLE_1_ID) + .depositId(deposit.getId()) + .build(); + when(tableRepository.findById(TABLE_1_ID)) + .thenReturn(Optional.of(TABLE_1)); + final FileResponseDto fileResponse = fileService.createResource(DATABASE_1_ID, TABLE_1_ID, upload, file); + + /* mock */ + when(tableRepository.findById(TABLE_1_ID)) + .thenReturn(Optional.of(TABLE_1)); + + /* test */ + final FileResponseDto findResponse = fileService.findResource(DATABASE_1_ID, TABLE_1_ID, fileResponse.getId()); + assertEquals(FILE_1_CHECKSUM, findResponse.getChecksum()); + assertEquals(fileResponse.getId(), findResponse.getId()); + } + + @Test + public void deleteRessource_succeeds() throws MetadataDatabaseNotFoundException, ZenodoApiException, + ZenodoFileTooLargeException, ZenodoNotFoundException, ZenodoAuthenticationException, FileNotFoundException { + final File file = ResourceUtils.getFile("classpath:csv/testdata.csv"); + + /* request */ + final DepositChangeResponseDto deposit = metadataService.storeCitation(); + final FileUploadDto upload = FileUploadDto.builder() + .name(FILE_1_NAME) + .build(); + final Table TABLE_1 = Table.builder() + .id(TABLE_1_ID) + .depositId(deposit.getId()) + .build(); + when(tableRepository.findById(TABLE_1_ID)) + .thenReturn(Optional.of(TABLE_1)); + final FileResponseDto fileResponse = fileService.createResource(DATABASE_1_ID, TABLE_1_ID, upload, file); + + /* mock */ + when(tableRepository.findById(TABLE_1_ID)) + .thenReturn(Optional.of(TABLE_1)); + + /* test */ + fileService.deleteResource(DATABASE_1_ID, TABLE_1_ID, fileResponse.getId()); + } + } \ No newline at end of file diff --git a/fda-citation-service/rest-service/src/test/java/at/tuwien/service/FileServiceUnitTest.java b/fda-citation-service/rest-service/src/test/java/at/tuwien/service/FileServiceUnitTest.java index f4cf2e7f547e406aa38a3760cdc6664ee45be3ed..30c1bc835a1cb37e11bea7f4a6bce137523f3be4 100644 --- a/fda-citation-service/rest-service/src/test/java/at/tuwien/service/FileServiceUnitTest.java +++ b/fda-citation-service/rest-service/src/test/java/at/tuwien/service/FileServiceUnitTest.java @@ -1,7 +1,6 @@ package at.tuwien.service; import at.tuwien.BaseUnitTest; -import at.tuwien.api.zenodo.deposit.DepositResponseDto; import at.tuwien.api.zenodo.files.FileResponseDto; import at.tuwien.api.zenodo.files.FileUploadDto; import at.tuwien.config.ReadyConfig; @@ -124,13 +123,14 @@ public class FileServiceUnitTest extends BaseUnitTest { ZenodoNotFoundException, ZenodoAuthenticationException { /* mock */ - when(apiTemplate.exchange(anyString(), eq(HttpMethod.GET), Mockito.any(), eq(FileResponseDto[].class), eq(DEPOSIT_1_ID), anyString())) + when(apiTemplate.exchange(anyString(), eq(HttpMethod.GET), Mockito.any(), eq(FileResponseDto[].class), + eq(DEPOSIT_1_ID), anyString())) .thenReturn(ResponseEntity.ok().body(new FileResponseDto[]{FILE_1})); when(tableRepository.findById(TABLE_1_ID)) .thenReturn(Optional.of(TABLE_1)); /* test */ - final List<FileResponseDto> response = fileService.listAll(DATABASE_1_ID, TABLE_1_ID); + final List<FileResponseDto> response = fileService.listResources(DATABASE_1_ID, TABLE_1_ID); assertEquals(1, response.size()); } @@ -138,14 +138,15 @@ public class FileServiceUnitTest extends BaseUnitTest { public void listAll_noContent_fails() { /* mock */ - when(apiTemplate.exchange(anyString(), eq(HttpMethod.GET), Mockito.any(), eq(FileResponseDto[].class), eq(DEPOSIT_1_ID), anyString())) + when(apiTemplate.exchange(anyString(), eq(HttpMethod.GET), Mockito.any(), eq(FileResponseDto[].class), + eq(DEPOSIT_1_ID), anyString())) .thenReturn(ResponseEntity.ok().body(null)); when(tableRepository.findById(TABLE_1_ID)) .thenReturn(Optional.of(TABLE_1)); /* test */ assertThrows(ZenodoApiException.class, () -> { - fileService.listAll(DATABASE_1_ID, TABLE_1_ID); + fileService.listResources(DATABASE_1_ID, TABLE_1_ID); }); } @@ -158,7 +159,86 @@ public class FileServiceUnitTest extends BaseUnitTest { /* test */ assertThrows(MetadataDatabaseNotFoundException.class, () -> { - fileService.listAll(DATABASE_1_ID, 9999L); + fileService.listResources(DATABASE_1_ID, 9999L); + }); + } + + @Test + public void findResource_succeeds() throws MetadataDatabaseNotFoundException, ZenodoApiException, + ZenodoNotFoundException, ZenodoAuthenticationException { + + /* mock */ + when(apiTemplate.exchange(anyString(), eq(HttpMethod.GET), Mockito.any(), eq(FileResponseDto.class), + eq(DEPOSIT_1_ID), eq(FILE_1_ID), anyString())) + .thenReturn(ResponseEntity.ok().body(FILE_1)); + when(tableRepository.findById(TABLE_1_ID)) + .thenReturn(Optional.of(TABLE_1)); + + /* test */ + final FileResponseDto file = fileService.findResource(DATABASE_1_ID, TABLE_1_ID, FILE_1_ID); + assertEquals(FILE_1_ID, file.getId()); + assertEquals(FILE_1_NAME, file.getFilename()); + assertEquals(FILE_1_SIZE, file.getFilesize()); + assertEquals(FILE_1_CHECKSUM, file.getChecksum()); + } + + @Test + public void findResource_noContent_fails() { + + /* mock */ + when(apiTemplate.exchange(anyString(), eq(HttpMethod.GET), Mockito.any(), eq(FileResponseDto.class), + eq(DEPOSIT_1_ID), eq(FILE_1_ID), anyString())) + .thenReturn(ResponseEntity.ok().body(null)); + when(tableRepository.findById(TABLE_1_ID)) + .thenReturn(Optional.of(TABLE_1)); + + /* test */ + assertThrows(ZenodoApiException.class, () -> { + fileService.findResource(DATABASE_1_ID, TABLE_1_ID, FILE_1_ID); + }); + } + + @Test + public void findResource_notFound_fails() { + + /* mock */ + when(tableRepository.findById(TABLE_1_ID)) + .thenReturn(Optional.empty()); + + /* test */ + assertThrows(MetadataDatabaseNotFoundException.class, () -> { + fileService.findResource(DATABASE_1_ID, TABLE_1_ID, FILE_1_ID); + }); + } + + @Test + public void deleteResource_succeeds() throws MetadataDatabaseNotFoundException, ZenodoApiException, + ZenodoNotFoundException, ZenodoAuthenticationException { + + /* mock */ + when(apiTemplate.exchange(anyString(), eq(HttpMethod.DELETE), Mockito.any(), eq(String.class), + eq(DEPOSIT_1_ID), eq(FILE_1_ID), anyString())) + .thenReturn(ResponseEntity.status(HttpStatus.NO_CONTENT).build()); + when(tableRepository.findById(TABLE_1_ID)) + .thenReturn(Optional.of(TABLE_1)); + + /* test */ + fileService.deleteResource(DATABASE_1_ID, TABLE_1_ID, FILE_1_ID); + } + + @Test + public void deleteResource_wrongStatus_fails() { + + /* mock */ + when(apiTemplate.exchange(anyString(), eq(HttpMethod.DELETE), Mockito.any(), eq(String.class), + eq(DEPOSIT_1_ID), eq(FILE_1_ID), anyString())) + .thenReturn(ResponseEntity.status(HttpStatus.OK).build()); + when(tableRepository.findById(TABLE_1_ID)) + .thenReturn(Optional.of(TABLE_1)); + + /* test */ + assertThrows(ZenodoApiException.class, () -> { + fileService.deleteResource(DATABASE_1_ID, TABLE_1_ID, FILE_1_ID); }); } diff --git a/fda-citation-service/services/src/main/java/at/tuwien/service/FileService.java b/fda-citation-service/services/src/main/java/at/tuwien/service/FileService.java index 33156ab397f5e935ff2e4948b6c55ae9e18b6f2d..659b8d125d47cf5db3f251782edf11f2a74db570 100644 --- a/fda-citation-service/services/src/main/java/at/tuwien/service/FileService.java +++ b/fda-citation-service/services/src/main/java/at/tuwien/service/FileService.java @@ -15,5 +15,11 @@ public interface FileService { throws ZenodoAuthenticationException, ZenodoApiException, ZenodoNotFoundException, ZenodoFileTooLargeException, MetadataDatabaseNotFoundException; - List<FileResponseDto> listAll(Long databaseId, Long tableId) throws MetadataDatabaseNotFoundException, ZenodoAuthenticationException, ZenodoNotFoundException, ZenodoApiException; + List<FileResponseDto> listResources(Long databaseId, Long tableId) throws MetadataDatabaseNotFoundException, ZenodoAuthenticationException, ZenodoNotFoundException, ZenodoApiException; + + FileResponseDto findResource(Long databaseId, Long tableId, String fileId) throws MetadataDatabaseNotFoundException, ZenodoAuthenticationException, ZenodoNotFoundException, ZenodoApiException; + + void deleteResource(Long databaseId, Long tableId, String fileId) + throws MetadataDatabaseNotFoundException, ZenodoAuthenticationException, ZenodoNotFoundException, + ZenodoApiException; } diff --git a/fda-citation-service/services/src/main/java/at/tuwien/service/ZenodoFileService.java b/fda-citation-service/services/src/main/java/at/tuwien/service/ZenodoFileService.java index d742822a0e9383a45a097021b6f581213b61b2d3..043318be0e077c82e76b08e6ee9fd63b60279ed2 100644 --- a/fda-citation-service/services/src/main/java/at/tuwien/service/ZenodoFileService.java +++ b/fda-citation-service/services/src/main/java/at/tuwien/service/ZenodoFileService.java @@ -50,12 +50,13 @@ public class ZenodoFileService implements FileService { zenodoMapper.resourceToHttpEntity(data.getName(), resource), FileResponseDto.class, table.getDepositId(), zenodoConfig.getApiKey()); } catch (IOException e) { throw new ZenodoApiException("Could not map file to byte array"); - } - if (response.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) { + } catch (HttpClientErrorException.Unauthorized e) { throw new ZenodoAuthenticationException("Token is missing or invalid."); + } catch (HttpClientErrorException.BadRequest e) { + throw new ZenodoNotFoundException("Did not find the resource with this id"); } if (response.getStatusCode().equals(HttpStatus.BAD_REQUEST)) { - throw new ZenodoNotFoundException("Did not find the deposit with this id"); + throw new ZenodoNotFoundException("Did not find the resource with this id"); } if (response.getBody() == null) { throw new ZenodoApiException("Endpoint returned null body"); @@ -64,7 +65,7 @@ public class ZenodoFileService implements FileService { } @Override - public List<FileResponseDto> listAll(Long databaseId, Long tableId) throws MetadataDatabaseNotFoundException, + public List<FileResponseDto> listResources(Long databaseId, Long tableId) throws MetadataDatabaseNotFoundException, ZenodoAuthenticationException, ZenodoNotFoundException, ZenodoApiException { final Table table = getTable(tableId); final ResponseEntity<FileResponseDto[]> response; @@ -72,20 +73,56 @@ public class ZenodoFileService implements FileService { response = apiTemplate.exchange("/api/deposit/depositions/{deposit_id}/files?access_token={token}", HttpMethod.GET, addHeaders(null), FileResponseDto[].class, table.getDepositId(), zenodoConfig.getApiKey()); } catch (HttpClientErrorException.NotFound e) { - throw new ZenodoNotFoundException("Did not find the deposit with this id"); - } - if (response.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) { + throw new ZenodoNotFoundException("Did not find the resoource with this id"); + } catch (HttpClientErrorException.Unauthorized e) { throw new ZenodoAuthenticationException("Token is missing or invalid."); } - if (response.getStatusCode().equals(HttpStatus.NOT_FOUND)) { - throw new ZenodoNotFoundException("Did not find the deposit with this id"); - } if (response.getBody() == null) { throw new ZenodoApiException("Endpoint returned null body"); } return Arrays.asList(response.getBody()); } + @Override + public FileResponseDto findResource(Long databaseId, Long tableId, String fileId) + throws MetadataDatabaseNotFoundException, ZenodoAuthenticationException, ZenodoNotFoundException, + ZenodoApiException { + final Table table = getTable(tableId); + final ResponseEntity<FileResponseDto> response; + try { + response = apiTemplate.exchange("/api/deposit/depositions/{deposit_id}/files/{file_id}?access_token={token}", + HttpMethod.GET, addHeaders(null), FileResponseDto.class, table.getDepositId(), fileId, + zenodoConfig.getApiKey()); + } catch (HttpClientErrorException.NotFound e) { + throw new ZenodoNotFoundException("Did not find the resoource with this ID"); + } catch (HttpClientErrorException.Unauthorized e) { + throw new ZenodoAuthenticationException("Token is missing or invalid."); + } + if (response.getBody() == null) { + throw new ZenodoApiException("Endpoint returned null body"); + } + return response.getBody(); + } + + @Override + public void deleteResource(Long databaseId, Long tableId, String fileId) + throws MetadataDatabaseNotFoundException, ZenodoAuthenticationException, ZenodoNotFoundException, ZenodoApiException { + final Table table = getTable(tableId); + final ResponseEntity<String> response; + try { + response = apiTemplate.exchange("/api/deposit/depositions/{deposit_id}/files/{file_id}?access_token={token}", + HttpMethod.DELETE, addHeaders(null), String.class, table.getDepositId(), fileId, + zenodoConfig.getApiKey()); + } catch (HttpClientErrorException.NotFound e) { + throw new ZenodoNotFoundException("Did not find the resource with this ID"); + } catch (HttpClientErrorException.Unauthorized e) { + throw new ZenodoAuthenticationException("Token is missing or invalid."); + } + if (!response.getStatusCode().equals(HttpStatus.NO_CONTENT)) { + throw new ZenodoApiException("Failed to delete the resource with this ID"); + } + } + /** * Wrapper function to throw error when table with id was not found *