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

Fixed some parts

Former-commit-id: f56aeb56
parent bcc1b005
No related branches found
No related tags found
1 merge request!42Fixed the query service tests
Showing
with 609 additions and 174 deletions
{
"name": "Public Transport in Zurich",
"repository": "mariadb",
"tag": "10.5"
}
\ No newline at end of file
{
"action": "START"
}
\ No newline at end of file
{
"description": "The data was collected and organized by https://data.stadt-zuerich.ch/ specifically under the link https://data.stadt-zuerich.ch/dataset/vbz-fahrzeiten-ogd. The data table is a variance analysis of the times certain trams and busses should have departed and when they actually departed. What is the fastest way between Klusplatz and Oerlikon at different times of day? What is the most punctual tram stop in Zurich?",
"description": "Public transport routes and schedules for the city of Zurich",
"is_public": true,
"name": "Public Transport in Zurich"
}
\ No newline at end of file
......@@ -2,21 +2,54 @@
GATEWAY="$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' fda-gateway-service):9095"
# fda-container-service
curl -d '@.fda-deployment/fda-container-service/create-container-air.json' -X POST "http://${GATEWAY}/api/container/" -H "Content-Type: application/json" && echo "seeded container air"
#curl -d '@fda-container-service/create-container-infection.json' -X POST "http://${GATEWAY}/api/container/" -H "Content-Type: application/json" && echo "seeded container infection"
#curl -d '@fda-container-service/create-container-weather.json' -X POST "http://${GATEWAY}/api/container/" -H "Content-Type: application/json" && echo "seeded container weather"
#
## fda-database-service
#curl -d '@fda-database-service/create-database-air.json' -X POST "http://${GATEWAY}/api/database/" -H "Content-Type: application/json"
#curl -d '@fda-database-service/create-database-infection.json' -X POST "http://${GATEWAY}/api/database/" -H "Content-Type: application/json"
#curl -d '@fda-database-service/create-database-weather.json' -X POST "http://${GATEWAY}/api/database/" -H "Content-Type: application/json"
#
## fda-table-service
#curl -d '@fda-table-service/create-table-air.json' -X POST "http://${GATEWAY}/api/database/1/table" -H "Content-Type: application/json"
#curl -d '@fda-table-service/create-table-infection.json' -X POST "http://${GATEWAY}/api/database/2/table" -H "Content-Type: application/json"
#curl -d '@fda-table-service/create-table-weather.json' -X POST "http://${GATEWAY}/api/database/3/table" -H "Content-Type: application/json"
#
## fda-query-service
STATUS=$(curl -X POST "http://${GATEWAY}/api/container/" \
-o /dev/null -w "%{http_code}" -s -m 10 -d '@.fda-deployment/fda-container-service/create-container-traffic.json' \
-H "Content-Type: application/json")
if [ "${STATUS}" != 201 ]; then
echo "[ERROR] container create"
echo "${STATUS}"
exit 1
fi
echo "[INFO] Created container"
STATUS=$(curl -X PUT "http://${GATEWAY}/api/container/1" \
-o /dev/null -w "%{http_code}" -s -m 10 -d '@.fda-deployment/fda-container-service/start-container-traffic.json' \
-H "Content-Type: application/json")
if [ "${STATUS}" != 202 ]; then
echo "[ERROR] container start"
echo "${STATUS}"
exit 2
fi
echo "[INFO] Started container"
# fda-database-service
STATUS=$(curl -X POST "http://${GATEWAY}/api/container/1/database" \
-o /dev/null -w "%{http_code}" -s -m 10 -d '@.fda-deployment/fda-database-service/create-database-traffic.json' \
-H "Content-Type: application/json")
if [ "${STATUS}" != 201 ]; then
echo "[ERROR] database create"
echo "${STATUS}"
exit 3
fi
echo "[INFO] Created database"
# fda-table-service
STATUS=$(curl -X POST "http://${GATEWAY}/api/container/1/database/1/table" \
-o /dev/null -w "%{http_code}" -s -m 10 -d '@.fda-deployment/fda-table-service/create-table-traffic.json' \
-H "Content-Type: application/json")
if [ "${STATUS}" != 201 ]; then
echo "[ERROR] table create"
echo "${STATUS}"
exit 4
fi
echo "[INFO] Created table"
# fda-query-service
STATUS=$(curl -X POST "http://${GATEWAY}/api/container/1/database/1/table/1/data?location=%2Ftmp%2Ffahrzeitensollist2017011520170121.csv" \
-o /dev/null -w "%{http_code}" -s -m 10 \
-H "Content-Type: application/json")
if [ "${STATUS}" != 201 ]; then
echo "[ERROR] dataset import"
echo "${STATUS}"
exit 5
fi
echo "[INFO] Imported dataset"
#curl -d '@fda-query-service/create-query-air1.json' -X POST "http://${GATEWAY}/api/database/1/query" -H "Content-Type: application/json"
#curl -d '@fda-query-service/create-query-air2.json' -X POST "http://${GATEWAY}/api/database/1/query" -H "Content-Type: application/json"
#curl -d '@fda-query-service/create-query-air3.json' -X POST "http://${GATEWAY}/api/database/1/query" -H "Content-Type: application/json"
......
......@@ -94,7 +94,7 @@ public class ContainerServiceIntegrationTest extends BaseUnitTest {
CONTAINER_1.setHash(request.getId());
/* mock data */
log.debug("save image {}", IMAGE_1);
log.debug("save image {}, dialect {}, driver {}", IMAGE_1, IMAGE_1_DIALECT, IMAGE_1_DRIVER);
imageRepository.save(IMAGE_1);
log.debug("save container {}", CONTAINER_1);
containerRepository.save(CONTAINER_1);
......
......@@ -18,9 +18,7 @@ import java.util.stream.Collectors;
@Mapper(componentModel = "spring")
public interface ImageMapper {
@Mappings({
@Mapping(target = "label", expression = "java(data.getRepository() + \":\" + data.getTag())")
})
@Mappings({})
ImageBriefDto containerImageToImageBriefDto(ContainerImage data);
@Mappings({
......
......@@ -19,19 +19,15 @@ public class ImageBriefDto {
private Long id;
@NotBlank
@ApiModelProperty(required = true, example = "postgres:latest")
private String label;
@NotBlank
@ApiModelProperty(required = true, example = "postgres")
@ApiModelProperty(required = true, example = "mariadb")
private String repository;
@NotBlank
@ToString.Exclude
@ApiModelProperty(required = true, example = "base64:aaaa")
private String logo;
@NotBlank
@ApiModelProperty(required = true, example = "latest")
@ApiModelProperty(required = true, example = "10.5")
private String tag;
}
......@@ -65,14 +65,13 @@ public class TableEndpoint {
@ApiResponse(code = 401, message = "Not authorized to create a tables."),
@ApiResponse(code = 404, message = "The database does not exist."),
@ApiResponse(code = 405, message = "The container is not running."),
@ApiResponse(code = 409, message = "The container image is not supported."),
@ApiResponse(code = 422, message = "The ."),
@ApiResponse(code = 409, message = "The table name already exists."),
})
public ResponseEntity<TableBriefDto> create(@NotNull @PathVariable("id") Long id,
@NotNull @PathVariable("databaseId") Long databaseId,
@NotNull @Valid @RequestBody TableCreateDto createDto)
throws ImageNotSupportedException, DatabaseNotFoundException, DataProcessingException,
ArbitraryPrimaryKeysException, TableMalformedException, AmqpException {
ArbitraryPrimaryKeysException, TableMalformedException, AmqpException, TableNameExistsException {
final Table table = tableService.createTable(databaseId, createDto);
amqpService.createQueue(table);
return ResponseEntity.status(HttpStatus.CREATED)
......
......@@ -93,6 +93,16 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ExceptionHandler({TableNameExistsException.class})
public ResponseEntity<Object> handle(TableNameExistsException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.CONFLICT)
.message(e.getLocalizedMessage())
.code("error.database.name")
.build();
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ExceptionHandler({TableMalformedException.class})
public ResponseEntity<Object> handle(TableMalformedException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
......
......@@ -32,6 +32,11 @@ public abstract class BaseUnitTest extends CsvUnitTest {
public final static String DATABASE_2_INTERNALNAME = "weather";
public final static String DATABASE_2_EXCHANGE = "fda." + DATABASE_2_INTERNALNAME;
public final static Long DATABASE_3_ID = 3L;
public final static String DATABASE_3_NAME = "Traffic";
public final static String DATABASE_3_INTERNALNAME = "traffic";
public final static String DATABASE_3_EXCHANGE = "fda." + DATABASE_3_INTERNALNAME;
public final static Long TABLE_1_ID = 1L;
public final static String TABLE_1_NAME = "Weather AUS";
public final static String TABLE_1_INTERNALNAME = "weather_aus";
......@@ -56,6 +61,18 @@ public abstract class BaseUnitTest extends CsvUnitTest {
public final static String TABLE_2_TRUE_ELEMENT = null;
public final static String TABLE_2_FALSE_ELEMENT = null;
public final static Long TABLE_3_ID = 3L;
public final static String TABLE_3_NAME = "Traffic";
public final static String TABLE_3_INTERNALNAME = "traffic";
public final static String TABLE_3_DESCRIPTION = "Traffic in Zürich";
public final static String TABLE_3_TOPIC = DATABASE_3_EXCHANGE + "." + TABLE_3_INTERNALNAME;
public final static Instant TABLE_3_LAST_MODIFIED = Instant.now();
public final static Boolean TABLE_3_SKIP_HEADERS = true;
public final static String TABLE_3_NULL_ELEMENT = "NA";
public final static Character TABLE_3_SEPARATOR = ',';
public final static String TABLE_3_TRUE_ELEMENT = null;
public final static String TABLE_3_FALSE_ELEMENT = null;
public final static Long COLUMN_1_1_ID = 1L;
public final static Integer COLUMN_1_1_ORDINALPOS = 0;
public final static Boolean COLUMN_1_1_PRIMARY = true;
......@@ -191,6 +208,22 @@ public abstract class BaseUnitTest extends CsvUnitTest {
public final static String CONTAINER_1_IP = "172.28.0.5";
public final static Instant CONTAINER_1_CREATED = Instant.now().minus(1, HOURS);
public final static Long CONTAINER_2_ID = 2L;
public final static String CONTAINER_2_HASH = "deadbeef";
public final static ContainerImage CONTAINER_2_IMAGE = IMAGE_1;
public final static String CONTAINER_2_NAME = "u02";
public final static String CONTAINER_2_INTERNALNAME = "fda-userdb-u02";
public final static String CONTAINER_2_IP = "172.28.0.6";
public final static Instant CONTAINER_2_CREATED = Instant.now().minus(1, HOURS);
public final static Long CONTAINER_3_ID = 3L;
public final static String CONTAINER_3_HASH = "deadbeef";
public final static ContainerImage CONTAINER_3_IMAGE = IMAGE_1;
public final static String CONTAINER_3_NAME = "u03";
public final static String CONTAINER_3_INTERNALNAME = "fda-userdb-u03";
public final static String CONTAINER_3_IP = "172.28.0.7";
public final static Instant CONTAINER_3_CREATED = Instant.now().minus(1, HOURS);
public final static Container CONTAINER_1 = Container.builder()
.id(CONTAINER_1_ID)
.name(CONTAINER_1_NAME)
......@@ -200,6 +233,24 @@ public abstract class BaseUnitTest extends CsvUnitTest {
.created(CONTAINER_1_CREATED)
.build();
public final static Container CONTAINER_2 = Container.builder()
.id(CONTAINER_2_ID)
.name(CONTAINER_2_NAME)
.internalName(CONTAINER_2_INTERNALNAME)
.image(CONTAINER_2_IMAGE)
.hash(CONTAINER_2_HASH)
.created(CONTAINER_2_CREATED)
.build();
public final static Container CONTAINER_3 = Container.builder()
.id(CONTAINER_3_ID)
.name(CONTAINER_3_NAME)
.internalName(CONTAINER_3_INTERNALNAME)
.image(CONTAINER_3_IMAGE)
.hash(CONTAINER_3_HASH)
.created(CONTAINER_3_CREATED)
.build();
public final static List<TableColumn> TABLE_1_COLUMNS = List.of(TableColumn.builder()
.id(COLUMN_1_1_ID)
.ordinalPosition(COLUMN_1_1_ORDINALPOS)
......@@ -309,6 +360,22 @@ public abstract class BaseUnitTest extends CsvUnitTest {
.skipHeaders(TABLE_2_SKIP_HEADERS)
.build();
public final static Table TABLE_3 = Table.builder()
.id(TABLE_3_ID)
.created(Instant.now())
.internalName(TABLE_3_INTERNALNAME)
.description(TABLE_3_DESCRIPTION)
.name(TABLE_3_NAME)
.lastModified(TABLE_3_LAST_MODIFIED)
.tdbid(DATABASE_3_ID)
.topic(TABLE_3_TOPIC)
.separator(TABLE_3_SEPARATOR)
.nullElement(TABLE_3_NULL_ELEMENT)
.trueElement(TABLE_3_TRUE_ELEMENT)
.falseElement(TABLE_3_FALSE_ELEMENT)
.skipHeaders(TABLE_3_SKIP_HEADERS)
.build();
public final static Database DATABASE_1 = Database.builder()
.id(DATABASE_1_ID)
.created(Instant.now().minus(1, HOURS))
......@@ -321,6 +388,30 @@ public abstract class BaseUnitTest extends CsvUnitTest {
.exchange(DATABASE_1_EXCHANGE)
.build();
public final static Database DATABASE_2 = Database.builder()
.id(DATABASE_2_ID)
.created(Instant.now().minus(1, HOURS))
.lastModified(Instant.now())
.isPublic(false)
.name(DATABASE_2_NAME)
.container(CONTAINER_2)
.tables(List.of(TABLE_2))
.internalName(DATABASE_2_INTERNALNAME)
.exchange(DATABASE_2_EXCHANGE)
.build();
public final static Database DATABASE_3 = Database.builder()
.id(DATABASE_3_ID)
.created(Instant.now().minus(1, HOURS))
.lastModified(Instant.now())
.isPublic(false)
.name(DATABASE_3_NAME)
.container(CONTAINER_3)
.tables(List.of(TABLE_3))
.internalName(DATABASE_3_INTERNALNAME)
.exchange(DATABASE_3_EXCHANGE)
.build();
public final static ColumnCreateDto[] COLUMNS_CSV01 = new ColumnCreateDto[]{
ColumnCreateDto.builder()
.type(COLUMN_1_1_TYPE_DTO)
......@@ -358,4 +449,337 @@ public abstract class BaseUnitTest extends CsvUnitTest {
.unique(COLUMN_1_5_UNIQUE)
.build()};
public final static ColumnCreateDto[] COLUMNS_CSV_CH = new ColumnCreateDto[]{
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("linie")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("richtung")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.DATE)
.name("betriebsdatum")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat("dd.MM.yy")
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("fahrzeug")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("kurs")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("seq_von")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("halt_diva_von")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("halt_punkt_diva_von")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("halt_kurz_von1")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.DATE)
.name("datum_von")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat("dd.MM.yy")
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("soll_an_von")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("ist_an_von")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("soll_ab_von")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("seq_nach")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("halt_diva_nach")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("halt_punkt_diva_nach")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("halt_kurz_nach1")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.DATE)
.name("datum_nach")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat("dd.MM.yy")
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("soll_an_nach")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("ist_an_nach1")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("soll_ab_nach")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("ist_ab_nach")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("fahrt_id")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("fahrweg_id")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("fw_no")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("fw_typ")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("fw_kurz")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.STRING)
.name("fw_lang")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("umlauf_von")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("halt_id_von")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("halt_id_nach")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("halt_punkt_id_von")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build(),
ColumnCreateDto.builder()
.type(ColumnTypeDto.NUMBER)
.name("halt_punkt_id_nach")
.nullAllowed(true)
.primaryKey(false)
.unique(false)
.dateFormat(null)
.checkExpression(null)
.enumValues(null)
.build()
};
}
......@@ -3,15 +3,19 @@ package at.tuwien.endpoint;
import at.tuwien.BaseUnitTest;
import at.tuwien.api.database.table.TableBriefDto;
import at.tuwien.api.database.table.TableCreateDto;
import at.tuwien.api.database.table.TableDto;
import at.tuwien.config.DockerConfig;
import at.tuwien.config.ReadyConfig;
import at.tuwien.endpoints.TableEndpoint;
import at.tuwien.exception.*;
import at.tuwien.repository.jpa.DatabaseRepository;
import at.tuwien.repository.jpa.TableRepository;
import at.tuwien.service.MessageQueueService;
import at.tuwien.service.impl.TableServiceImpl;
import at.tuwien.repository.jpa.ImageRepository;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.exception.NotModifiedException;
import com.github.dockerjava.api.model.Network;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterEach;
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;
......@@ -20,19 +24,18 @@ 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.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Arrays;
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.*;
@Slf4j
@SpringBootTest
@ExtendWith(SpringExtension.class)
public class TableEndpointUnitTest extends BaseUnitTest {
public class TableEndpointIntegrationTest extends BaseUnitTest {
@MockBean
private Channel channel;
......@@ -40,130 +43,88 @@ public class TableEndpointUnitTest extends BaseUnitTest {
@MockBean
private ReadyConfig readyConfig;
@MockBean
private TableServiceImpl tableService;
@MockBean
private TableRepository tableRepository;
@MockBean
private DatabaseRepository databaseRepository;
@MockBean
private MessageQueueService messageQueueService;
@Autowired
private TableEndpoint tableEndpoint;
@Test
public void findAll_succeeds() throws DatabaseNotFoundException {
@Autowired
private ImageRepository imageRepository;
/* mock */
when(tableRepository.findByDatabase(DATABASE_1))
.thenReturn(List.of(TABLE_1));
when(tableService.findAll(DATABASE_1_ID))
.thenReturn(List.of(TABLE_1));
@Autowired
private DatabaseRepository databaseRepository;
/* test */
final ResponseEntity<List<TableBriefDto>> response = tableEndpoint.findAll(CONTAINER_1_ID, DATABASE_1_ID);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(1, Objects.requireNonNull(response.getBody()).size());
@BeforeEach
@Transactional
public void beforeEach() {
afterEach();
/* 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 CreateContainerResponse response = dockerClient.createContainerCmd(IMAGE_1_REPOSITORY + ":" + IMAGE_1_TAG)
.withHostConfig(hostConfig.withNetworkMode("fda-userdb"))
.withName(CONTAINER_3_INTERNALNAME)
.withIpv4Address(CONTAINER_3_IP)
.withHostName(CONTAINER_3_INTERNALNAME)
.withEnv("MARIADB_USER=mariadb", "MARIADB_PASSWORD=mariadb", "MARIADB_ROOT_PASSWORD=mariadb", "MARIADB_DATABASE=traffic")
.exec();
CONTAINER_3.setHash(response.getId());
/* repository */
imageRepository.save(IMAGE_1);
databaseRepository.save(DATABASE_1);
databaseRepository.save(DATABASE_2);
databaseRepository.save(DATABASE_3);
}
@Test
public void create_succeeds() throws DatabaseNotFoundException, ImageNotSupportedException,
TableNotFoundException, DataProcessingException, ArbitraryPrimaryKeysException, TableMalformedException,
AmqpException, IOException, TableNameExistsException {
final TableCreateDto request = TableCreateDto.builder()
.name(TABLE_1_NAME)
.description(TABLE_1_DESCRIPTION)
.columns(COLUMNS_CSV01)
.build();
/* mock */
when(tableRepository.findById(TABLE_1_ID))
.thenReturn(Optional.of(TABLE_1));
when(tableService.findById(DATABASE_1_ID, TABLE_1_ID))
.thenReturn(TABLE_1);
doNothing()
.when(messageQueueService)
.create(TABLE_1);
/* test */
final ResponseEntity<TableBriefDto> response = tableEndpoint.create(CONTAINER_1_ID, DATABASE_1_ID, request);
assertEquals(HttpStatus.CREATED, response.getStatusCode());
@AfterEach
public void afterEach() {
/* 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
}
@Test
public void create_databaseNotFound_fails() throws DatabaseNotFoundException, ImageNotSupportedException,
TableMalformedException, TableNameExistsException {
final TableCreateDto request = TableCreateDto.builder()
.name(TABLE_1_NAME)
.description(TABLE_1_DESCRIPTION)
.columns(COLUMNS_CSV01)
.build();
when(tableService.createTable(DATABASE_1_ID, request))
.thenAnswer(invocation -> {
throw new DatabaseNotFoundException("no db");
});
/* test */
assertThrows(DatabaseNotFoundException.class, () -> {
tableEndpoint.create(CONTAINER_1_ID, DATABASE_1_ID, request);
dockerClient.removeContainerCmd(container.getId()).exec();
});
}
@Test
public void findById_succeeds() throws TableNotFoundException, DatabaseNotFoundException {
when(tableService.findById(DATABASE_1_ID, TABLE_1_ID))
.thenReturn(TABLE_1);
/* test */
final ResponseEntity<TableDto> response = tableEndpoint.findById(CONTAINER_1_ID, DATABASE_1_ID, TABLE_1_ID);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals(TABLE_1_ID, Objects.requireNonNull(response.getBody()).getId());
assertEquals(TABLE_1_NAME, Objects.requireNonNull(response.getBody()).getName());
}
@Test
public void findById_notFound_fails() throws TableNotFoundException, DatabaseNotFoundException {
when(tableRepository.findById(TABLE_1_ID))
.thenReturn(Optional.empty());
doThrow(TableNotFoundException.class)
.when(tableService)
.findById(DATABASE_1_ID, TABLE_1_ID);
/* test */
assertThrows(TableNotFoundException.class, () -> {
tableEndpoint.findById(CONTAINER_1_ID, DATABASE_1_ID, TABLE_1_ID);
/* 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();
});
}
@Test
public void delete_notFound_fails() throws TableNotFoundException, DatabaseNotFoundException,
ImageNotSupportedException {
doThrow(TableNotFoundException.class)
.when(tableService)
.deleteTable(DATABASE_1_ID, TABLE_1_ID);
/* test */
assertThrows(TableNotFoundException.class, () -> {
tableEndpoint.delete(CONTAINER_1_ID, DATABASE_1_ID, TABLE_1_ID);
});
}
public void create_succeeds() throws DatabaseNotFoundException, ImageNotSupportedException,
DataProcessingException, ArbitraryPrimaryKeysException, TableMalformedException,
AmqpException, TableNameExistsException, InterruptedException {
final TableCreateDto request = TableCreateDto.builder()
.name(TABLE_3_NAME)
.description(TABLE_3_DESCRIPTION)
.columns(COLUMNS_CSV_CH)
.build();
@Test
public void delete_succeeds() throws TableNotFoundException, DatabaseNotFoundException, ImageNotSupportedException,
DataProcessingException {
/* test */
tableEndpoint.delete(CONTAINER_1_ID, DATABASE_1_ID, TABLE_1_ID);
}
/* mock */
DockerConfig.startContainer(CONTAINER_3);
@Test
public void update_fails() {
/* test */
final ResponseEntity<TableBriefDto> response = tableEndpoint.update(CONTAINER_1_ID, DATABASE_1_ID, TABLE_1_ID);
assertEquals(HttpStatus.UNPROCESSABLE_ENTITY, response.getStatusCode());
final ResponseEntity<TableBriefDto> response = tableEndpoint.create(CONTAINER_3_ID, DATABASE_3_ID, request);
assertEquals(HttpStatus.CREATED, response.getStatusCode());
}
}
......@@ -73,7 +73,7 @@ public class TableEndpointUnitTest extends BaseUnitTest {
@Test
public void create_succeeds() throws DatabaseNotFoundException, ImageNotSupportedException,
TableNotFoundException, DataProcessingException, ArbitraryPrimaryKeysException, TableMalformedException,
AmqpException, IOException {
AmqpException, IOException, TableNameExistsException {
final TableCreateDto request = TableCreateDto.builder()
.name(TABLE_1_NAME)
.description(TABLE_1_DESCRIPTION)
......@@ -96,7 +96,7 @@ public class TableEndpointUnitTest extends BaseUnitTest {
@Test
public void create_databaseNotFound_fails() throws DatabaseNotFoundException, ImageNotSupportedException,
TableMalformedException {
TableMalformedException, TableNameExistsException {
final TableCreateDto request = TableCreateDto.builder()
.name(TABLE_1_NAME)
.description(TABLE_1_DESCRIPTION)
......@@ -114,8 +114,7 @@ public class TableEndpointUnitTest extends BaseUnitTest {
}
@Test
public void findById_succeeds() throws TableNotFoundException, DatabaseNotFoundException,
ImageNotSupportedException {
public void findById_succeeds() throws TableNotFoundException, DatabaseNotFoundException {
when(tableService.findById(DATABASE_1_ID, TABLE_1_ID))
.thenReturn(TABLE_1);
......
......@@ -127,7 +127,7 @@ public class TableServiceIntegrationTest extends BaseUnitTest {
@Test
public void createTable_succeeds() throws ArbitraryPrimaryKeysException, DatabaseNotFoundException,
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException {
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException, TableNameExistsException {
final TableCreateDto request = TableCreateDto.builder()
.name(TABLE_2_NAME)
.description(TABLE_2_DESCRIPTION)
......@@ -149,7 +149,7 @@ public class TableServiceIntegrationTest extends BaseUnitTest {
@Test
public void createTable_noPrimaryKeyAutoGenerate_succeeds() throws ArbitraryPrimaryKeysException, DatabaseNotFoundException,
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException {
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException, TableNameExistsException {
final ColumnCreateDto[] columns = new ColumnCreateDto[]{
ColumnCreateDto.builder()
.name(COLUMN_1_2_NAME)
......@@ -183,7 +183,7 @@ public class TableServiceIntegrationTest extends BaseUnitTest {
@Test
public void createTable_noPrimaryKeyAutoGenerateEmpty_succeeds() throws ArbitraryPrimaryKeysException, DatabaseNotFoundException,
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException {
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException, TableNameExistsException {
final ColumnCreateDto[] columns = new ColumnCreateDto[0];
final TableCreateDto request = TableCreateDto.builder()
.name(TABLE_2_NAME)
......@@ -245,7 +245,7 @@ public class TableServiceIntegrationTest extends BaseUnitTest {
@Test
public void createTable_groupPrimaryKey_succeeds() throws ArbitraryPrimaryKeysException, DatabaseNotFoundException,
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException {
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException, TableNameExistsException {
final ColumnCreateDto[] columns = new ColumnCreateDto[]{
ColumnCreateDto.builder()
.name(COLUMN_1_1_NAME)
......@@ -288,7 +288,7 @@ public class TableServiceIntegrationTest extends BaseUnitTest {
@Test
public void createTable_checkExpression_succeeds() throws ArbitraryPrimaryKeysException, DatabaseNotFoundException,
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException {
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException, TableNameExistsException {
final ColumnCreateDto[] columns = new ColumnCreateDto[]{
ColumnCreateDto.builder()
.name(COLUMN_1_1_NAME)
......@@ -321,7 +321,7 @@ public class TableServiceIntegrationTest extends BaseUnitTest {
@Test
public void createTable_withEnum_succeeds() throws ArbitraryPrimaryKeysException, DatabaseNotFoundException,
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException {
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException, TableNameExistsException {
final ColumnCreateDto[] columns = new ColumnCreateDto[]{
ColumnCreateDto.builder()
.name(COLUMN_1_1_NAME)
......@@ -365,7 +365,7 @@ public class TableServiceIntegrationTest extends BaseUnitTest {
@Test
public void createTable_withUniqueColumn_succeeds() throws ArbitraryPrimaryKeysException, DatabaseNotFoundException,
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException {
ImageNotSupportedException, DataProcessingException, TableMalformedException, InterruptedException, TableNameExistsException {
final ColumnCreateDto[] columns = new ColumnCreateDto[]{
ColumnCreateDto.builder()
.name(COLUMN_1_1_NAME)
......@@ -428,7 +428,7 @@ public class TableServiceIntegrationTest extends BaseUnitTest {
@Test
public void createTable_textPrimaryKey_succeeds() throws InterruptedException, SQLException, TableMalformedException,
ArbitraryPrimaryKeysException, DatabaseNotFoundException, ImageNotSupportedException,
DataProcessingException {
DataProcessingException, TableNameExistsException {
final TableCreateDto request = TableCreateDto.builder()
.name("Issue 99")
.description("Related to issue 99")
......@@ -461,7 +461,7 @@ public class TableServiceIntegrationTest extends BaseUnitTest {
@Test
public void createTable_blobPrimaryKey_succeeds() throws InterruptedException, SQLException, TableMalformedException,
ArbitraryPrimaryKeysException, DatabaseNotFoundException, ImageNotSupportedException,
DataProcessingException {
DataProcessingException, TableNameExistsException {
final TableCreateDto request = TableCreateDto.builder()
.name("Issue 99")
.description("Related to issue 99")
......@@ -506,7 +506,7 @@ public class TableServiceIntegrationTest extends BaseUnitTest {
@Test
public void createTable_issue106_succeeds() throws InterruptedException, SQLException, TableMalformedException,
ArbitraryPrimaryKeysException, DatabaseNotFoundException, ImageNotSupportedException,
DataProcessingException {
DataProcessingException, TableNameExistsException {
final TableCreateDto request = TableCreateDto.builder()
.name("Table")
.description(TABLE_2_DESCRIPTION)
......
......@@ -3,20 +3,18 @@ package at.tuwien.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
import java.io.IOException;
@ResponseStatus(code = HttpStatus.CONFLICT)
public class TableNameExistsException extends Exception {
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
public class TableMalformedException extends Exception {
public TableMalformedException(String msg) {
public TableNameExistsException(String msg) {
super(msg);
}
public TableMalformedException(String msg, Throwable thr) {
public TableNameExistsException(String msg, Throwable thr) {
super(msg, thr);
}
public TableMalformedException(Throwable thr) {
public TableNameExistsException(Throwable thr) {
super(thr);
}
......
......@@ -199,7 +199,7 @@ public interface TableMapper {
/* null expressions */
.append(c.getNullAllowed() ? " NULL" : " NOT NULL")
/* default expressions */
.append(!primaryColumnExists && c.getName().equals("id") ? " DEFAULT NEXTVAL(`seq_id`)" : "")
.append(!primaryColumnExists && c.getName().equals("id") ? " DEFAULT NEXTVAL(" + tableCreateDtoToSequenceName(data) + ")" : "")
/* check expressions */
.append(c.getCheckExpression() != null &&
!c.getCheckExpression().isEmpty() ? " CHECK (" + c.getCheckExpression() + ")" : ""));
......@@ -237,12 +237,16 @@ public interface TableMapper {
.build();
}
default String tableCreateDtoToSequenceName(TableCreateDto data) {
return "`seq_" + nameToInternalName(data.getName()) + "_id`";
}
default String tableToCreateSequenceRawQuery(Database database, TableCreateDto data)
throws ImageNotSupportedException {
if (!database.getContainer().getImage().getRepository().equals("mariadb")) {
throw new ImageNotSupportedException("Currently only MariaDB is supported");
}
return "CREATE SEQUENCE `seq_id` START WITH 1 INCREMENT BY 1;";
return "CREATE SEQUENCE " + tableCreateDtoToSequenceName(data) + " START WITH 1 INCREMENT BY 1;";
}
}
......@@ -52,6 +52,6 @@ public interface TableService {
* @throws TableMalformedException The table seems malformed by the mapper.
*/
Table createTable(Long databaseId, TableCreateDto createDto) throws ImageNotSupportedException,
DatabaseNotFoundException, DataProcessingException, ArbitraryPrimaryKeysException, TableMalformedException;
DatabaseNotFoundException, DataProcessingException, ArbitraryPrimaryKeysException, TableMalformedException, TableNameExistsException;
}
......@@ -55,6 +55,7 @@ public class TableServiceImpl extends HibernateConnector implements TableService
session.createSQLQuery(tableMapper.tableToDropTableRawQuery(table));
transaction.commit();
session.close();
log.info("Deleted table with id {}", table.getId());
}
@Override
......@@ -71,7 +72,7 @@ public class TableServiceImpl extends HibernateConnector implements TableService
@Override
@Transactional
public Table createTable(Long databaseId, TableCreateDto createDto) throws ImageNotSupportedException,
DatabaseNotFoundException, TableMalformedException {
DatabaseNotFoundException, TableMalformedException, TableNameExistsException {
/* find */
final Database database = databaseService.findDatabase(databaseId);
/* run query */
......@@ -102,6 +103,7 @@ public class TableServiceImpl extends HibernateConnector implements TableService
.forEach(column -> {
column.setOrdinalPosition(idx[0]++);
});
log.info("Created table with id {}", table.getId());
log.debug("Saving table {}",table);
return tableRepository.save(table);
}
......
<template>
<div>
<v-progress-linear v-if="loading" :indeterminate="!error" />
<v-tabs-items>
<v-card v-if="!loading && queries.length === 0" flat>
<v-card-title>
......
<template>
<div>
<v-progress-linear v-if="loading" :indeterminate="!error" />
<v-card v-if="!loading && tables.length === 0" flat>
<v-card-title>
(no tables)
......
<template>
<div v-if="db">
<DBToolbar />
<v-progress-linear v-if="loading" :indeterminate="!error" />
<v-tabs-items v-model="tab">
<v-card flat>
<v-card-title>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment