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

Added more tests, fixed the hibernate problem

parent f8fe8c42
No related branches found
No related tags found
3 merge requests!81New stable release,!43Merge dev to master,!34Resolve "Test AMQP"
This commit is part of merge request !34. Comments created here will be created in the context of that merge request.
Showing
with 272 additions and 146 deletions
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
<springfox.version>3.0.0</springfox.version> <springfox.version>3.0.0</springfox.version>
<jacoco.version>0.8.7</jacoco.version> <jacoco.version>0.8.7</jacoco.version>
<opencsv.version>5.4</opencsv.version> <opencsv.version>5.4</opencsv.version>
<hibernate-c3po.version>5.6.3.Final</hibernate-c3po.version>
</properties> </properties>
<dependencies> <dependencies>
...@@ -111,6 +112,11 @@ ...@@ -111,6 +112,11 @@
<version>${project.version}</version> <version>${project.version}</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>${hibernate-c3po.version}</version>
</dependency>
<!-- Testing --> <!-- Testing -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
...@@ -207,6 +213,8 @@ ...@@ -207,6 +213,8 @@
<excludes> <excludes>
<exclude>at/tuwien/utils/**/*</exclude> <exclude>at/tuwien/utils/**/*</exclude>
<exclude>at/tuwien/mapper/**/*</exclude> <exclude>at/tuwien/mapper/**/*</exclude>
<exclude>at/tuwien/entities/**/*</exclude>
<exclude>at/tuwien/seeder/**/*</exclude>
<exclude>at/tuwien/handlers/**/*</exclude> <exclude>at/tuwien/handlers/**/*</exclude>
<exclude>at/tuwien/exception/**/*</exclude> <exclude>at/tuwien/exception/**/*</exclude>
<exclude>at/tuwien/config/**/*</exclude> <exclude>at/tuwien/config/**/*</exclude>
......
...@@ -4,6 +4,7 @@ import at.tuwien.api.database.query.ExecuteStatementDto; ...@@ -4,6 +4,7 @@ import at.tuwien.api.database.query.ExecuteStatementDto;
import at.tuwien.api.database.query.QueryDto; import at.tuwien.api.database.query.QueryDto;
import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.query.QueryResultDto;
import at.tuwien.api.database.query.SaveStatementDto; import at.tuwien.api.database.query.SaveStatementDto;
import at.tuwien.entities.Query;
import at.tuwien.exception.*; import at.tuwien.exception.*;
import at.tuwien.mapper.QueryMapper; import at.tuwien.mapper.QueryMapper;
import at.tuwien.service.QueryService; import at.tuwien.service.QueryService;
...@@ -80,8 +81,10 @@ public class QueryEndpoint { ...@@ -80,8 +81,10 @@ public class QueryEndpoint {
@PathVariable Long queryId) @PathVariable Long queryId)
throws QueryStoreException, QueryNotFoundException, DatabaseNotFoundException, ImageNotSupportedException, throws QueryStoreException, QueryNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
TableNotFoundException, QueryMalformedException { TableNotFoundException, QueryMalformedException {
final QueryDto query = queryMapper.queryToQueryDto(storeService.findOne(id, queryId)); final Query query = storeService.findOne(id, queryId);
final QueryResultDto result = queryService.execute(id, tableId, queryMapper.queryDtoToExecuteStatementDto(query)); final QueryDto queryDto = queryMapper.queryToQueryDto(query);
final ExecuteStatementDto statement = queryMapper.queryDtoToExecuteStatementDto(queryDto);
final QueryResultDto result = queryService.execute(id, tableId, statement);
return ResponseEntity.status(HttpStatus.ACCEPTED) return ResponseEntity.status(HttpStatus.ACCEPTED)
.body(result); .body(result);
} }
......
package at.tuwien.config;
import at.tuwien.entities.database.table.Table;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
@Slf4j
@Configuration
public class MariaDbConfig {
public static void clearQueryStore(Table table) throws SQLException {
final String jdbc = "jdbc:mariadb://" + table.getDatabase().getContainer().getInternalName() + "/" + table.getDatabase().getInternalName();
log.trace("connect to database {}", jdbc);
final Connection connection = DriverManager.getConnection(jdbc, "mariadb", "mariadb");
final Statement statement = connection.createStatement();
statement.execute("DROP TABLE IF EXISTS qs_queries;");
statement.execute("DROP TABLE IF EXISTS qs_seq;");
connection.close();
}
}
package at.tuwien.endpoint;
import at.tuwien.BaseUnitTest;
import at.tuwien.api.database.query.ExecuteStatementDto;
import at.tuwien.api.database.query.QueryDto;
import at.tuwien.api.database.query.QueryResultDto;
import at.tuwien.api.database.query.SaveStatementDto;
import at.tuwien.config.DockerConfig;
import at.tuwien.config.MariaDbConfig;
import at.tuwien.config.ReadyConfig;
import at.tuwien.exception.*;
import at.tuwien.repository.jpa.DatabaseRepository;
import at.tuwien.repository.jpa.ImageRepository;
import at.tuwien.service.StoreService;
import at.tuwien.service.impl.QueryServiceImpl;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.exception.NotModifiedException;
import com.github.dockerjava.api.model.Bind;
import com.github.dockerjava.api.model.Network;
import com.rabbitmq.client.Channel;
import lombok.extern.log4j.Log4j2;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
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.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import static at.tuwien.config.DockerConfig.dockerClient;
import static at.tuwien.config.DockerConfig.hostConfig;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;
@Log4j2
@SpringBootTest
@ExtendWith(SpringExtension.class)
public class QueryEndpointIntegrationTest extends BaseUnitTest {
@MockBean
private Channel channel;
@MockBean
private ReadyConfig readyConfig;
@Autowired
private QueryEndpoint queryEndpoint;
@Autowired
private ImageRepository imageRepository;
@Autowired
private DatabaseRepository databaseRepository;
@MockBean
private QueryServiceImpl queryService;
@MockBean
private StoreService storeService;
@BeforeAll
public static void beforeAll() {
afterAll();
/* create network */
dockerClient.createNetworkCmd()
.withName("fda-userdb")
.withIpam(new Network.Ipam()
.withConfig(new Network.Ipam.Config()
.withSubnet("172.28.0.0/16")))
.withEnableIpv6(false)
.exec();
/* create container */
final String bind = new File("./src/test/resources/weather").toPath().toAbsolutePath() + ":/docker-entrypoint-initdb.d";
log.trace("container bind {}", bind);
final CreateContainerResponse response = dockerClient.createContainerCmd(IMAGE_1_REPOSITORY + ":" + IMAGE_1_TAG)
.withHostConfig(hostConfig.withNetworkMode("fda-userdb"))
.withName(CONTAINER_1_INTERNALNAME)
.withIpv4Address(CONTAINER_1_IP)
.withHostName(CONTAINER_1_INTERNALNAME)
.withEnv("MARIADB_USER=mariadb", "MARIADB_PASSWORD=mariadb", "MARIADB_ROOT_PASSWORD=mariadb", "MARIADB_DATABASE=weather")
.withBinds(Bind.parse(bind))
.exec();
CONTAINER_1.setHash(response.getId());
}
@AfterAll
public static void afterAll() {
/* stop containers and remove them */
dockerClient.listContainersCmd()
.withShowAll(true)
.exec()
.forEach(container -> {
log.info("Delete container {}", Arrays.asList(container.getNames()));
try {
dockerClient.stopContainerCmd(container.getId()).exec();
} catch (NotModifiedException e) {
// ignore
}
dockerClient.removeContainerCmd(container.getId()).exec();
});
/* remove networks */
dockerClient.listNetworksCmd()
.exec()
.stream()
.filter(n -> n.getName().startsWith("fda"))
.forEach(network -> {
log.info("Delete network {}", network.getName());
dockerClient.removeNetworkCmd(network.getId()).exec();
});
}
@BeforeEach
@Transactional
public void beforeEach() {
TABLE_1.setDatabase(DATABASE_1);
TABLE_2.setDatabase(DATABASE_1);
imageRepository.save(IMAGE_1);
databaseRepository.save(DATABASE_1);
}
@Test
public void reExecute_succeeds() throws TableNotFoundException, QueryStoreException, QueryMalformedException,
DatabaseNotFoundException, ImageNotSupportedException, QueryNotFoundException, InterruptedException, SQLException {
final QueryResultDto result = QueryResultDto.builder()
.id(QUERY_1_ID)
.result(List.of(Map.of("key", "value")))
.build();
final ExecuteStatementDto statement = ExecuteStatementDto.builder()
.statement(QUERY_1_STATEMENT)
.build();
/* mock */
DockerConfig.startContainer(CONTAINER_1);
MariaDbConfig.clearQueryStore(TABLE_1);
storeService.insert(DATABASE_1_ID, result, statement);
/* test */
final ResponseEntity<QueryResultDto> response = queryEndpoint.reExecute(DATABASE_1_ID, TABLE_1_ID, QUERY_1_ID);
assertEquals(HttpStatus.ACCEPTED, response.getStatusCode());
assertEquals(result, response.getBody());
}
}
...@@ -6,7 +6,6 @@ import at.tuwien.api.database.query.QueryDto; ...@@ -6,7 +6,6 @@ import at.tuwien.api.database.query.QueryDto;
import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.query.QueryResultDto;
import at.tuwien.api.database.query.SaveStatementDto; import at.tuwien.api.database.query.SaveStatementDto;
import at.tuwien.config.ReadyConfig; import at.tuwien.config.ReadyConfig;
import at.tuwien.entities.Query;
import at.tuwien.exception.*; import at.tuwien.exception.*;
import at.tuwien.service.StoreService; import at.tuwien.service.StoreService;
import at.tuwien.service.impl.QueryServiceImpl; import at.tuwien.service.impl.QueryServiceImpl;
...@@ -142,27 +141,4 @@ public class QueryEndpointUnitTest extends BaseUnitTest { ...@@ -142,27 +141,4 @@ public class QueryEndpointUnitTest extends BaseUnitTest {
}); });
} }
@Test
public void reExecute_succeeds() throws TableNotFoundException, QueryStoreException, QueryMalformedException,
DatabaseNotFoundException, ImageNotSupportedException, QueryNotFoundException {
final QueryResultDto result = QueryResultDto.builder()
.id(QUERY_1_ID)
.result(List.of(Map.of("key", "value")))
.build();
final ExecuteStatementDto statement = ExecuteStatementDto.builder()
.statement(QUERY_1_STATEMENT)
.build();
/* mock */
when(storeService.findOne(DATABASE_1_ID, QUERY_1_ID))
.thenReturn(QUERY_1);
when(queryService.execute(DATABASE_1_ID, TABLE_1_ID, statement))
.thenReturn(result);
/* test */
final ResponseEntity<QueryResultDto> response = queryEndpoint.reExecute(DATABASE_1_ID, TABLE_1_ID, QUERY_1_ID);
assertEquals(HttpStatus.ACCEPTED, response.getStatusCode());
assertEquals(result, response.getBody());
}
} }
...@@ -4,6 +4,7 @@ import at.tuwien.BaseUnitTest; ...@@ -4,6 +4,7 @@ import at.tuwien.BaseUnitTest;
import at.tuwien.api.database.query.ExecuteStatementDto; import at.tuwien.api.database.query.ExecuteStatementDto;
import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.query.QueryResultDto;
import at.tuwien.config.DockerConfig; import at.tuwien.config.DockerConfig;
import at.tuwien.config.MariaDbConfig;
import at.tuwien.config.ReadyConfig; import at.tuwien.config.ReadyConfig;
import at.tuwien.exception.*; import at.tuwien.exception.*;
import at.tuwien.repository.jpa.DatabaseRepository; import at.tuwien.repository.jpa.DatabaseRepository;
...@@ -27,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -27,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
import java.io.File; import java.io.File;
import java.math.BigInteger; import java.math.BigInteger;
import java.sql.SQLException;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
...@@ -55,6 +57,9 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { ...@@ -55,6 +57,9 @@ public class QueryServiceIntegrationTest extends BaseUnitTest {
@Autowired @Autowired
private QueryService queryService; private QueryService queryService;
@Autowired
private StoreService storeService;
@Autowired @Autowired
private ImageRepository imageRepository; private ImageRepository imageRepository;
...@@ -180,6 +185,23 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { ...@@ -180,6 +185,23 @@ public class QueryServiceIntegrationTest extends BaseUnitTest {
assertEquals(0.0, response.getResult().get(2).get(COLUMN_1_5_NAME)); assertEquals(0.0, response.getResult().get(2).get(COLUMN_1_5_NAME));
} }
// TODO use own user that has only read-only permissions
@Test
@Disabled
public void execute_modifyData_fails() throws DatabaseNotFoundException, ImageNotSupportedException, InterruptedException, QueryMalformedException, TableNotFoundException, QueryStoreException {
final ExecuteStatementDto request = ExecuteStatementDto.builder()
.statement("DELETE FROM `weather_aus`;")
.build();
/* mock */
DockerConfig.startContainer(CONTAINER_1);
/* test */
final QueryResultDto response = queryService.execute(DATABASE_1_ID, TABLE_1_ID, request);
assertNotNull(response.getResult());
assertEquals(3, response.getResult().size());
}
@Test @Test
public void execute_tableNotExists_fails() throws InterruptedException { public void execute_tableNotExists_fails() throws InterruptedException {
final ExecuteStatementDto request = ExecuteStatementDto.builder() final ExecuteStatementDto request = ExecuteStatementDto.builder()
...@@ -229,7 +251,7 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { ...@@ -229,7 +251,7 @@ public class QueryServiceIntegrationTest extends BaseUnitTest {
@Test @Test
public void execute_columnNotFound_fails() throws InterruptedException { public void execute_columnNotFound_fails() throws InterruptedException {
final ExecuteStatementDto request = ExecuteStatementDto.builder() final ExecuteStatementDto request = ExecuteStatementDto.builder()
.statement(QUERY_1_STATEMENT) .statement("SELECT `local` FROM `weather_aus`")
.build(); .build();
/* mock */ /* mock */
......
...@@ -4,6 +4,7 @@ import at.tuwien.BaseUnitTest; ...@@ -4,6 +4,7 @@ import at.tuwien.BaseUnitTest;
import at.tuwien.api.database.query.ExecuteStatementDto; import at.tuwien.api.database.query.ExecuteStatementDto;
import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.query.QueryResultDto;
import at.tuwien.config.DockerConfig; import at.tuwien.config.DockerConfig;
import at.tuwien.config.MariaDbConfig;
import at.tuwien.config.ReadyConfig; import at.tuwien.config.ReadyConfig;
import at.tuwien.entities.Query; import at.tuwien.entities.Query;
import at.tuwien.exception.DatabaseNotFoundException; import at.tuwien.exception.DatabaseNotFoundException;
...@@ -27,6 +28,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; ...@@ -27,6 +28,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.io.File; import java.io.File;
import java.sql.SQLException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -116,7 +118,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { ...@@ -116,7 +118,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
@Test @Test
public void findAll_succeeds() throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException, public void findAll_succeeds() throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException,
InterruptedException { InterruptedException, SQLException {
final QueryResultDto result = QueryResultDto.builder() final QueryResultDto result = QueryResultDto.builder()
.result(List.of(Map.of("key", "val"))) .result(List.of(Map.of("key", "val")))
.build(); .build();
...@@ -129,6 +131,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { ...@@ -129,6 +131,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
/* mock */ /* mock */
DockerConfig.startContainer(CONTAINER_1); DockerConfig.startContainer(CONTAINER_1);
MariaDbConfig.clearQueryStore(TABLE_1);
storeService.insert(DATABASE_1_ID, result, statement1); storeService.insert(DATABASE_1_ID, result, statement1);
storeService.insert(DATABASE_1_ID, result, statement2); storeService.insert(DATABASE_1_ID, result, statement2);
...@@ -139,7 +142,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { ...@@ -139,7 +142,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
@Test @Test
public void findOne_succeeds() throws DatabaseNotFoundException, ImageNotSupportedException, QueryStoreException, public void findOne_succeeds() throws DatabaseNotFoundException, ImageNotSupportedException, QueryStoreException,
QueryNotFoundException, InterruptedException { QueryNotFoundException, InterruptedException, SQLException {
final QueryResultDto result = QueryResultDto.builder() final QueryResultDto result = QueryResultDto.builder()
.result(List.of(Map.of("key", "val"))) .result(List.of(Map.of("key", "val")))
.build(); .build();
...@@ -149,6 +152,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { ...@@ -149,6 +152,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
/* mock */ /* mock */
DockerConfig.startContainer(CONTAINER_1); DockerConfig.startContainer(CONTAINER_1);
MariaDbConfig.clearQueryStore(TABLE_1);
storeService.insert(DATABASE_1_ID, result, statement); storeService.insert(DATABASE_1_ID, result, statement);
/* test */ /* test */
...@@ -160,7 +164,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { ...@@ -160,7 +164,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
@Test @Test
public void findOne_notFound_fails() throws InterruptedException, QueryStoreException, DatabaseNotFoundException, public void findOne_notFound_fails() throws InterruptedException, QueryStoreException, DatabaseNotFoundException,
ImageNotSupportedException { ImageNotSupportedException, SQLException {
final QueryResultDto result = QueryResultDto.builder() final QueryResultDto result = QueryResultDto.builder()
.result(List.of(Map.of("key", "val"))) .result(List.of(Map.of("key", "val")))
.build(); .build();
...@@ -170,7 +174,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { ...@@ -170,7 +174,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
/* mock */ /* mock */
DockerConfig.startContainer(CONTAINER_1); DockerConfig.startContainer(CONTAINER_1);
storeService.insert(DATABASE_1_ID, result, statement); MariaDbConfig.clearQueryStore(TABLE_1);
/* test */ /* test */
assertThrows(QueryNotFoundException.class, () -> { assertThrows(QueryNotFoundException.class, () -> {
...@@ -179,7 +183,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { ...@@ -179,7 +183,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
} }
@Test @Test
public void insert_succeeds() throws DatabaseNotFoundException, ImageNotSupportedException, QueryStoreException, InterruptedException { public void insert_succeeds() throws DatabaseNotFoundException, ImageNotSupportedException, QueryStoreException, InterruptedException, SQLException {
final QueryResultDto result = QueryResultDto.builder() final QueryResultDto result = QueryResultDto.builder()
.result(List.of(Map.of("key", "val"))) .result(List.of(Map.of("key", "val")))
.build(); .build();
...@@ -189,6 +193,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { ...@@ -189,6 +193,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
/* mock */ /* mock */
DockerConfig.startContainer(CONTAINER_1); DockerConfig.startContainer(CONTAINER_1);
MariaDbConfig.clearQueryStore(TABLE_1);
/* test */ /* test */
final Query response = storeService.insert(DATABASE_1_ID, result, statement); final Query response = storeService.insert(DATABASE_1_ID, result, statement);
...@@ -197,7 +202,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { ...@@ -197,7 +202,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
} }
@Test @Test
public void insert_notRunning_fails() { public void insert_notRunning_fails() throws SQLException {
final QueryResultDto result = QueryResultDto.builder() final QueryResultDto result = QueryResultDto.builder()
.result(List.of(Map.of("id", "1"))) .result(List.of(Map.of("id", "1")))
.build(); .build();
...@@ -215,8 +220,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { ...@@ -215,8 +220,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
} }
@Test @Test
public void insert_dbNotFound_fails() throws InterruptedException, QueryStoreException, DatabaseNotFoundException, public void insert_dbNotFound_fails() throws InterruptedException, SQLException {
ImageNotSupportedException {
final QueryResultDto result = QueryResultDto.builder() final QueryResultDto result = QueryResultDto.builder()
.result(List.of(Map.of("id", "1"))) .result(List.of(Map.of("id", "1")))
.build(); .build();
...@@ -226,7 +230,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { ...@@ -226,7 +230,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest {
/* mock */ /* mock */
DockerConfig.startContainer(CONTAINER_1); DockerConfig.startContainer(CONTAINER_1);
storeService.create(DATABASE_1_ID); MariaDbConfig.clearQueryStore(TABLE_1);
/* test */ /* test */
assertThrows(DatabaseNotFoundException.class, () -> { assertThrows(DatabaseNotFoundException.class, () -> {
......
...@@ -42,13 +42,6 @@ public interface QueryMapper { ...@@ -42,13 +42,6 @@ public interface QueryMapper {
}) })
ExecuteStatementDto saveStatementDtoToExecuteStatementDto(SaveStatementDto data); ExecuteStatementDto saveStatementDtoToExecuteStatementDto(SaveStatementDto data);
@Mappings({
@Mapping(source = "statement", target = "query")
})
Query executeStatementDtoToQuery(ExecuteStatementDto data);
Query queryDtoToQuery(QueryDto data);
QueryDto queryToQueryDto(Query data); QueryDto queryToQueryDto(Query data);
List<QueryDto> queryListToQueryDtoList(List<Query> data); List<QueryDto> queryListToQueryDtoList(List<Query> data);
...@@ -200,17 +193,4 @@ public interface QueryMapper { ...@@ -200,17 +193,4 @@ public interface QueryMapper {
throw new IllegalArgumentException("Column type not known"); throw new IllegalArgumentException("Column type not known");
} }
} }
default String getHash(QueryResultDto data) {
if (data == null) {
return DigestUtils.sha256Hex(String.valueOf(RandomUtils.nextLong()));
}
if (data.getResult().size() == 0) {
return DigestUtils.sha256Hex(String.valueOf(RandomUtils.nextLong()));
}
if (data.getResult().size() == 1 && data.getResult().get(0).size() == 0) {
return DigestUtils.sha256Hex(String.valueOf(RandomUtils.nextLong()));
}
return DigestUtils.sha256Hex(data.getResult().toString());
}
} }
package at.tuwien.repository.jpa;
import at.tuwien.entities.container.Container;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ContainerRepository extends JpaRepository<Container, Long> {
}
...@@ -11,10 +11,6 @@ import java.util.Optional; ...@@ -11,10 +11,6 @@ import java.util.Optional;
@Repository @Repository
public interface TableRepository extends JpaRepository<Table, Long> { public interface TableRepository extends JpaRepository<Table, Long> {
List<Table> findByDatabase(Database database);
Optional<Table> findByDatabaseAndId(Database database, Long tableId); Optional<Table> findByDatabaseAndId(Database database, Long tableId);
Optional<Table> findByDatabaseAndName(Database database, String name);
} }
...@@ -24,7 +24,6 @@ public interface QueryService { ...@@ -24,7 +24,6 @@ public interface QueryService {
* @throws DatabaseNotFoundException * @throws DatabaseNotFoundException
* @throws ImageNotSupportedException * @throws ImageNotSupportedException
*/ */
@Transactional
QueryResultDto execute(Long databaseId, Long tableId, ExecuteStatementDto query) throws TableNotFoundException, QueryResultDto execute(Long databaseId, Long tableId, ExecuteStatementDto query) throws TableNotFoundException,
QueryStoreException, QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException; QueryStoreException, QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException;
......
...@@ -42,16 +42,6 @@ public interface StoreService { ...@@ -42,16 +42,6 @@ public interface StoreService {
Query findOne(Long databaseId, Long queryId) throws DatabaseNotFoundException, ImageNotSupportedException, Query findOne(Long databaseId, Long queryId) throws DatabaseNotFoundException, ImageNotSupportedException,
QueryStoreException, QueryNotFoundException; QueryStoreException, QueryNotFoundException;
/**
* Forcefully creates the query store if not existing, this method is usually not required since Hibernate configures the query store automatically on every operation.
*
* @param databaseId The database id.
* @throws QueryStoreException The query store produced an invalid result
* @throws DatabaseNotFoundException The database was not found in the metadata database
* @throws ImageNotSupportedException The image is not supported
*/
void create(Long databaseId) throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException;
/** /**
* Inserts a query and metadata to the query store of a given database id * Inserts a query and metadata to the query store of a given database id
* *
......
...@@ -16,8 +16,12 @@ import java.util.stream.Collectors; ...@@ -16,8 +16,12 @@ import java.util.stream.Collectors;
@Service @Service
public abstract class HibernateConnector { public abstract class HibernateConnector {
private static final Integer POOL_SIZE = 3; private static final Integer MIN_SIZE = 5;
private static final Integer MAX_SIZE = 30;
private static final Integer INCREMENT_SIZE = 5;
private static final Integer TIMEOUT = 1800;
private static final String SESSION_CONTEXT = "thread"; private static final String SESSION_CONTEXT = "thread";
private static final String COORDINATOR_CLASS = "jdbc";
@Transactional @Transactional
protected SessionFactory getSessionFactory(Database database) { protected SessionFactory getSessionFactory(Database database) {
...@@ -40,11 +44,14 @@ public abstract class HibernateConnector { ...@@ -40,11 +44,14 @@ public abstract class HibernateConnector {
.setProperty("hibernate.connection.username", username) .setProperty("hibernate.connection.username", username)
.setProperty("hibernate.connection.password", password) .setProperty("hibernate.connection.password", password)
.setProperty("hibernate.connection.driver_class", database.getContainer().getImage().getDriverClass()) .setProperty("hibernate.connection.driver_class", database.getContainer().getImage().getDriverClass())
.setProperty("hibernate.connection.pool_size", String.valueOf(POOL_SIZE))
.setProperty("hibernate.generate_statistics", "true")
.setProperty("hibernate.dialect", database.getContainer().getImage().getDialect()) .setProperty("hibernate.dialect", database.getContainer().getImage().getDialect())
.setProperty("hibernate.current_session_context_class", SESSION_CONTEXT) .setProperty("hibernate.current_session_context_class", SESSION_CONTEXT)
.setProperty("hibernate.hbm2ddl.auto", "create") .setProperty("hibernate.transaction.coordinator_class", COORDINATOR_CLASS)
.setProperty("hibernate.hbm2ddl.auto", "update")
.setProperty("hibernate.c3p0.min_size", String.valueOf(MIN_SIZE))
.setProperty("hibernate.c3p0.max_size", String.valueOf(MAX_SIZE))
.setProperty("hibernate.c3p0.acquire_increment", String.valueOf(INCREMENT_SIZE))
.setProperty("hibernate.c3p0.timeout", String.valueOf(TIMEOUT))
.addAnnotatedClass(Query.class); .addAnnotatedClass(Query.class);
return configuration.buildSessionFactory(); return configuration.buildSessionFactory();
} }
......
...@@ -56,7 +56,6 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService ...@@ -56,7 +56,6 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
/* run query */ /* run query */
final Session session = getSessionFactory(table.getDatabase()) final Session session = getSessionFactory(table.getDatabase())
.openSession(); .openSession();
session.setDefaultReadOnly(true) /* important */;
session.beginTransaction(); session.beginTransaction();
/* prepare the statement */ /* prepare the statement */
final NativeQuery<?> query = session.createSQLQuery(statement.getStatement()); final NativeQuery<?> query = session.createSQLQuery(statement.getStatement());
......
...@@ -11,8 +11,7 @@ import at.tuwien.service.DatabaseService; ...@@ -11,8 +11,7 @@ import at.tuwien.service.DatabaseService;
import at.tuwien.service.StoreService; import at.tuwien.service.StoreService;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.hibernate.Session; import org.hibernate.*;
import org.hibernate.service.spi.ServiceException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -34,7 +33,7 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService ...@@ -34,7 +33,7 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
} }
@Override @Override
@Transactional @Transactional(readOnly = true)
public List<Query> findAll(Long databaseId) throws DatabaseNotFoundException, ImageNotSupportedException, public List<Query> findAll(Long databaseId) throws DatabaseNotFoundException, ImageNotSupportedException,
QueryStoreException { QueryStoreException {
/* find */ /* find */
...@@ -43,14 +42,12 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService ...@@ -43,14 +42,12 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
throw new ImageNotSupportedException("Currently only MariaDB is supported"); throw new ImageNotSupportedException("Currently only MariaDB is supported");
} }
/* run query */ /* run query */
final Session session = getSessionFactory(database) final SessionFactory sessionFactory = getSessionFactory(database);
.openSession(); final Session session = sessionFactory.openSession();
session.beginTransaction(); final Transaction transaction = session.beginTransaction();
/* use jpq to select all */ /* use jpq to select all */
final org.hibernate.query.Query<Query> queries = session.createQuery("from Query where databaseId = :id", Query.class); final org.hibernate.query.Query<Query> queries = session.createQuery("select q from Query q", Query.class);
queries.setParameter("id", databaseId); transaction.commit();
session.getTransaction()
.commit();
final List<Query> out = queries.list(); final List<Query> out = queries.list();
log.info("Found {} queries", out.size()); log.info("Found {} queries", out.size());
session.close(); session.close();
...@@ -58,7 +55,7 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService ...@@ -58,7 +55,7 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
} }
@Override @Override
@Transactional @Transactional(readOnly = true)
public Query findOne(Long databaseId, Long queryId) throws DatabaseNotFoundException, ImageNotSupportedException, QueryNotFoundException { public Query findOne(Long databaseId, Long queryId) throws DatabaseNotFoundException, ImageNotSupportedException, QueryNotFoundException {
/* find */ /* find */
final Database database = databaseService.find(databaseId); final Database database = databaseService.find(databaseId);
...@@ -66,60 +63,34 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService ...@@ -66,60 +63,34 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
throw new ImageNotSupportedException("Currently only MariaDB is supported"); throw new ImageNotSupportedException("Currently only MariaDB is supported");
} }
/* run query */ /* run query */
final Session session = getSessionFactory(database) final SessionFactory sessionFactory = getSessionFactory(database);
.openSession(); final Session session = sessionFactory.openSession();
session.beginTransaction(); final Transaction transaction = session.beginTransaction();
/* use jpa to select one */ /* use jpa to select one */
final org.hibernate.query.Query<Query> query = session.createQuery("from Query where databaseId = :dbid and id = :id", final org.hibernate.query.Query<Query> query = session.createQuery("from Query where databaseId = :dbid and id = :id",
Query.class); Query.class);
query.setParameter("id", queryId); query.setParameter("id", queryId);
query.setParameter("dbid", databaseId); query.setParameter("dbid", databaseId);
session.getTransaction() final Query result = query.uniqueResult();
.commit(); transaction.commit();
final List<Query> queries = query.list(); if (result == null) {
if (queries.size() != 1) { log.error("Query not found with id {}", queryId);
log.error("Could not find query with id {}", queryId);
log.debug("result list is {}", queries.size());
throw new QueryNotFoundException("Query was not found"); throw new QueryNotFoundException("Query was not found");
} }
log.info("Found query with id {}", queryId); log.info("Found query with id {}", queryId);
session.close(); session.close();
return queries.get(0); return result;
} }
@Override @Override
@Transactional @Transactional(readOnly = true)
public void create(Long databaseId) throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException {
/* find */
final Database database = databaseService.find(databaseId);
if (!database.getContainer().getImage().getRepository().equals("mariadb")) {
throw new ImageNotSupportedException("Currently only MariaDB is supported");
}
/* run query */
final Session session;
try {
session = getSessionFactory(database)
.openSession();
} catch (ServiceException e) {
log.error("Session opening failed");
throw new QueryStoreException("session failed", e);
}
session.beginTransaction();
log.info("Created querstore for database id {}", databaseId);
session.getTransaction()
.commit();
session.close();
}
@Override
@Transactional
public Query insert(Long databaseId, QueryResultDto result, SaveStatementDto metadata) public Query insert(Long databaseId, QueryResultDto result, SaveStatementDto metadata)
throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException { throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException {
return insert(databaseId, result, queryMapper.saveStatementDtoToExecuteStatementDto(metadata)); return insert(databaseId, result, queryMapper.saveStatementDtoToExecuteStatementDto(metadata));
} }
@Override @Override
@Transactional @Transactional(readOnly = true)
public Query insert(Long databaseId, QueryResultDto result, ExecuteStatementDto metadata) public Query insert(Long databaseId, QueryResultDto result, ExecuteStatementDto metadata)
throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException { throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException {
/* find */ /* find */
...@@ -127,16 +98,16 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService ...@@ -127,16 +98,16 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
if (!database.getContainer().getImage().getRepository().equals("mariadb")) { if (!database.getContainer().getImage().getRepository().equals("mariadb")) {
throw new ImageNotSupportedException("Currently only MariaDB is supported"); throw new ImageNotSupportedException("Currently only MariaDB is supported");
} }
/* run query */ /* save */
final Session session; final SessionFactory sessionFactory;
try { try {
session = getSessionFactory(database) sessionFactory = getSessionFactory(database);
.openSession(); } catch (HibernateException e) {
} catch (ServiceException e) { log.error("Failed to open session");
log.error("Session opening failed"); throw new QueryStoreException("Failed to open session", e);
throw new QueryStoreException("session failed", e);
} }
session.beginTransaction(); final Session session = sessionFactory.openSession();
final Transaction transaction = session.beginTransaction();
final Query query = Query.builder() final Query query = Query.builder()
.databaseId(databaseId) .databaseId(databaseId)
.query(metadata.getStatement()) .query(metadata.getStatement())
...@@ -146,13 +117,11 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService ...@@ -146,13 +117,11 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService
.resultHash(DigestUtils.sha256Hex(result.getResult().toString())) .resultHash(DigestUtils.sha256Hex(result.getResult().toString()))
.execution(Instant.now()) .execution(Instant.now())
.build(); .build();
session.save(query);
transaction.commit();
/* store the result in the query store */ /* store the result in the query store */
final Long id = (Long) session.save(query); log.info("Saved query with id {}", query.getId());
query.setId(id);
log.info("Saved query with id {}", id);
log.debug("saved query {}", query); log.debug("saved query {}", query);
session.getTransaction()
.commit();
session.close(); session.close();
return query; return query;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment