Skip to content
Snippets Groups Projects
Commit 050aeb6b authored by Martin Weise's avatar Martin Weise
Browse files

attempt in LAZY-lize all EAGER loading references for better performance

parent a6fcc3a4
Branches
Tags
2 merge requests!81New stable release,!43Merge dev to master
Showing
with 67 additions and 34 deletions
......@@ -13,6 +13,7 @@ import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
......@@ -37,6 +38,7 @@ public class ContainerEndpoint {
this.containerService = containerService;
}
@Transactional
@GetMapping("/")
@ApiOperation(value = "List all containers", notes = "Lists the containers in the metadata database.")
@ApiResponses({
......@@ -51,6 +53,7 @@ public class ContainerEndpoint {
.collect(Collectors.toList()));
}
@Transactional
@PostMapping("/")
@ApiOperation(value = "Creates a new container", notes = "Creates a new container whose image is registered in the metadata database too.")
@ApiResponses({
......@@ -67,6 +70,7 @@ public class ContainerEndpoint {
.body(response);
}
@Transactional
@GetMapping("/{id}")
@ApiOperation(value = "Get all informations about a container", notes = "Since we follow the REST-principle, this method provides more information than the findAll method.")
@ApiResponses({
......@@ -95,6 +99,7 @@ public class ContainerEndpoint {
.body(containerDto);
}
@Transactional
@PutMapping("/{id}")
@ApiOperation(value = "Change the state of a container", notes = "The new state can only be one of START/STOP.")
@ApiResponses({
......
......@@ -16,6 +16,7 @@ import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
......@@ -39,6 +40,7 @@ public class ImageEndpoint {
this.imageMapper = imageMapper;
}
@Transactional
@GetMapping("/")
@ApiOperation(value = "List all images", notes = "Lists the images in the metadata database.")
@ApiResponses({
......@@ -53,6 +55,7 @@ public class ImageEndpoint {
.collect(Collectors.toList()));
}
@Transactional
@PostMapping("/")
@ApiOperation(value = "Creates a new image", notes = "Creates a new image in the metadata database.")
@ApiResponses({
......@@ -68,6 +71,7 @@ public class ImageEndpoint {
.body(imageMapper.containerImageToImageDto(image));
}
@Transactional
@GetMapping("/{id}")
@ApiOperation(value = "Get all informations about a image", notes = "Since we follow the REST-principle, this method provides more information than the findAll method.")
@ApiResponses({
......@@ -81,6 +85,7 @@ public class ImageEndpoint {
.body(imageMapper.containerImageToImageDto(image));
}
@Transactional
@PutMapping("/{id}")
@ApiOperation(value = "Update image information", notes = "Polls new information about an image")
@ApiResponses({
......@@ -102,7 +107,7 @@ public class ImageEndpoint {
@ApiResponse(code = 401, message = "Not authorized to delete a image."),
@ApiResponse(code = 404, message = "No image found with this id in metadata database."),
})
public ResponseEntity delete(@NotNull @PathVariable Long id) throws ImageNotFoundException {
public ResponseEntity<?> delete(@NotNull @PathVariable Long id) throws ImageNotFoundException {
imageService.delete(id);
return ResponseEntity.status(HttpStatus.OK)
.build();
......
......@@ -23,7 +23,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import javax.transaction.Transactional;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.Map;
......
......@@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.SocketUtils;
import javax.transaction.Transactional;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
......@@ -109,6 +109,7 @@ public class ContainerService {
return container.get();
}
@Transactional
public void remove(Long containerId) throws ContainerNotFoundException, DockerClientException,
ContainerStillRunningException {
final Optional<Container> container = containerRepository.findById(containerId);
......@@ -128,6 +129,7 @@ public class ContainerService {
log.debug("Removed container {}", containerId);
}
@Transactional
public Container getById(Long containerId) throws ContainerNotFoundException {
final Optional<Container> container = containerRepository.findById(containerId);
if (container.isEmpty()) {
......@@ -137,6 +139,7 @@ public class ContainerService {
return container.get();
}
@Transactional
public List<Container> getAll() {
return containerRepository.findAll();
}
......@@ -147,6 +150,7 @@ public class ContainerService {
* @param containerId The container ID
* @return The container
*/
@Transactional
public Container start(Long containerId) throws ContainerNotFoundException, DockerClientException {
Container container = getById(containerId);
try {
......
......@@ -17,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityNotFoundException;
import javax.validation.ConstraintViolationException;
......@@ -40,10 +41,12 @@ public class ImageService {
this.imageMapper = imageMapper;
}
@Transactional
public List<ContainerImage> getAll() {
return imageRepository.findAll();
}
@Transactional
public ContainerImage getById(Long imageId) throws ImageNotFoundException {
final Optional<ContainerImage> image = imageRepository.findById(imageId);
if (image.isEmpty()) {
......@@ -53,6 +56,7 @@ public class ImageService {
return image.get();
}
@Transactional
public ContainerImage create(ImageCreateDto createDto) throws ImageNotFoundException, ImageAlreadyExistsException {
pull(createDto.getRepository(), createDto.getTag());
final ContainerImage image = inspect(createDto.getRepository(), createDto.getTag());
......@@ -70,6 +74,7 @@ public class ImageService {
return out;
}
@Transactional
public ContainerImage update(Long imageId, ImageChangeDto changeDto) throws ImageNotFoundException {
final ContainerImage image = getById(imageId);
/* pull changes */
......
......@@ -14,6 +14,7 @@ import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
......@@ -36,6 +37,7 @@ public class DatabaseEndpoint {
this.databaseService = databaseService;
}
@Transactional
@GetMapping("/")
@ApiOperation(value = "List all databases", notes = "Currently a container supports only databases of the same image, e.g. there is one PostgreSQL engine running with multiple databases inside a container.")
@ApiResponses({
......@@ -50,6 +52,7 @@ public class DatabaseEndpoint {
return ResponseEntity.ok(databases);
}
@Transactional
@PostMapping("/")
@ApiOperation(value = "Creates a new database in a container", notes = "Creates a new database in a container. Note that the backend distincts between numerical (req: categories), nominal (req: max_length) and categorical (req: max_length, siUnit, min, max, mean, median, standard_deviation, histogram) column types.")
@ApiResponses({
......@@ -66,6 +69,7 @@ public class DatabaseEndpoint {
.body(databaseMapper.databaseToDatabaseBriefDto(database));
}
@Transactional
@GetMapping("/{id}")
@ApiOperation(value = "Get all informations about a database")
@ApiResponses({
......
......@@ -18,7 +18,7 @@ import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import javax.transaction.Transactional;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
......
......@@ -11,7 +11,7 @@ import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
......@@ -39,6 +39,7 @@ public class DatabaseService {
*
* @return A list of databases
*/
@Transactional
public List<Database> findAll() {
return databaseRepository.findAll();
}
......@@ -50,6 +51,7 @@ public class DatabaseService {
* @return The database
* @throws DatabaseNotFoundException In case the database was not found
*/
@Transactional
public Database findById(Long databaseId) throws DatabaseNotFoundException {
final Optional<Database> opt = databaseRepository.findById(databaseId);
if (opt.isEmpty()) {
......
......@@ -17,6 +17,7 @@ import net.sf.jsqlparser.JSQLParserException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
......@@ -42,6 +43,7 @@ public class QueryEndpoint {
this.queryMapper = queryMapper;
}
@Transactional
@GetMapping("/query")
@ApiOperation(value = "List all queries", notes = "Lists all already executed queries")
@ApiResponses({
......@@ -71,6 +73,7 @@ public class QueryEndpoint {
.build();
}
@Transactional
@PutMapping("/query")
@ApiOperation(value = "executes a query")
@ApiResponses(value = {
......@@ -85,7 +88,7 @@ public class QueryEndpoint {
return ResponseEntity.ok(response);
}
@Transactional
@PutMapping("/query/version/{timestamp}")
@ApiOperation(value = "executes a query with a given timestamp")
@ApiResponses(value = {@ApiResponse(code = 201, message = "result of Query with Timestamp")})
......
......@@ -18,6 +18,7 @@ import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityNotFoundException;
import java.io.StringReader;
......@@ -42,13 +43,7 @@ public class QueryService {
this.postgresService = postgresService;
}
public QueryResultDto executeQuery(String id, ExecuteQueryDto dto) {
System.out.println("test");
return null;
}
@Transactional
public List<Query> findAll(Long id) throws ImageNotSupportedException, DatabaseNotFoundException, DatabaseConnectionException, QueryMalformedException {
return postgresService.getQueries(findDatabase(id));
}
......@@ -74,7 +69,6 @@ public class QueryService {
return null;
}
public void create(Long id) throws DatabaseConnectionException, ImageNotSupportedException, DatabaseNotFoundException {
postgresService.createQuerystore(findDatabase(id));
}
......
......@@ -17,6 +17,7 @@ import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
......@@ -42,6 +43,7 @@ public class TableEndpoint {
this.queryResultMapper = queryResultMapper;
}
@Transactional
@GetMapping("/table")
@ApiOperation(value = "List all tables", notes = "Lists the tables in the metadata database for this database.")
@ApiResponses({
......@@ -57,6 +59,7 @@ public class TableEndpoint {
.collect(Collectors.toList()));
}
@Transactional
@PostMapping("/table")
@ApiOperation(value = "Create a table", notes = "Creates a new table for a database, requires a running container.")
@ApiResponses({
......@@ -77,6 +80,7 @@ public class TableEndpoint {
.body(tableMapper.tableToTableBriefDto(table));
}
@Transactional
@PostMapping("/table/csv")
@ApiOperation(value = "Create a table", notes = "Creates a file, which is given as a multipart file.")
@ApiResponses({
......@@ -93,6 +97,7 @@ public class TableEndpoint {
.body(tableMapper.tableToTableDto(table));
}
@Transactional
@PostMapping("/table/csv/local")
@ApiOperation(value = "Create a table", notes = "This is done by saving a file on the shared docker filesystem and then sending the link to the file.")
@ApiResponses({
......@@ -110,6 +115,7 @@ public class TableEndpoint {
}
@Transactional
@GetMapping("/table/{tableId}")
@ApiOperation(value = "List all tables", notes = "Lists the tables in the metadata database for this database.")
@ApiResponses({
......@@ -118,7 +124,7 @@ public class TableEndpoint {
@ApiResponse(code = 404, message = "Table not found in metadata database."),
})
public ResponseEntity<TableDto> findById(@PathVariable("id") Long databaseId, @PathVariable("tableId") Long tableId)
throws TableNotFoundException {
throws TableNotFoundException, DatabaseNotFoundException, ImageNotSupportedException {
final Table table = tableService.findById(databaseId, tableId);
return ResponseEntity.ok(tableMapper.tableToTableDto(table));
}
......@@ -147,10 +153,11 @@ public class TableEndpoint {
@ResponseStatus(HttpStatus.OK)
public void delete(@PathVariable("id") Long databaseId, @PathVariable("tableId") Long tableId)
throws TableNotFoundException, DatabaseConnectionException, TableMalformedException,
DataProcessingException {
DataProcessingException, DatabaseNotFoundException, ImageNotSupportedException {
tableService.delete(databaseId, tableId);
}
@Transactional
@PostMapping("/table/{tableId}")
@ApiOperation(value = "Insert values", notes = "Insert Data into a Table in the database.")
@ApiResponses({
......@@ -168,6 +175,7 @@ public class TableEndpoint {
return ResponseEntity.ok(queryResultMapper.queryResultToQueryResultDto(queryResult));
}
@Transactional
@GetMapping("/table/{tableId}/data")
@ApiOperation(value = "show data", notes = "Show all the data for a table")
@ApiResponses({
......
......@@ -137,7 +137,7 @@ public class TableEndpointUnitTest extends BaseUnitTest {
@Disabled("not throwing")
@Test
public void create_notSql_fails() throws TableNotFoundException, SQLException {
public void create_notSql_fails() throws TableNotFoundException, SQLException, DatabaseNotFoundException, ImageNotSupportedException {
final TableCreateDto request = TableCreateDto.builder()
.name(TABLE_1_NAME)
.description(TABLE_1_DESCRIPTION)
......@@ -153,7 +153,7 @@ public class TableEndpointUnitTest extends BaseUnitTest {
}
@Test
public void findById_succeeds() throws TableNotFoundException {
public void findById_succeeds() throws TableNotFoundException, DatabaseNotFoundException, ImageNotSupportedException {
when(tableService.findById(DATABASE_1_ID, TABLE_1_ID))
.thenReturn(TABLE_1);
......@@ -184,7 +184,7 @@ public class TableEndpointUnitTest extends BaseUnitTest {
@Test
public void delete_notFound_fails() throws TableNotFoundException, DatabaseConnectionException,
TableMalformedException, DataProcessingException {
TableMalformedException, DataProcessingException, DatabaseNotFoundException, ImageNotSupportedException {
doThrow(TableNotFoundException.class)
.when(tableService)
.delete(DATABASE_1_ID, TABLE_1_ID);
......@@ -197,7 +197,7 @@ public class TableEndpointUnitTest extends BaseUnitTest {
@Test
public void delete_succeeds() throws TableNotFoundException, DatabaseConnectionException, TableMalformedException,
DataProcessingException {
DataProcessingException, DatabaseNotFoundException, ImageNotSupportedException {
/* test */
tableEndpoint.delete(DATABASE_1_ID, TABLE_1_ID);
}
......
......@@ -76,7 +76,7 @@ public class TableServiceUnitTest extends BaseUnitTest {
@Disabled("invalid mock")
@Test
public void delete_succeeds() throws TableNotFoundException, DatabaseConnectionException, TableMalformedException,
DataProcessingException {
DataProcessingException, DatabaseNotFoundException, ImageNotSupportedException {
when(tableRepository.findById(TABLE_1_ID))
.thenReturn(Optional.of(TABLE_1));
doNothing()
......@@ -92,11 +92,11 @@ public class TableServiceUnitTest extends BaseUnitTest {
@Test
public void delete_notFound_fails() {
when(tableRepository.findByDatabaseAndId(DATABASE_1, TABLE_1_ID))
when(databaseRepository.findById(DATABASE_1_ID))
.thenReturn(Optional.empty());
/* test */
assertThrows(TableNotFoundException.class, () -> {
assertThrows(DatabaseNotFoundException.class, () -> {
tableService.delete(DATABASE_1_ID, TABLE_1_ID);
});
}
......@@ -104,8 +104,8 @@ public class TableServiceUnitTest extends BaseUnitTest {
@Test
public void delete_noConnection_fails() throws DatabaseConnectionException, TableMalformedException,
DataProcessingException {
when(tableRepository.findByDatabaseAndId(DATABASE_1, TABLE_1_ID))
.thenReturn(Optional.empty());
when(databaseRepository.findById(DATABASE_1_ID))
.thenReturn(Optional.of(DATABASE_1));
doAnswer(invocation -> new TableMalformedException("no connection"))
.when(postgresService)
.deleteTable(TABLE_1);
......@@ -118,6 +118,8 @@ public class TableServiceUnitTest extends BaseUnitTest {
@Test
public void delete_noSql_fails() throws DataProcessingException {
when(databaseRepository.findById(DATABASE_1_ID))
.thenReturn(Optional.of(DATABASE_1));
when(tableRepository.findByDatabaseAndId(DATABASE_1, TABLE_1_ID))
.thenReturn(Optional.empty());
......@@ -128,7 +130,9 @@ public class TableServiceUnitTest extends BaseUnitTest {
}
@Test
public void findById_succeeds() throws TableNotFoundException {
public void findById_succeeds() throws TableNotFoundException, DatabaseNotFoundException, ImageNotSupportedException {
when(databaseRepository.findById(DATABASE_1_ID))
.thenReturn(Optional.of(DATABASE_1));
when(tableRepository.findByDatabaseAndId(DATABASE_1, TABLE_1_ID))
.thenReturn(Optional.of(TABLE_1));
......@@ -140,6 +144,8 @@ public class TableServiceUnitTest extends BaseUnitTest {
@Test
public void findById_noTable_fails() {
when(databaseRepository.findById(DATABASE_1_ID))
.thenReturn(Optional.of(DATABASE_1));
when(tableRepository.findByDatabaseAndId(DATABASE_1, 9999L))
.thenReturn(Optional.empty());
......
......@@ -15,6 +15,7 @@ import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.ift.CellProcessor;
......@@ -23,7 +24,6 @@ import org.supercsv.io.ICsvMapReader;
import org.supercsv.prefs.CsvPreference;
import javax.persistence.EntityNotFoundException;
import javax.transaction.Transactional;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
......@@ -70,18 +70,15 @@ public class TableService {
}
@Transactional
public void delete(Long databaseId, Long tableId) throws TableNotFoundException, DatabaseConnectionException, TableMalformedException, DataProcessingException {
public void delete(Long databaseId, Long tableId) throws TableNotFoundException, DatabaseConnectionException, TableMalformedException, DataProcessingException, DatabaseNotFoundException, ImageNotSupportedException {
final Table table = findById(databaseId, tableId);
postgresService.deleteTable(table);
tableRepository.deleteById(tableId);
}
@Transactional
public Table findById(Long databaseId, Long tableId) throws TableNotFoundException {
final Database database = Database.builder()
.id(databaseId)
.build();
final Optional<Table> table = tableRepository.findByDatabaseAndId(database, tableId);
public Table findById(Long databaseId, Long tableId) throws TableNotFoundException, DatabaseNotFoundException, ImageNotSupportedException {
final Optional<Table> table = tableRepository.findByDatabaseAndId(findDatabase(databaseId), tableId);
if (table.isEmpty()) {
log.error("table {} not found in database {}", tableId, databaseId);
throw new TableNotFoundException("table not found in database");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment