Skip to content
Snippets Groups Projects
Unverified Commit 1b393c6b authored by Martin Weise's avatar Martin Weise
Browse files

transaction handling fixed

parent 4ed9f348
Branches
Tags
3 merge requests!81New stable release,!43Merge dev to master,!27Draft: Resolve "Zenodo Sandbox integration for PID (e.g. DOI)"
Showing
with 347 additions and 108 deletions
......@@ -29,6 +29,7 @@
<swagger.version>2.1.7</swagger.version>
<springfox.version>3.0.0</springfox.version>
<jacoco.version>0.8.7</jacoco.version>
<javax-ws-rs.version>2.1.1</javax-ws-rs.version>
</properties>
<dependencies>
......@@ -49,6 +50,11 @@
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>${spring-cloud.version}</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>${javax-ws-rs.version}</version>
</dependency>
<!-- Entities and API -->
<dependency>
<groupId>at.tuwien</groupId>
......
package at.tuwien.endpoints;
import at.tuwien.api.zenodo.files.FileResponseDto;
import at.tuwien.exception.MetadataDatabaseNotFoundException;
import at.tuwien.exception.ZenodoApiException;
import at.tuwien.exception.ZenodoAuthenticationException;
import at.tuwien.exception.ZenodoNotFoundException;
import at.tuwien.api.zenodo.files.FileUploadDto;
import at.tuwien.exception.*;
import at.tuwien.service.FileService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;
@Log4j2
@CrossOrigin(origins = "*")
@RestController
@RequestMapping("/api/database/{id}/table/{tableid}/file")
@RequestMapping("/api/database/{id}/table/{tableid}/deposit/file")
public class FileEndpoint {
private final FileService fileService;
......@@ -34,23 +34,36 @@ public class FileEndpoint {
return fileService.listResources(databaseId, tableId);
}
// public FileResponseDto find(@Valid @RequestParam("id") Long databaseId,
// @Valid @RequestParam("tableId") Long tableId) {
//
// }
//
// public FileResponseDto create(@Valid @RequestParam("id") Long databaseId,
// @Valid @RequestParam("tableId") Long tableId) {
//
// }
//
// public FileResponseDto update(@Valid @RequestParam("id") Long databaseId,
// @Valid @RequestParam("tableId") Long tableId) {
//
// }
//
// public FileResponseDto delete(@Valid @RequestParam("id") Long databaseId,
// @Valid @RequestParam("tableId") Long tableId) {
//
// }
@GetMapping("/{fileId}")
public FileResponseDto find(@Valid @RequestParam("id") Long databaseId,
@Valid @RequestParam("tableId") Long tableId,
@NotBlank @RequestParam("fileId") String fileId)
throws MetadataDatabaseNotFoundException, ZenodoApiException, ZenodoNotFoundException,
ZenodoAuthenticationException {
return fileService.findResource(databaseId, tableId, fileId);
}
@PostMapping
public FileResponseDto create(@Valid @RequestParam("id") Long databaseId,
@Valid @RequestParam("tableId") Long tableId,
@Valid @RequestParam("data") FileUploadDto data,
@Valid @RequestParam("file") MultipartFile file)
throws MetadataDatabaseNotFoundException, ZenodoApiException, ZenodoFileTooLargeException,
ZenodoNotFoundException, ZenodoAuthenticationException {
return fileService.createResource(databaseId, tableId, data, file);
}
@PutMapping("/{fileId}")
public FileResponseDto update(@Valid @RequestParam("id") Long databaseId,
@Valid @RequestParam("tableId") Long tableId,
@NotBlank @RequestParam("fileId") String fileId) {
return null;
}
@DeleteMapping("/{fileId}")
public FileResponseDto delete(@Valid @RequestParam("id") Long databaseId,
@Valid @RequestParam("tableId") Long tableId,
@NotBlank @RequestParam("fileId") String fileId) {
return null;
}
}
package at.tuwien.endpoints;
import at.tuwien.api.zenodo.deposit.DepositChangeRequestDto;
import at.tuwien.api.zenodo.deposit.DepositChangeResponseDto;
import at.tuwien.api.zenodo.deposit.DepositResponseDto;
import at.tuwien.exception.MetadataDatabaseNotFoundException;
import at.tuwien.exception.ZenodoApiException;
import at.tuwien.exception.ZenodoAuthenticationException;
import at.tuwien.exception.ZenodoNotFoundException;
import at.tuwien.service.MetadataService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;
@Log4j2
@CrossOrigin(origins = "*")
@RestController
@RequestMapping("/api/database/{id}/table/{tableid}/metadata")
@RequestMapping("/api/database/{id}/table/{tableid}/deposit/metadata")
public class MetadataEndpoint {
private final MetadataService citationService;
private final MetadataService metadataService;
@Autowired
public MetadataEndpoint(MetadataService citationService) {
this.citationService = citationService;
public MetadataEndpoint(MetadataService metadataService) {
this.metadataService = metadataService;
}
@GetMapping
public List<DepositResponseDto> findAll(@Valid @RequestParam("id") Long databaseId,
@Valid @RequestParam("tableId") Long tableId) throws ZenodoApiException,
ZenodoAuthenticationException, MetadataDatabaseNotFoundException {
return metadataService.listCitations(databaseId, tableId);
}
@PostMapping
public DepositChangeResponseDto create(@Valid @RequestParam("id") Long databaseId,
@Valid @RequestParam("tableId") Long tableId) throws ZenodoApiException,
ZenodoAuthenticationException, MetadataDatabaseNotFoundException {
return metadataService.storeCitation(databaseId, tableId);
}
@GetMapping("/{fileId}")
public DepositResponseDto find(@Valid @RequestParam("id") Long databaseId,
@Valid @RequestParam("tableId") Long tableId)
throws MetadataDatabaseNotFoundException, ZenodoApiException, ZenodoNotFoundException,
ZenodoAuthenticationException {
return metadataService.findCitation(databaseId, tableId);
}
@PutMapping("/{fileId}")
public DepositChangeResponseDto update(@Valid @RequestParam("id") Long databaseId,
@Valid @RequestParam("tableId") Long tableId,
@Valid @RequestBody DepositChangeRequestDto data)
throws MetadataDatabaseNotFoundException, ZenodoApiException, ZenodoNotFoundException,
ZenodoAuthenticationException {
return metadataService.updateCitation(databaseId, tableId, data);
}
@DeleteMapping("/{fileId}")
public void delete(@Valid @RequestParam("id") Long databaseId,
@Valid @RequestParam("tableId") Long tableId,
@NotBlank @RequestParam("fileId") String fileId) throws MetadataDatabaseNotFoundException,
ZenodoApiException, ZenodoAuthenticationException {
metadataService.deleteCitation(databaseId, tableId);
}
}
......@@ -8,27 +8,21 @@ 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.apache.commons.io.FileUtils;
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.mock.web.MockMultipartFile;
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.*;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@SpringBootTest
......@@ -50,10 +44,11 @@ public class FileServiceIntegrationTest extends BaseUnitTest {
@Test
public void createResource_succeeds() throws IOException, ZenodoApiException, ZenodoNotFoundException,
ZenodoAuthenticationException, ZenodoFileTooLargeException, MetadataDatabaseNotFoundException {
final File file = ResourceUtils.getFile("classpath:csv/testdata.csv");
final MockMultipartFile file = new MockMultipartFile("testdata.csv", FileUtils.readFileToByteArray(
ResourceUtils.getFile("classpath:csv/testdata.csv")));
/* request */
final DepositChangeResponseDto deposit = metadataService.storeCitation();
final DepositChangeResponseDto deposit = metadataService.storeCitation(DATABASE_1_ID, TABLE_1_ID);
final FileUploadDto request = FileUploadDto.builder()
.name(FILE_1_NAME)
.build();
......@@ -76,10 +71,11 @@ public class FileServiceIntegrationTest extends BaseUnitTest {
@Test
public void createResource_largeFile_succeeds() throws IOException, ZenodoApiException, ZenodoNotFoundException,
ZenodoAuthenticationException, ZenodoFileTooLargeException, MetadataDatabaseNotFoundException {
final File file = ResourceUtils.getFile("classpath:csv/weatherAUS.csv");
final MockMultipartFile file = new MockMultipartFile("weatherAUS.csv", FileUtils.readFileToByteArray(
ResourceUtils.getFile("classpath:csv/weatherAUS.csv")));
/* request */
final DepositChangeResponseDto deposit = metadataService.storeCitation();
final DepositChangeResponseDto deposit = metadataService.storeCitation(DATABASE_1_ID, TABLE_1_ID);
final FileUploadDto request = FileUploadDto.builder()
.name(FILE_2_NAME)
.build();
......@@ -114,11 +110,12 @@ public class FileServiceIntegrationTest extends BaseUnitTest {
@Test
public void listAll_succeeds() throws MetadataDatabaseNotFoundException, ZenodoApiException,
ZenodoNotFoundException, ZenodoAuthenticationException, FileNotFoundException, ZenodoFileTooLargeException {
final File file = ResourceUtils.getFile("classpath:csv/testdata.csv");
ZenodoNotFoundException, ZenodoAuthenticationException, IOException, ZenodoFileTooLargeException {
final MockMultipartFile file = new MockMultipartFile("testdata.csv", FileUtils.readFileToByteArray(
ResourceUtils.getFile("classpath:csv/testdata.csv")));
/* request */
final DepositChangeResponseDto deposit = metadataService.storeCitation();
final DepositChangeResponseDto deposit = metadataService.storeCitation(DATABASE_1_ID, TABLE_1_ID);
final FileUploadDto upload = FileUploadDto.builder()
.name(FILE_1_NAME)
.build();
......@@ -143,11 +140,12 @@ public class FileServiceIntegrationTest extends BaseUnitTest {
@Test
public void findResource_noContent_fails() throws MetadataDatabaseNotFoundException, ZenodoApiException,
ZenodoFileTooLargeException, ZenodoNotFoundException, ZenodoAuthenticationException, FileNotFoundException {
final File file = ResourceUtils.getFile("classpath:csv/testdata.csv");
ZenodoFileTooLargeException, ZenodoNotFoundException, ZenodoAuthenticationException, IOException {
final MockMultipartFile file = new MockMultipartFile("testdata.csv", FileUtils.readFileToByteArray(
ResourceUtils.getFile("classpath:csv/testdata.csv")));
/* request */
final DepositChangeResponseDto deposit = metadataService.storeCitation();
final DepositChangeResponseDto deposit = metadataService.storeCitation(DATABASE_1_ID, TABLE_1_ID);
final FileUploadDto upload = FileUploadDto.builder()
.name(FILE_1_NAME)
.build();
......@@ -171,11 +169,12 @@ public class FileServiceIntegrationTest extends BaseUnitTest {
@Test
public void deleteRessource_succeeds() throws MetadataDatabaseNotFoundException, ZenodoApiException,
ZenodoFileTooLargeException, ZenodoNotFoundException, ZenodoAuthenticationException, FileNotFoundException {
final File file = ResourceUtils.getFile("classpath:csv/testdata.csv");
ZenodoFileTooLargeException, ZenodoNotFoundException, ZenodoAuthenticationException, IOException {
final MockMultipartFile file = new MockMultipartFile("testdata.csv", FileUtils.readFileToByteArray(
ResourceUtils.getFile("classpath:csv/testdata.csv")));
/* request */
final DepositChangeResponseDto deposit = metadataService.storeCitation();
final DepositChangeResponseDto deposit = metadataService.storeCitation(DATABASE_1_ID, TABLE_1_ID);
final FileUploadDto upload = FileUploadDto.builder()
.name(FILE_1_NAME)
.build();
......
......@@ -6,6 +6,7 @@ import at.tuwien.api.zenodo.files.FileUploadDto;
import at.tuwien.config.ReadyConfig;
import at.tuwien.exception.*;
import at.tuwien.repository.jpa.TableRepository;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
......@@ -16,12 +17,12 @@ import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ResourceUtils;
import org.springframework.web.client.RestTemplate;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
......@@ -51,7 +52,8 @@ public class FileServiceUnitTest extends BaseUnitTest {
@Test
public void createResource_succeeds() throws IOException, ZenodoApiException, ZenodoNotFoundException,
ZenodoAuthenticationException, ZenodoFileTooLargeException, MetadataDatabaseNotFoundException {
final File file = ResourceUtils.getFile("classpath:csv/testdata.csv");
final MockMultipartFile file = new MockMultipartFile("testdata.csv", FileUtils.readFileToByteArray(
ResourceUtils.getFile("classpath:csv/testdata.csv")));
/* mock */
when(apiTemplate.postForEntity(anyString(), Mockito.<MultiValueMap<String, HttpEntity<?>>>any(),
......@@ -75,7 +77,8 @@ public class FileServiceUnitTest extends BaseUnitTest {
@Test
public void createResource_notExists_fails() throws IOException {
final File file = ResourceUtils.getFile("classpath:csv/testdata.csv");
final MockMultipartFile file = new MockMultipartFile("testdata.csv", FileUtils.readFileToByteArray(
ResourceUtils.getFile("classpath:csv/testdata.csv")));
/* mock */
when(apiTemplate.postForEntity(anyString(), Mockito.<MultiValueMap<String, HttpEntity<?>>>any(),
......@@ -98,7 +101,8 @@ public class FileServiceUnitTest extends BaseUnitTest {
@Test
public void createResource_bodyEmpty_fails() throws IOException {
final File file = ResourceUtils.getFile("classpath:csv/testdata.csv");
final MockMultipartFile file = new MockMultipartFile("testdata.csv", FileUtils.readFileToByteArray(
ResourceUtils.getFile("classpath:csv/testdata.csv")));
/* mock */
when(apiTemplate.postForEntity(anyString(), Mockito.<MultiValueMap<String, HttpEntity<?>>>any(),
......
......@@ -3,9 +3,12 @@ package at.tuwien.service;
import at.tuwien.BaseUnitTest;
import at.tuwien.api.zenodo.deposit.*;
import at.tuwien.config.ReadyConfig;
import at.tuwien.entities.database.table.Table;
import at.tuwien.exception.MetadataDatabaseNotFoundException;
import at.tuwien.exception.ZenodoApiException;
import at.tuwien.exception.ZenodoAuthenticationException;
import at.tuwien.exception.ZenodoNotFoundException;
import at.tuwien.repository.jpa.TableRepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
......@@ -14,6 +17,10 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.util.Optional;
import static org.mockito.Mockito.when;
@SpringBootTest
@ExtendWith(SpringExtension.class)
public class MetadataServiceIntegrationTest extends BaseUnitTest {
......@@ -24,31 +31,43 @@ public class MetadataServiceIntegrationTest extends BaseUnitTest {
@Autowired
private ZenodoMetadataService zenodoService;
@MockBean
private TableRepository tableRepository;
@Test
public void listDeposit_succeeds() throws ZenodoApiException, ZenodoAuthenticationException {
/* test */
zenodoService.listCitations();
zenodoService.listCitations(DATABASE_1_ID, TABLE_1_ID);
}
@Test
public void createDeposit_succeeds() throws ZenodoApiException, ZenodoAuthenticationException {
public void createDeposit_succeeds() throws ZenodoApiException, ZenodoAuthenticationException,
MetadataDatabaseNotFoundException {
/* test */
final DepositChangeResponseDto response = zenodoService.storeCitation();
final DepositChangeResponseDto response = zenodoService.storeCitation(DATABASE_1_ID, TABLE_1_ID);
Assertions.assertNotNull(response.getId());
}
@Test
public void updateDeposit_succeeds() throws ZenodoApiException, ZenodoAuthenticationException,
ZenodoNotFoundException {
ZenodoNotFoundException, MetadataDatabaseNotFoundException {
final DepositChangeResponseDto deposit = zenodoService.storeCitation(DATABASE_1_ID, TABLE_1_ID);
final DepositChangeRequestDto request = DepositChangeRequestDto.builder()
.metadata(METADATA_1)
.build();
final DepositChangeResponseDto response = zenodoService.storeCitation();
/* mock */
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));
/* test */
final DepositChangeResponseDto response2 = zenodoService.updateCitation(response.getId(), request);
final DepositChangeResponseDto response2 = zenodoService.updateCitation(DATABASE_1_ID, TABLE_1_ID, request);
Assertions.assertNotNull(response2.getId());
Assertions.assertEquals(METADATA_1_TITLE, response2.getTitle());
Assertions.assertEquals(METADATA_1_TITLE, response2.getMetadata().getTitle());
......
......@@ -6,9 +6,11 @@ import at.tuwien.api.zenodo.deposit.DepositResponseDto;
import at.tuwien.api.zenodo.deposit.DepositChangeRequestDto;
import at.tuwien.api.zenodo.deposit.MetadataDto;
import at.tuwien.config.ReadyConfig;
import at.tuwien.exception.MetadataDatabaseNotFoundException;
import at.tuwien.exception.ZenodoApiException;
import at.tuwien.exception.ZenodoAuthenticationException;
import at.tuwien.exception.ZenodoNotFoundException;
import at.tuwien.repository.jpa.TableRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
......@@ -23,6 +25,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
......@@ -43,15 +46,19 @@ public class MetadataServiceUnitTest extends BaseUnitTest {
@MockBean
private RestTemplate apiTemplate;
@MockBean
private TableRepository tableRepository;
@Test
public void listCitations_succeeds() throws ZenodoApiException, ZenodoAuthenticationException {
/* mocks */
when(apiTemplate.exchange(anyString(), eq(HttpMethod.GET), Mockito.any(), eq(DepositResponseDto[].class), anyString()))
when(apiTemplate.exchange(anyString(), eq(HttpMethod.GET), Mockito.any(), eq(DepositResponseDto[].class),
anyString()))
.thenReturn(ResponseEntity.ok(new DepositResponseDto[]{DEPOSIT_2}));
/* test */
final List<DepositResponseDto> response = zenodoService.listCitations();
final List<DepositResponseDto> response = zenodoService.listCitations(DATABASE_1_ID, TABLE_1_ID);
assertEquals(1, response.size());
}
......@@ -59,61 +66,74 @@ public class MetadataServiceUnitTest extends BaseUnitTest {
public void listCitations_empty_fails() {
/* mocks */
when(apiTemplate.exchange(anyString(), eq(HttpMethod.GET), Mockito.any(), eq(DepositResponseDto[].class), anyString()))
when(apiTemplate.exchange(anyString(), eq(HttpMethod.GET), Mockito.any(), eq(DepositResponseDto[].class),
anyString()))
.thenReturn(ResponseEntity.ok().build());
/* test */
assertThrows(ZenodoApiException.class, () -> {
zenodoService.listCitations();
zenodoService.listCitations(DATABASE_1_ID, TABLE_1_ID);
});
}
@Test
public void storeCitation_succeed() throws ZenodoApiException, ZenodoAuthenticationException {
public void storeCitation_succeed() throws ZenodoApiException, ZenodoAuthenticationException,
MetadataDatabaseNotFoundException {
/* mocks */
when(apiTemplate.exchange(anyString(), eq(HttpMethod.POST), Mockito.<HttpEntity<String>>any(), eq(DepositChangeResponseDto.class), anyString()))
when(apiTemplate.exchange(anyString(), eq(HttpMethod.POST), Mockito.<HttpEntity<String>>any(), eq(DepositChangeResponseDto.class),
anyString()))
.thenReturn(ResponseEntity.status(HttpStatus.CREATED)
.body(DEPOSIT_1));
/* test */
final DepositChangeResponseDto response = zenodoService.storeCitation();
final DepositChangeResponseDto response = zenodoService.storeCitation(DATABASE_1_ID, TABLE_1_ID);
assertEquals(DEPOSIT_1_CREATED, response.getCreated());
assertEquals(DEPOSIT_1_MODIFIED, response.getModified());
}
@Test
public void deleteCitation_succeeds() throws ZenodoApiException, ZenodoAuthenticationException {
public void deleteCitation_succeeds() throws ZenodoApiException, ZenodoAuthenticationException,
MetadataDatabaseNotFoundException {
/* mocks */
when(apiTemplate.exchange(anyString(), eq(HttpMethod.DELETE), Mockito.any(), eq(String.class), anyLong(), anyString()))
when(tableRepository.findById(TABLE_1_ID))
.thenReturn(Optional.of(TABLE_1));
when(apiTemplate.exchange(anyString(), eq(HttpMethod.DELETE), Mockito.any(), eq(String.class), anyLong(),
anyString()))
.thenReturn(ResponseEntity.status(HttpStatus.CREATED)
.build());
/* test */
zenodoService.deleteCitation(DEPOSIT_1_ID);
zenodoService.deleteCitation(DATABASE_1_ID, TABLE_1_ID);
}
@Test
public void deleteCitation_fails() {
/* mocks */
when(apiTemplate.exchange(anyString(), eq(HttpMethod.DELETE), Mockito.any(), eq(String.class), anyLong(), anyString()))
when(tableRepository.findById(TABLE_1_ID))
.thenReturn(Optional.of(TABLE_1));
when(apiTemplate.exchange(anyString(), eq(HttpMethod.DELETE), Mockito.any(), eq(String.class), anyLong(),
anyString()))
.thenReturn(ResponseEntity.status(HttpStatus.OK)
.build());
/* test */
assertThrows(ZenodoApiException.class, () -> {
zenodoService.deleteCitation(DEPOSIT_1_ID);
zenodoService.deleteCitation(DATABASE_1_ID, TABLE_1_ID);
});
}
@Test
public void updateCitation_succeeds() throws ZenodoApiException, ZenodoAuthenticationException,
ZenodoNotFoundException {
ZenodoNotFoundException, MetadataDatabaseNotFoundException {
/* mocks */
when(apiTemplate.exchange(anyString(), eq(HttpMethod.PUT), Mockito.<HttpEntity<DepositChangeRequestDto>>any(), eq(DepositChangeResponseDto.class), eq(DEPOSIT_1_ID), anyString()))
when(tableRepository.findById(TABLE_1_ID))
.thenReturn(Optional.of(TABLE_1));
when(apiTemplate.exchange(anyString(), eq(HttpMethod.PUT), Mockito.<HttpEntity<DepositChangeRequestDto>>any(), eq(DepositChangeResponseDto.class),
eq(DEPOSIT_1_ID), anyString()))
.thenReturn(ResponseEntity.status(HttpStatus.OK)
.body(DEPOSIT_1));
......@@ -123,14 +143,17 @@ public class MetadataServiceUnitTest extends BaseUnitTest {
.build();
/* test */
zenodoService.updateCitation(DEPOSIT_1_ID, request);
zenodoService.updateCitation(DATABASE_1_ID, TABLE_1_ID, request);
}
@Test
public void updateCitation_only1orcid_fails() {
/* mocks */
when(apiTemplate.exchange(anyString(), eq(HttpMethod.PUT), Mockito.<HttpEntity<DepositChangeRequestDto>>any(), eq(DepositChangeResponseDto.class), eq(DEPOSIT_1_ID), anyString()))
when(tableRepository.findById(TABLE_1_ID))
.thenReturn(Optional.of(TABLE_1));
when(apiTemplate.exchange(anyString(), eq(HttpMethod.PUT), Mockito.<HttpEntity<DepositChangeRequestDto>>any(), eq(DepositChangeResponseDto.class),
eq(DEPOSIT_1_ID), anyString()))
.thenReturn(ResponseEntity.status(HttpStatus.BAD_REQUEST)
.build());
......@@ -143,7 +166,7 @@ public class MetadataServiceUnitTest extends BaseUnitTest {
/* test */
assertThrows(ZenodoNotFoundException.class, () -> {
zenodoService.updateCitation(DEPOSIT_1_ID, request);
zenodoService.updateCitation(DATABASE_1_ID, TABLE_1_ID, request);
});
}
......@@ -151,7 +174,10 @@ public class MetadataServiceUnitTest extends BaseUnitTest {
public void updateCitation_notExists_fails() {
/* mocks */
when(apiTemplate.exchange(anyString(), eq(HttpMethod.PUT), Mockito.<HttpEntity<DepositChangeRequestDto>>any(), eq(DepositChangeResponseDto.class), eq(DEPOSIT_1_ID), anyString()))
when(tableRepository.findById(TABLE_1_ID))
.thenReturn(Optional.of(TABLE_1));
when(apiTemplate.exchange(anyString(), eq(HttpMethod.PUT), Mockito.<HttpEntity<DepositChangeRequestDto>>any(), eq(DepositChangeResponseDto.class),
eq(DEPOSIT_1_ID), anyString()))
.thenReturn(ResponseEntity.status(HttpStatus.BAD_REQUEST)
.build());
......@@ -162,7 +188,30 @@ public class MetadataServiceUnitTest extends BaseUnitTest {
/* test */
assertThrows(ZenodoNotFoundException.class, () -> {
zenodoService.updateCitation(DEPOSIT_1_ID, request);
zenodoService.updateCitation(DATABASE_1_ID, TABLE_1_ID, request);
});
}
@Test
public void updateCitation_notFound_fails() {
/* mocks */
when(tableRepository.findById(TABLE_1_ID))
.thenReturn(Optional.empty());
when(apiTemplate.exchange(anyString(), eq(HttpMethod.PUT), Mockito.<HttpEntity<DepositChangeRequestDto>>any(),
eq(DepositChangeResponseDto.class),
eq(DEPOSIT_1_ID), anyString()))
.thenReturn(ResponseEntity.status(HttpStatus.BAD_REQUEST)
.build());
/* request */
final DepositChangeRequestDto request = DepositChangeRequestDto.builder()
.metadata(METADATA_1)
.build();
/* test */
assertThrows(MetadataDatabaseNotFoundException.class, () -> {
zenodoService.updateCitation(DATABASE_1_ID, TABLE_1_ID, request);
});
}
......
package at.tuwien.mapper;
import org.apache.commons.io.FileUtils;
import org.mapstruct.Mapper;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.List;
@Mapper(componentModel = "spring")
public interface ZenodoMapper {
default MultiValueMap<String, HttpEntity<?>> resourceToHttpEntity(String name, File resource) throws IOException {
default MultiValueMap<String, HttpEntity<?>> resourceToHttpEntity(String name, MultipartFile resource) throws IOException {
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
final HttpHeaders parts = new HttpHeaders();
parts.setContentType(MediaType.TEXT_PLAIN);
final ByteArrayResource byteArrayResource = new ByteArrayResource(FileUtils.readFileToByteArray(resource)) {
final ByteArrayResource byteArrayResource = new ByteArrayResource(resource.getBytes()) {
@Override
public String getFilename() {
return name;
......
......@@ -4,6 +4,7 @@ import at.tuwien.api.zenodo.files.FileResponseDto;
import at.tuwien.api.zenodo.files.FileUploadDto;
import at.tuwien.exception.*;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.List;
......@@ -25,7 +26,7 @@ public interface FileService {
* @throws ZenodoFileTooLargeException The file exceeds the capabilities
* @throws MetadataDatabaseNotFoundException The deposit was not found on the metadata database
*/
FileResponseDto createResource(Long databaseId, Long tableId, FileUploadDto data, File resource)
FileResponseDto createResource(Long databaseId, Long tableId, FileUploadDto data, MultipartFile resource)
throws ZenodoAuthenticationException, ZenodoApiException, ZenodoNotFoundException,
ZenodoFileTooLargeException, MetadataDatabaseNotFoundException;
......
package at.tuwien.service;
import at.tuwien.api.zenodo.deposit.*;
import at.tuwien.exception.MetadataDatabaseNotFoundException;
import at.tuwien.exception.ZenodoApiException;
import at.tuwien.exception.ZenodoAuthenticationException;
import at.tuwien.exception.ZenodoNotFoundException;
......@@ -14,40 +15,61 @@ public interface MetadataService {
/**
* List all deposits (e.g. datasets) available
*
* @param databaseId The database-table id pair
* @param tableId The database-table id pair
* @return The deposists
* @throws ZenodoAuthenticationException Token invalid
* @throws ZenodoApiException Something other went wrong
*/
List<DepositResponseDto> listCitations() throws ZenodoAuthenticationException, ZenodoApiException;
List<DepositResponseDto> listCitations(Long databaseId, Long tableId) throws ZenodoAuthenticationException, ZenodoApiException, MetadataDatabaseNotFoundException;
/**
* Create a new deposit
*
* @param databaseId The database-table id pair
* @param tableId The database-table id pair
* @return The created deposit
* @throws ZenodoAuthenticationException Token invalid
* @throws ZenodoApiException Something other went wrong
*/
DepositChangeResponseDto storeCitation() throws ZenodoAuthenticationException, ZenodoApiException;
DepositChangeResponseDto storeCitation(Long databaseId, Long tableId) throws ZenodoAuthenticationException, ZenodoApiException, MetadataDatabaseNotFoundException;
/**
* Update a deposit with new metadata for a given id
*
* @param id The id
* @param databaseId The database-table id pair
* @param tableId The database-table id pair
* @param data The new metadata
* @return The updated deposit
* @throws ZenodoAuthenticationException Token invalid
* @throws ZenodoApiException Something other went wrong
* @throws ZenodoNotFoundException The deposit id was not found on the remote server
*/
DepositChangeResponseDto updateCitation(Long id, DepositChangeRequestDto data) throws ZenodoAuthenticationException,
ZenodoApiException, ZenodoNotFoundException;
DepositChangeResponseDto updateCitation(Long databaseId, Long tableId, DepositChangeRequestDto data) throws ZenodoAuthenticationException,
ZenodoApiException, ZenodoNotFoundException, MetadataDatabaseNotFoundException;
/**
* Find a deposit by database-table id pair
*
* @param databaseId The database-table id pair
* @param tableId The database-table id pair
* @return The deposit
* @throws ZenodoAuthenticationException Token invalid
* @throws ZenodoApiException Something other went wrong
* @throws ZenodoNotFoundException The deposit id was not found on the remote server
* @throws MetadataDatabaseNotFoundException The deposit id was not found in the metadata database
*/
DepositResponseDto findCitation(Long databaseId, Long tableId)
throws ZenodoAuthenticationException, ZenodoApiException, ZenodoNotFoundException,
MetadataDatabaseNotFoundException;
/**
* Delete a deposit from a given id
*
* @param id The id
* @param databaseId The database-table id pair
* @param tableId The database-table id pair
* @throws ZenodoAuthenticationException Token invalid
* @throws ZenodoApiException Something other went wrong
*/
void deleteCitation(Long id) throws ZenodoAuthenticationException, ZenodoApiException;
void deleteCitation(Long databaseId, Long tableId) throws ZenodoAuthenticationException, ZenodoApiException, MetadataDatabaseNotFoundException;
}
......@@ -3,6 +3,7 @@ package at.tuwien.service;
import at.tuwien.api.zenodo.files.FileResponseDto;
import at.tuwien.api.zenodo.files.FileUploadDto;
import at.tuwien.config.ZenodoConfig;
import at.tuwien.entities.database.Database;
import at.tuwien.entities.database.table.Table;
import at.tuwien.exception.*;
import at.tuwien.mapper.ZenodoMapper;
......@@ -12,7 +13,9 @@ import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import javax.transaction.Transactional;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
......@@ -37,13 +40,14 @@ public class ZenodoFileService implements FileService {
}
@Override
public FileResponseDto createResource(Long databaseId, Long tableId, FileUploadDto data, File resource)
@Transactional
public FileResponseDto createResource(Long databaseId, Long tableId, FileUploadDto data, MultipartFile resource)
throws ZenodoAuthenticationException, ZenodoApiException, ZenodoNotFoundException,
ZenodoFileTooLargeException, MetadataDatabaseNotFoundException {
if (resource.getTotalSpace() > 50_1000_1000_1000L) {
if (resource.getSize() > 50_1000_1000_1000L) {
throw new ZenodoFileTooLargeException("Only 50GB per file is allowed!");
}
final Table table = getTable(tableId);
final Table table = getTable(databaseId, tableId);
final ResponseEntity<FileResponseDto> response;
try {
response = apiTemplate.postForEntity("/api/deposit/depositions/{deposit_id}/files?access_token={token}",
......@@ -65,9 +69,10 @@ public class ZenodoFileService implements FileService {
}
@Override
@Transactional
public List<FileResponseDto> listResources(Long databaseId, Long tableId) throws MetadataDatabaseNotFoundException,
ZenodoAuthenticationException, ZenodoNotFoundException, ZenodoApiException {
final Table table = getTable(tableId);
final Table table = getTable(databaseId, tableId);
final ResponseEntity<FileResponseDto[]> response;
try {
response = apiTemplate.exchange("/api/deposit/depositions/{deposit_id}/files?access_token={token}",
......@@ -84,10 +89,11 @@ public class ZenodoFileService implements FileService {
}
@Override
@Transactional
public FileResponseDto findResource(Long databaseId, Long tableId, String fileId)
throws MetadataDatabaseNotFoundException, ZenodoAuthenticationException, ZenodoNotFoundException,
ZenodoApiException {
final Table table = getTable(tableId);
final Table table = getTable(databaseId, tableId);
final ResponseEntity<FileResponseDto> response;
try {
response = apiTemplate.exchange("/api/deposit/depositions/{deposit_id}/files/{file_id}?access_token={token}",
......@@ -105,9 +111,10 @@ public class ZenodoFileService implements FileService {
}
@Override
@Transactional
public void deleteResource(Long databaseId, Long tableId, String fileId)
throws MetadataDatabaseNotFoundException, ZenodoAuthenticationException, ZenodoNotFoundException, ZenodoApiException {
final Table table = getTable(tableId);
final Table table = getTable(databaseId, tableId);
final ResponseEntity<String> response;
try {
response = apiTemplate.exchange("/api/deposit/depositions/{deposit_id}/files/{file_id}?access_token={token}",
......@@ -126,12 +133,17 @@ public class ZenodoFileService implements FileService {
/**
* Wrapper function to throw error when table with id was not found
*
* @param databaseId The database id
* @param tableId The table id
* @return The table
* @throws MetadataDatabaseNotFoundException The error
*/
private Table getTable(Long tableId) throws MetadataDatabaseNotFoundException {
final Optional<Table> table = tableRepository.findById(tableId);
@Transactional
protected Table getTable(Long databaseId, Long tableId) throws MetadataDatabaseNotFoundException {
final Database database = Database.builder()
.id(databaseId)
.build();
final Optional<Table> table = tableRepository.findByDatabaseAndId(database, tableId);
if (table.isEmpty()) {
throw new MetadataDatabaseNotFoundException("Failed to find table with this id");
}
......
......@@ -2,31 +2,41 @@ package at.tuwien.service;
import at.tuwien.api.zenodo.deposit.*;
import at.tuwien.config.ZenodoConfig;
import at.tuwien.entities.database.Database;
import at.tuwien.entities.database.table.Table;
import at.tuwien.exception.MetadataDatabaseNotFoundException;
import at.tuwien.exception.ZenodoApiException;
import at.tuwien.exception.ZenodoAuthenticationException;
import at.tuwien.exception.ZenodoNotFoundException;
import at.tuwien.repository.jpa.TableRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.transaction.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@Service
public class ZenodoMetadataService implements MetadataService {
private final RestTemplate apiTemplate;
private final ZenodoConfig zenodoConfig;
private final TableRepository tableRepository;
@Autowired
public ZenodoMetadataService(RestTemplate apiTemplate, ZenodoConfig zenodoConfig) {
public ZenodoMetadataService(RestTemplate apiTemplate, ZenodoConfig zenodoConfig, TableRepository tableRepository) {
this.apiTemplate = apiTemplate;
this.zenodoConfig = zenodoConfig;
this.tableRepository = tableRepository;
}
@Override
public List<DepositResponseDto> listCitations() throws ZenodoAuthenticationException, ZenodoApiException {
@Transactional
public List<DepositResponseDto> listCitations(Long databaseId, Long tableId) throws ZenodoAuthenticationException,
ZenodoApiException {
final ResponseEntity<DepositResponseDto[]> response = apiTemplate.exchange("/api/deposit/depositions?access_token={token}",
HttpMethod.GET, addHeaders(null), DepositResponseDto[].class, zenodoConfig.getApiKey());
if (response.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) {
......@@ -39,7 +49,10 @@ public class ZenodoMetadataService implements MetadataService {
}
@Override
public DepositChangeResponseDto storeCitation() throws ZenodoAuthenticationException, ZenodoApiException {
@Transactional
public DepositChangeResponseDto storeCitation(Long databaseId, Long tableId) throws ZenodoAuthenticationException,
ZenodoApiException, MetadataDatabaseNotFoundException {
final Table table = getTable(databaseId, tableId);
final ResponseEntity<DepositChangeResponseDto> response = apiTemplate.exchange("/api/deposit/depositions?access_token={token}",
HttpMethod.POST, addHeaders("{}"), DepositChangeResponseDto.class, zenodoConfig.getApiKey());
if (response.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) {
......@@ -51,14 +64,20 @@ public class ZenodoMetadataService implements MetadataService {
if (response.getBody() == null) {
throw new ZenodoApiException("Endpoint returned null body");
}
table.setDepositId(response.getBody().getId());
tableRepository.save(table);
return response.getBody();
}
@Override
public DepositChangeResponseDto updateCitation(Long id, DepositChangeRequestDto data) throws ZenodoAuthenticationException,
ZenodoApiException, ZenodoNotFoundException {
@Transactional
public DepositChangeResponseDto updateCitation(Long databaseId, Long tableId, DepositChangeRequestDto data)
throws ZenodoAuthenticationException, ZenodoApiException, ZenodoNotFoundException,
MetadataDatabaseNotFoundException {
final Table table = getTable(databaseId, tableId);
final ResponseEntity<DepositChangeResponseDto> response = apiTemplate.exchange("/api/deposit/depositions/{deposit_id}?access_token={token}",
HttpMethod.PUT, addHeaders(data), DepositChangeResponseDto.class, id, zenodoConfig.getApiKey());
HttpMethod.PUT, addHeaders(data), DepositChangeResponseDto.class, table.getDepositId(),
zenodoConfig.getApiKey());
if (response.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) {
throw new ZenodoAuthenticationException("Token is missing or invalid.");
}
......@@ -75,9 +94,32 @@ public class ZenodoMetadataService implements MetadataService {
}
@Override
public void deleteCitation(Long id) throws ZenodoAuthenticationException, ZenodoApiException {
@Transactional
public DepositResponseDto findCitation(Long databaseId, Long tableId) throws ZenodoAuthenticationException,
ZenodoApiException, ZenodoNotFoundException, MetadataDatabaseNotFoundException {
final Table table = getTable(databaseId, tableId);
final ResponseEntity<DepositResponseDto> response = apiTemplate.exchange("/api/deposit/depositions/{deposit_id}?access_token={token}",
HttpMethod.GET, addHeaders(null), DepositResponseDto.class, table.getDepositId(),
zenodoConfig.getApiKey());
if (response.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) {
throw new ZenodoAuthenticationException("Token is missing or invalid.");
}
if (response.getStatusCode().equals(HttpStatus.BAD_REQUEST)) {
throw new ZenodoNotFoundException("Could not get the citation.");
}
if (response.getBody() == null) {
throw new ZenodoApiException("Endpoint returned null body");
}
return response.getBody();
}
@Override
@Transactional
public void deleteCitation(Long databaseId, Long tableId) throws ZenodoAuthenticationException, ZenodoApiException,
MetadataDatabaseNotFoundException {
final Table table = getTable(databaseId, tableId);
final ResponseEntity<String> response = apiTemplate.exchange("/api/deposit/depositions/{deposit_id}?access_token={token}",
HttpMethod.DELETE, addHeaders(null), String.class, id, zenodoConfig.getApiKey());
HttpMethod.DELETE, addHeaders(null), String.class, table.getDepositId(), zenodoConfig.getApiKey());
if (response.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) {
throw new ZenodoAuthenticationException("Token is missing or invalid.");
}
......@@ -86,6 +128,33 @@ public class ZenodoMetadataService implements MetadataService {
}
}
/**
* Wrapper function to throw error when table with id was not found
*
* @param databaseId The database id
* @param tableId The table id
* @return The table
* @throws MetadataDatabaseNotFoundException The error
*/
@Transactional
protected Table getTable(Long databaseId, Long tableId) throws MetadataDatabaseNotFoundException {
final Database database = Database.builder()
.id(databaseId)
.build();
final Optional<Table> table = tableRepository.findByDatabaseAndId(database, tableId);
if (table.isEmpty()) {
throw new MetadataDatabaseNotFoundException("Failed to find table with this id");
}
return table.get();
}
/**
* Wrapper to add headers to all non-file upload requests
*
* @param body The request data
* @return The request with headers
*/
private HttpEntity<Object> addHeaders(Object body) {
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment