diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index df1d27a0704c0e7c2ff793f4bb177db69e3afdd5..2e63d7f758e379d84ce50573d73ef0a9c2ee9208 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -70,6 +70,9 @@ services: environment: SPRING_PROFILES_ACTIVE: docker TZ: Europe/Vienna + depends_on: + fda-discovery-service: + condition: service_healthy ports: - "9095:9095" logging: @@ -93,14 +96,6 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock depends_on: - fda-discovery-service: - condition: service_healthy - fda-authentication-service: - condition: service_healthy - fda-broker-service: - condition: service_healthy - fda-metadata-db: - condition: service_healthy fda-container-service: condition: service_healthy logging: @@ -123,12 +118,8 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock depends_on: - fda-discovery-service: - condition: service_healthy fda-authentication-service: condition: service_healthy - fda-metadata-db: - condition: service_healthy logging: driver: json-file @@ -147,10 +138,6 @@ services: ports: - "9097:9097" depends_on: - fda-metadata-db: - condition: service_healthy - fda-discovery-service: - condition: service_healthy fda-discovery-service: condition: service_healthy logging: @@ -167,23 +154,15 @@ services: ipv4_address: 172.29.0.12 fda-userdb: environment: - SPRING_PROFILES_ACTIVE: docker + SPRING_PROFILES_ACTIVE: docker,seeder TZ: Europe/Vienna ports: - "9093:9093" volumes: - /tmp:/tmp depends_on: - fda-discovery-service: - condition: service_healthy - fda-container-service: - condition: service_healthy - fda-authentication-service: - condition: service_healthy fda-table-service: condition: service_healthy - fda-metadata-db: - condition: service_healthy logging: driver: json-file @@ -207,18 +186,8 @@ services: - /var/run/docker.sock:/var/run/docker.sock - /tmp:/tmp depends_on: - fda-metadata-db: - condition: service_healthy - fda-discovery-service: - condition: service_healthy - fda-authentication-service: - condition: service_healthy - fda-broker-service: - condition: service_healthy fda-database-service: condition: service_healthy - fda-search-service: - condition: service_started logging: driver: json-file @@ -237,12 +206,6 @@ services: ports: - "9096:9096" depends_on: - fda-metadata-db: - condition: service_healthy - fda-authentication-service: - condition: service_healthy - fda-discovery-service: - condition: service_healthy fda-query-service: condition: service_healthy @@ -267,8 +230,6 @@ services: depends_on: fda-discovery-service: condition: service_healthy - fda-database-service: - condition: service_healthy logging: driver: json-file @@ -309,6 +270,9 @@ services: ports: - "5672:5672" - "15672:15672" + depends_on: + fda-discovery-service: + condition: service_healthy volumes: - fda-broker-service-data:/var/lib/rabbitmq/ logging: @@ -351,23 +315,11 @@ services: - /tmp:/tmp - "./fda-ui/.prod:/certs" depends_on: - fda-container-service: - condition: service_healthy - fda-database-service: - condition: service_healthy - fda-table-service: - condition: service_healthy - fda-query-service: - condition: service_healthy fda-identifier-service: condition: service_healthy - fda-authentication-service: - condition: service_healthy environment: HOST: 0.0.0.0 API: http://fda-gateway-service:9095 TZ: Europe/Vienna - KEY: "${UI_KEY}" - CERT: "${UI_CERT}" logging: driver: json-file \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index adc2fca0ef258bf4f6bba3fd010bd86c2fb42f13..423c75ef18e46e0afbccef62ce6b72b6ed4fd251 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -53,6 +53,9 @@ services: environment: SPRING_PROFILES_ACTIVE: docker TZ: Europe/Vienna + depends_on: + fda-gateway-service: + condition: service_healthy ports: - "9090:9090" logging: @@ -93,14 +96,6 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock depends_on: - fda-discovery-service: - condition: service_healthy - fda-authentication-service: - condition: service_healthy - fda-broker-service: - condition: service_healthy - fda-metadata-db: - condition: service_healthy fda-container-service: condition: service_healthy logging: @@ -123,12 +118,8 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock depends_on: - fda-discovery-service: - condition: service_healthy fda-authentication-service: condition: service_healthy - fda-metadata-db: - condition: service_healthy logging: driver: json-file @@ -147,10 +138,6 @@ services: ports: - "9097:9097" depends_on: - fda-metadata-db: - condition: service_healthy - fda-discovery-service: - condition: service_healthy fda-discovery-service: condition: service_healthy logging: @@ -174,16 +161,8 @@ services: volumes: - /tmp:/tmp depends_on: - fda-discovery-service: - condition: service_healthy - fda-container-service: - condition: service_healthy - fda-authentication-service: - condition: service_healthy fda-table-service: condition: service_healthy - fda-metadata-db: - condition: service_healthy logging: driver: json-file @@ -207,18 +186,8 @@ services: - /var/run/docker.sock:/var/run/docker.sock - /tmp:/tmp depends_on: - fda-metadata-db: - condition: service_healthy - fda-discovery-service: - condition: service_healthy - fda-authentication-service: - condition: service_healthy - fda-broker-service: - condition: service_healthy fda-database-service: condition: service_healthy - fda-search-service: - condition: service_started logging: driver: json-file @@ -237,12 +206,6 @@ services: ports: - "9096:9096" depends_on: - fda-metadata-db: - condition: service_healthy - fda-authentication-service: - condition: service_healthy - fda-discovery-service: - condition: service_healthy fda-query-service: condition: service_healthy @@ -267,8 +230,6 @@ services: depends_on: fda-discovery-service: condition: service_healthy - fda-database-service: - condition: service_healthy logging: driver: json-file @@ -309,6 +270,9 @@ services: ports: - "5672:5672" - "15672:15672" + depends_on: + fda-discovery-service: + condition: service_healthy volumes: - fda-broker-service-data:/var/lib/rabbitmq/ logging: @@ -351,18 +315,8 @@ services: - /tmp:/tmp - "./fda-ui/.prod:/certs" depends_on: - fda-container-service: - condition: service_healthy - fda-database-service: - condition: service_healthy - fda-table-service: - condition: service_healthy - fda-query-service: - condition: service_healthy fda-identifier-service: condition: service_healthy - fda-authentication-service: - condition: service_healthy environment: HOST: 0.0.0.0 API: http://fda-gateway-service:9095 diff --git a/fda-authentication-service/services/src/main/java/at/tuwien/service/impl/UserDetailsServiceImpl.java b/fda-authentication-service/services/src/main/java/at/tuwien/service/impl/UserDetailsServiceImpl.java index bd0887b32ecda00c663d9440536a26bc2c6dcc1d..756e2a1b223ad1e186cc0b681b12682dddd4778d 100644 --- a/fda-authentication-service/services/src/main/java/at/tuwien/service/impl/UserDetailsServiceImpl.java +++ b/fda-authentication-service/services/src/main/java/at/tuwien/service/impl/UserDetailsServiceImpl.java @@ -12,6 +12,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; import java.util.stream.Collectors; @Slf4j @@ -30,11 +31,15 @@ public class UserDetailsServiceImpl implements UserDetailsService { @Override @Transactional(readOnly = true) public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - final User user = userRepository.findByUsername(username) - .orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username)); + final Optional<User> user = userRepository.findByUsername(username); + if (user.isEmpty()) { + log.error("Failed to load user by username {}", username); + throw new UsernameNotFoundException("Failed to load user by username"); + } log.debug("loaded user {}", user); - final UserDetailsDto details = userMapper.userToUserDetailsDto(user); - details.setAuthorities(user.getRoles() + final UserDetailsDto details = userMapper.userToUserDetailsDto(user.get()); + details.setAuthorities(user.get() + .getRoles() .stream() .map(userMapper::roleTypeToGrantedAuthority) .collect(Collectors.toList())); diff --git a/fda-container-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java b/fda-container-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java index 6c487bebef4120ed7e6cf8f34f1290e2fa35e62c..1f6f6840d3fd7b808cb668bd06e4f40eac423546 100644 --- a/fda-container-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java +++ b/fda-container-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java @@ -139,10 +139,21 @@ public abstract class AbstractSeeder { public final static String CONTAINER_1_REPOSITORY = "mariadb"; public final static String CONTAINER_1_TAG = "10.5"; + public final static Long CONTAINER_2_ID = 2L; + public final static String CONTAINER_2_NAME = "Sensor"; + public final static String CONTAINER_2_REPOSITORY = "mariadb"; + public final static String CONTAINER_2_TAG = "10.5"; + public final static ContainerCreateRequestDto CONTAINER_1_CREATE_DTO = ContainerCreateRequestDto.builder() .name(CONTAINER_1_NAME) .repository(CONTAINER_1_REPOSITORY) .tag(CONTAINER_1_TAG) .build(); + public final static ContainerCreateRequestDto CONTAINER_2_CREATE_DTO = ContainerCreateRequestDto.builder() + .name(CONTAINER_2_NAME) + .repository(CONTAINER_2_REPOSITORY) + .tag(CONTAINER_2_TAG) + .build(); + } diff --git a/fda-container-service/services/src/main/java/at/tuwien/seeder/impl/ContainerSeederImpl.java b/fda-container-service/services/src/main/java/at/tuwien/seeder/impl/ContainerSeederImpl.java index c7b5965fee7f589d2c55fd90f905ed2a335f0323..fb6d2efa4dfa4e3aedabe2542e9223841f80b7e6 100644 --- a/fda-container-service/services/src/main/java/at/tuwien/seeder/impl/ContainerSeederImpl.java +++ b/fda-container-service/services/src/main/java/at/tuwien/seeder/impl/ContainerSeederImpl.java @@ -33,6 +33,10 @@ public class ContainerSeederImpl extends AbstractSeeder implements Seeder { log.info("Created container id {}", container1.getId()); final Container container1start = containerService.start(CONTAINER_1_ID); log.info("Started container id {}", container1start.getId()); + final Container container2 = containerService.create(CONTAINER_2_CREATE_DTO); + log.info("Created container id {}", container2.getId()); + final Container container2start = containerService.start(CONTAINER_2_ID); + log.info("Started container id {}", container2start.getId()); } } diff --git a/fda-database-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java b/fda-database-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java index 1e6d9a298f2d487bd01b5d5815c733447a7a7d60..7f073ceb85be56f55819e02f9c64742959f19203 100644 --- a/fda-database-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java +++ b/fda-database-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java @@ -6,6 +6,8 @@ public abstract class AbstractSeeder { public final static Long CONTAINER_1_ID = 1L; + public final static Long CONTAINER_2_ID = 2L; + public final static Long DATABASE_1_ID = 1L; public final static String DATABASE_1_NAME = "Public Transport in Zürich"; public final static String DATABASE_1_DESCRIPTION = "Public transport routes and schedules for the city of Zurich https://www.kaggle.com/laa283/zurich-public-transport/version/2"; @@ -17,4 +19,15 @@ public abstract class AbstractSeeder { .description(DATABASE_1_DESCRIPTION) .build(); + public final static Long DATABASE_2_ID = 2L; + public final static String DATABASE_2_NAME = "Sensor Data collected from the Server"; + public final static String DATABASE_2_DESCRIPTION = "Collection of various live data from the deployment server"; + public final static Boolean DATABASE_2_PUBLIC = true; + + public final static DatabaseCreateDto DATABASE_2_CREATE_DTO = DatabaseCreateDto.builder() + .name(DATABASE_2_NAME) + .isPublic(DATABASE_2_PUBLIC) + .description(DATABASE_2_DESCRIPTION) + .build(); + } diff --git a/fda-database-service/services/src/main/java/at/tuwien/seeder/impl/DatabaseSeederImpl.java b/fda-database-service/services/src/main/java/at/tuwien/seeder/impl/DatabaseSeederImpl.java index c0c1c0f8d70ac3a9abdcda177ca6fb351c44cf60..8bc2d99ff13b8d052062eafdbfc53e9f35656d66 100644 --- a/fda-database-service/services/src/main/java/at/tuwien/seeder/impl/DatabaseSeederImpl.java +++ b/fda-database-service/services/src/main/java/at/tuwien/seeder/impl/DatabaseSeederImpl.java @@ -31,6 +31,8 @@ public class DatabaseSeederImpl extends AbstractSeeder implements Seeder { } final Database database1 = databaseService.create(CONTAINER_1_ID, DATABASE_1_CREATE_DTO); log.info("Seeded database id {}", database1.getId()); + final Database database2 = databaseService.create(CONTAINER_2_ID, DATABASE_2_CREATE_DTO); + log.info("Seeded database id {}", database2.getId()); } } diff --git a/fda-identifier-service/services/src/main/java/at/tuwien/seeder/Seeder.java b/fda-identifier-service/services/src/main/java/at/tuwien/seeder/Seeder.java index 241057caf951d628e2f8935bd4badb27a6a36182..544ccc3054cfa9b48228c2cae37470c4e74f2084 100644 --- a/fda-identifier-service/services/src/main/java/at/tuwien/seeder/Seeder.java +++ b/fda-identifier-service/services/src/main/java/at/tuwien/seeder/Seeder.java @@ -1,10 +1,6 @@ package at.tuwien.seeder; -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.context.event.EventListener; - public interface Seeder { - @EventListener(ApplicationReadyEvent.class) void seed(); } diff --git a/fda-identifier-service/services/src/main/java/at/tuwien/seeder/impl/SeederImpl.java b/fda-identifier-service/services/src/main/java/at/tuwien/seeder/impl/SeederImpl.java index d7d1e29fce3d3a60d458a90f33a362cfe3dab475..bebd3a2f00e5141811b2557da309bd3de5885043 100644 --- a/fda-identifier-service/services/src/main/java/at/tuwien/seeder/impl/SeederImpl.java +++ b/fda-identifier-service/services/src/main/java/at/tuwien/seeder/impl/SeederImpl.java @@ -1,6 +1,7 @@ package at.tuwien.seeder.impl; import at.tuwien.seeder.Seeder; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -17,7 +18,9 @@ public class SeederImpl implements Seeder { } @Override + @SneakyThrows public void seed() { + Thread.sleep(60 * 1000); identifierSeederImpl.seed(); } } diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseBriefDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseBriefDto.java index cb5fd01831b2782fa16a1d3cd79ee55458589182..6e70519e1cfb49d4e071fe625f3ac4d21e1a787b 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseBriefDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseBriefDto.java @@ -15,23 +15,22 @@ import java.time.Instant; @NoArgsConstructor public class DatabaseBriefDto { - @NotNull + @NotNull(message = "database id is required") @Parameter(name = "database id", example = "1") private Long id; - @NotBlank + @NotBlank(message = "name is required") @Parameter(name = "database name", example = "Weather Australia") private String name; - @NotBlank + @NotBlank(message = "description is required") @Parameter(name = "database description", example = "Weather in Australia") private String description; - @NotBlank + @NotBlank(message = "engine is required") @Parameter(name = "database engine", example = "mariadb:latest") private String engine; - @NotBlank @Parameter(name = "database creation time", example = "2020-08-04 11:12:00") private Instant created; diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseCreateDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseCreateDto.java index f4b1b0edcec691be2b38ecd9fad437f89f15785f..fdd88f55449171be5a291a5d0cb256aa4557d3b3 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseCreateDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseCreateDto.java @@ -16,16 +16,16 @@ import javax.validation.constraints.NotNull; @NoArgsConstructor public class DatabaseCreateDto { - @NotBlank + @NotBlank(message = "database name is required") @ApiModelProperty(name = "database name", example = "Weather Australia") private String name; - @NotNull + @NotNull(message = "public attribute is required") @JsonProperty("is_public") @Parameter(name = "database publicity", example = "true") private Boolean isPublic; - @NotBlank + @NotBlank(message = "description is required") @Parameter(name = "database description", example = "true") private String description; diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseDto.java index 80cd617e9aa354bd56b245f4126832bbf89843ab..6fb1b28c55ec6cfabe79b45f590f11166e9d35df 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/DatabaseDto.java @@ -22,7 +22,6 @@ import java.util.List; public class DatabaseDto { @NotNull - @Min(value = 1) @ApiModelProperty(name = "database id", example = "1") private Long id; @@ -59,11 +58,9 @@ public class DatabaseDto { @ApiModelProperty(name = "database publisher", example = "National Office") private String publisher; - @NotBlank @ApiModelProperty(name = "database creation time", example = "2020-08-04 11:12:00") private Instant created; - @NotBlank @ApiModelProperty(name = "database deletion time", example = "2020-08-04 11:13:00") private Instant deleted; diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/ExecuteStatementDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/ExecuteStatementDto.java index 41c49b17d642ac07c838be68e8fed6b4d78d1143..15a8edcc4e5aa717f573ab7aa2d54cd1c18fb427 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/ExecuteStatementDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/ExecuteStatementDto.java @@ -16,15 +16,15 @@ import java.util.List; @NoArgsConstructor public class ExecuteStatementDto { - @NotBlank + @NotBlank(message = "statement is required") @ApiModelProperty(name = "sql query") private String statement; - @NotNull + @NotNull(message = "list of tables is required") @ApiModelProperty(name = "tables mentioned in the query") private List<TableBriefDto> tables; - @NotNull + @NotNull(message = "list of columns is required") @ApiModelProperty(name = "columns mentioned in the query") - private List<ColumnBriefDto> columns; + private List<List<ColumnBriefDto>> columns; } diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/ImportDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/ImportDto.java index 4ef454e40fa145ff10c2faa7ce58feda8eefc059..f1d2b8efbbd5804c153a84696ddc95a8fdff4bc2 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/ImportDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/ImportDto.java @@ -12,7 +12,7 @@ import javax.validation.constraints.NotBlank; @NoArgsConstructor public class ImportDto { - @NotBlank + @NotBlank(message = "location is required") @ApiModelProperty(name = "csv location") private String location; } diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryDto.java index 6a789eafecf966b07b2d2b9a8b1d8c43584657ae..4f12ca0342bd7b08081e75b71103f5915ba2a13e 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryDto.java @@ -18,22 +18,22 @@ import java.time.Instant; @ToString public class QueryDto { - @NotNull + @NotNull(message = "id is required") @ApiModelProperty(name = "query id", example = "1") private Long id; - @NotNull + @NotNull(message = "container id is required") @ApiModelProperty(name = "container id", example = "1") private Long cid; - @NotNull + @NotNull(message = "database id is required") @ApiModelProperty(name = "database id", example = "1") private Long dbid; @ApiModelProperty(name = "execution time", example = "2022-01-01 08:00:00.000") private Instant execution; - @NotBlank + @NotBlank(message = "statement is required") @ApiModelProperty(name = "query raw", example = "select * from table") private String query; @@ -41,7 +41,7 @@ public class QueryDto { @ApiModelProperty(name = "query normalized", example = "select id, name from table") private String queryNormalized; - @NotBlank + @NotBlank(message = "query hash is required") @JsonProperty("query_hash") @ApiModelProperty(name = "query hash sha256", example = "17e682f060b5f8e47ea04c5c4855908b0a5ad612022260fe50e11ecb0cc0ab76") private String queryHash; @@ -54,10 +54,9 @@ public class QueryDto { @ApiModelProperty(name = "result number of records", example = "1") private Long resultNumber; - @NotNull + @NotNull(message = "created timestamp is required") private Instant created; - @NotNull @JsonProperty("last_modified") private Instant lastModified; diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryResultDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryResultDto.java index c2f4a798d75b2be0e60032ec27f4d8fb02e8ceff..31622806f01b599e86e594b2ad848c6260379f7b 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryResultDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/QueryResultDto.java @@ -16,11 +16,11 @@ import java.util.Map; @ToString public class QueryResultDto { - @NotNull + @NotNull(message = "result set is required") @ApiModelProperty(notes = "query result") private List<Map<String, Object>> result; - @NotNull + @NotNull(message = "query id is required") @ApiModelProperty(notes = "query id") private Long id; diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/SaveStatementDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/SaveStatementDto.java index 912c73bb52eab4096fad7dffdcf66967a72a2a23..f798bcab936b66c91a543cd7f5b04c8990587316 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/SaveStatementDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/query/SaveStatementDto.java @@ -12,7 +12,7 @@ import javax.validation.constraints.NotBlank; @NoArgsConstructor public class SaveStatementDto { - @NotBlank + @NotBlank(message = "statement is required") @ApiModelProperty(notes = "sql query") private String statement; } diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/table/TableBriefDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/table/TableBriefDto.java index c06579b13ebb0031d2b0625522cd04556081ce2e..c3c7a24cd061b36089be819ce770d7a7c50104aa 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/table/TableBriefDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/table/TableBriefDto.java @@ -15,15 +15,15 @@ import javax.validation.constraints.NotNull; @NoArgsConstructor public class TableBriefDto { - @NotNull + @NotNull(message = "id is required") @ApiModelProperty(name = "table id", example = "1") private Long id; - @NotBlank + @NotBlank(message = "name is required") @ApiModelProperty(name = "table name", example = "Weather Australia") private String name; - @NotBlank + @NotBlank(message = "internal name is required") @JsonProperty("internal_name") @ApiModelProperty(name = "table internal name", example = "weather_australia") private String internalName; diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/table/columns/ColumnBriefDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/table/columns/ColumnBriefDto.java index 37da670ca03106737dc683577393524f8219694c..a40aa8243fa14bbd1a1611f700ef670abd0edbbf 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/database/table/columns/ColumnBriefDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/database/table/columns/ColumnBriefDto.java @@ -15,15 +15,15 @@ import javax.validation.constraints.NotNull; @NoArgsConstructor public class ColumnBriefDto { - @NotNull + @NotNull(message = "id is required") @ApiModelProperty(name = "id", example = "1", required = true) private Long id; - @NotBlank + @NotBlank(message = "name is required") @ApiModelProperty(name = "name", example = "Date", required = true) private String name; - @NotBlank + @NotBlank(message = "internal name is required") @JsonProperty("internal_name") @ApiModelProperty(name = "internal name", example = "mdb_date", required = true) private String internalName; diff --git a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java index f4e1c82b559f5081ca83272740d68864fb85825d..a04384712e1209ae8fe4b0173a88255a55a29537 100644 --- a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java +++ b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/QueryEndpoint.java @@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import javax.validation.constraints.NotNull; +import java.time.Instant; @Log4j2 @RestController @@ -36,18 +37,19 @@ public class QueryEndpoint { this.storeService = storeService; } - @PutMapping("/execute") + @PutMapping @Transactional @PreAuthorize("hasRole('ROLE_RESEARCHER')") @ApiOperation(value = "executes a query and save the results") @ApiResponses(value = { @ApiResponse(code = 200, message = "Executed the query, Saved it and return the results"), + @ApiResponse(code = 400, message = "The payload is malformed."), @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."),}) public ResponseEntity<QueryResultDto> execute(@NotNull @PathVariable("id") Long id, @NotNull @PathVariable("databaseId") Long databaseId, - @NotNull @RequestBody @Valid ExecuteStatementDto data) + @Valid @RequestBody ExecuteStatementDto data) throws DatabaseNotFoundException, ImageNotSupportedException, QueryStoreException, QueryMalformedException, TableNotFoundException, ContainerNotFoundException { /* validation */ @@ -60,13 +62,14 @@ public class QueryEndpoint { throw new QueryMalformedException("Invalid table"); } final QueryResultDto result = queryService.execute(id, databaseId, data); - final QueryDto query = queryMapper.queryToQueryDto(storeService.insert(id, databaseId, result, data)); + final QueryDto query = queryMapper.queryToQueryDto(storeService.insert(id, databaseId, result, data, + Instant.now())); result.setId(query.getId()); return ResponseEntity.status(HttpStatus.ACCEPTED) .body(result); } - @PostMapping("/save") + @PostMapping @Transactional @PreAuthorize("hasRole('ROLE_RESEARCHER')") @ApiOperation(value = "saves a query without execution") @@ -77,7 +80,7 @@ public class QueryEndpoint { @ApiResponse(code = 409, message = "The container image is not supported."),}) public ResponseEntity<QueryDto> save(@NotNull @PathVariable("id") Long id, @NotNull @PathVariable("databaseId") Long databaseId, - @NotNull @RequestBody SaveStatementDto data) + @Valid @RequestBody SaveStatementDto data) throws DatabaseNotFoundException, ImageNotSupportedException, QueryStoreException, ContainerNotFoundException { final Query query = storeService.insert(id, databaseId, null, data); @@ -86,7 +89,7 @@ public class QueryEndpoint { .body(queryDto); } - @PutMapping("/execute/{queryId}") + @PutMapping("/{queryId}") @Transactional @PreAuthorize("hasRole('ROLE_RESEARCHER')") @ApiOperation(value = "re-executes a query by given id") diff --git a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/TableDataEndpoint.java b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/TableDataEndpoint.java index d322f13acd3841168f54cd2c82ad60aa9b12fc80..7ffda30d7f2e4d0b589e1d59914a5e9fed2be736 100644 --- a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/TableDataEndpoint.java +++ b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/TableDataEndpoint.java @@ -5,6 +5,7 @@ import at.tuwien.api.database.query.QueryResultDto; import at.tuwien.api.database.table.TableCsvDto; import at.tuwien.exception.*; import at.tuwien.service.QueryService; +import at.tuwien.service.StoreService; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; @@ -28,10 +29,12 @@ import java.time.Instant; public class TableDataEndpoint { private final QueryService queryService; + private final StoreService storeService; @Autowired - public TableDataEndpoint(QueryService queryService) { + public TableDataEndpoint(QueryService queryService, StoreService storeService) { this.queryService = queryService; + this.storeService = storeService; } @PostMapping @@ -95,7 +98,8 @@ public class TableDataEndpoint { @RequestParam(required = false) Long page, @RequestParam(required = false) Long size) throws TableNotFoundException, DatabaseNotFoundException, DatabaseConnectionException, - ImageNotSupportedException, TableMalformedException, PaginationException, ContainerNotFoundException { + ImageNotSupportedException, TableMalformedException, PaginationException, ContainerNotFoundException, + QueryStoreException { if ((page == null && size != null) || (page != null && size == null)) { log.error("Cannot perform pagination with only one of page/size set."); log.debug("invalid pagination specification, one of page/size is null, either both should be null or none."); @@ -107,6 +111,8 @@ public class TableDataEndpoint { if (size != null && size <= 0) { throw new PaginationException("Page number cannot be lower or equal to 0"); } + /* fixme query store maybe not created, create it through running findAll() */ + storeService.findAll(id, databaseId); final BigInteger count = queryService.count(id, databaseId, tableId, timestamp); final HttpHeaders headers = new HttpHeaders(); headers.set("FDA-COUNT", count.toString()); diff --git a/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointIntegrationTest.java b/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointIntegrationTest.java index 93bb02dd2c6bcdedbe83d1fc20ca01493dcce74e..7313d83ca58b496e15709800fd7fc7d7478ef0a8 100644 --- a/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointIntegrationTest.java +++ b/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointIntegrationTest.java @@ -34,6 +34,7 @@ import org.springframework.transaction.annotation.Transactional; import java.io.File; import java.sql.SQLException; +import java.time.Instant; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -142,11 +143,12 @@ public class QueryEndpointIntegrationTest extends BaseUnitTest { final ExecuteStatementDto statement = ExecuteStatementDto.builder() .statement(QUERY_1_STATEMENT) .build(); + final Instant execution = Instant.now(); /* mock */ DockerConfig.startContainer(CONTAINER_1); MariaDbConfig.clearQueryStore(TABLE_1); - storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement); + storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement, execution); /* test */ final ResponseEntity<QueryResultDto> response = queryEndpoint.reExecute(CONTAINER_1_ID, DATABASE_1_ID, diff --git a/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointUnitTest.java b/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointUnitTest.java index 061853cd7732d64a04e97f05ddad03da4d6fbc44..08387c806078b65e39903b02a67d06055cd8a8cc 100644 --- a/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointUnitTest.java +++ b/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/QueryEndpointUnitTest.java @@ -20,6 +20,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit.jupiter.SpringExtension; +import java.time.Instant; import java.util.List; import java.util.Map; @@ -56,11 +57,12 @@ public class QueryEndpointUnitTest extends BaseUnitTest { .id(QUERY_1_ID) .result(List.of(Map.of("key", "value"))) .build(); + final Instant execution = Instant.now(); /* mock */ when(queryService.execute(CONTAINER_1_ID, DATABASE_1_ID, request)) .thenReturn(result); - when(storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, request)) + when(storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, request, execution)) .thenReturn(QUERY_1); /* test */ @@ -79,11 +81,12 @@ public class QueryEndpointUnitTest extends BaseUnitTest { .id(QUERY_1_ID) .result(List.of()) .build(); + final Instant execution = Instant.now(); /* mock */ when(queryService.execute(CONTAINER_1_ID, DATABASE_1_ID, request)) .thenReturn(result); - when(storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, request)) + when(storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, request, execution)) .thenReturn(QUERY_1); /* test */ diff --git a/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/TableDataEndpointUnitTest.java b/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/TableDataEndpointUnitTest.java index 753feb331e4b2ae41f790efacde939979471d2a3..5ff9a82cec2c1c012b4dbbbacb57bd1105b1b20f 100644 --- a/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/TableDataEndpointUnitTest.java +++ b/fda-query-service/rest-service/src/test/java/at/tuwien/endpoint/TableDataEndpointUnitTest.java @@ -82,7 +82,7 @@ public class TableDataEndpointUnitTest extends BaseUnitTest { @Test public void getAll_succeeds() throws TableNotFoundException, DatabaseConnectionException, TableMalformedException, - DatabaseNotFoundException, ImageNotSupportedException, PaginationException, ContainerNotFoundException { + DatabaseNotFoundException, ImageNotSupportedException, PaginationException, ContainerNotFoundException, QueryStoreException { /* test */ dataEndpoint.getAll(CONTAINER_1_ID, DATABASE_1_ID, TABLE_1_ID, null, null, null); @@ -91,7 +91,7 @@ public class TableDataEndpointUnitTest extends BaseUnitTest { @Test public void findAll_noPagination_succeeds() throws TableNotFoundException, DatabaseConnectionException, TableMalformedException, DatabaseNotFoundException, ImageNotSupportedException, PaginationException, - ContainerNotFoundException { + ContainerNotFoundException, QueryStoreException { final Long page = null; final Long size = null; @@ -179,7 +179,7 @@ public class TableDataEndpointUnitTest extends BaseUnitTest { @Test public void getAllTotal_succeeds() throws TableNotFoundException, DatabaseConnectionException, TableMalformedException, DatabaseNotFoundException, ImageNotSupportedException, - PaginationException, ContainerNotFoundException { + PaginationException, ContainerNotFoundException, QueryStoreException { final Instant timestamp = Instant.now(); /* test */ @@ -192,7 +192,7 @@ public class TableDataEndpointUnitTest extends BaseUnitTest { @Test public void getAllCount_succeeds() throws TableNotFoundException, DatabaseConnectionException, TableMalformedException, DatabaseNotFoundException, ImageNotSupportedException, - PaginationException, ContainerNotFoundException { + PaginationException, ContainerNotFoundException, QueryStoreException { final Instant timestamp = Instant.now(); /* test */ diff --git a/fda-query-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationTest.java b/fda-query-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationTest.java index a17d0e75b9c8e414b7c080d7591a5a4a3c8dac52..00f1fa2dfd41d15833737b1a1a91b971eacd1f0a 100644 --- a/fda-query-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationTest.java +++ b/fda-query-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationTest.java @@ -26,6 +26,7 @@ import org.springframework.transaction.annotation.Transactional; import java.io.File; import java.sql.SQLException; +import java.time.Instant; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -125,12 +126,13 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { final ExecuteStatementDto statement2 = ExecuteStatementDto.builder() .statement(QUERY_2_STATEMENT) .build(); + final Instant execution = Instant.now(); /* mock */ DockerConfig.startContainer(CONTAINER_1); MariaDbConfig.clearQueryStore(TABLE_1); - storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement1); - storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement2); + storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement1, execution); + storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement2, execution); /* test */ final List<Query> response = storeService.findAll(CONTAINER_1_ID, DATABASE_1_ID); @@ -146,11 +148,12 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { final ExecuteStatementDto statement = ExecuteStatementDto.builder() .statement(QUERY_1_STATEMENT) .build(); + final Instant execution = Instant.now(); /* mock */ DockerConfig.startContainer(CONTAINER_1); MariaDbConfig.clearQueryStore(TABLE_1); - storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement); + storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement, execution); /* test */ final Query response = storeService.findOne(CONTAINER_1_ID, DATABASE_1_ID, QUERY_1_ID); @@ -187,13 +190,14 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { final ExecuteStatementDto statement = ExecuteStatementDto.builder() .statement(QUERY_1_STATEMENT) .build(); + final Instant execution = Instant.now(); /* mock */ DockerConfig.startContainer(CONTAINER_1); MariaDbConfig.clearQueryStore(TABLE_1); /* test */ - final Query response = storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement); + final Query response = storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement, execution); assertEquals(QUERY_1_ID, response.getId()); assertEquals(QUERY_1_STATEMENT, response.getQuery()); } @@ -206,13 +210,14 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { final ExecuteStatementDto statement = ExecuteStatementDto.builder() .statement(QUERY_1_STATEMENT) .build(); + final Instant execution = Instant.now(); /* mock */ DockerConfig.stopContainer(CONTAINER_1); /* test */ assertThrows(QueryStoreException.class, () -> { - storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement); + storeService.insert(CONTAINER_1_ID, DATABASE_1_ID, result, statement, execution); }); } @@ -224,6 +229,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { final ExecuteStatementDto statement = ExecuteStatementDto.builder() .statement(QUERY_1_STATEMENT) .build(); + final Instant execution = Instant.now(); /* mock */ DockerConfig.startContainer(CONTAINER_1); @@ -231,7 +237,7 @@ public class StoreServiceIntegrationTest extends BaseUnitTest { /* test */ assertThrows(DatabaseNotFoundException.class, () -> { - storeService.insert(CONTAINER_1_ID, 9999L, result, statement); + storeService.insert(CONTAINER_1_ID, 9999L, result, statement, execution); }); } diff --git a/fda-query-service/services/src/main/java/at/tuwien/querystore/Column.java b/fda-query-service/services/src/main/java/at/tuwien/querystore/Column.java new file mode 100644 index 0000000000000000000000000000000000000000..8075f71848c3a70a6253e4c6d0f3d2bbc3f66548 --- /dev/null +++ b/fda-query-service/services/src/main/java/at/tuwien/querystore/Column.java @@ -0,0 +1,50 @@ +package at.tuwien.querystore; + +import lombok.*; +import org.hibernate.annotations.GenericGenerator; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import java.io.Serializable; +import java.time.Instant; + +@Data +@Entity +@javax.persistence.Table(name = "qs_column") +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ToString +@EntityListeners(AuditingEntityListener.class) +public class Column implements Serializable { + + @Id + @EqualsAndHashCode.Include + @GeneratedValue(generator = "column-sequence") + @GenericGenerator( + name = "column-sequence", + strategy = "enhanced-sequence", + parameters = @org.hibernate.annotations.Parameter(name = "sequence_name", value = "qs_column_seq") + ) + private Long id; + + @javax.persistence.Column(nullable = false) + private Long tid; + + @javax.persistence.Column(nullable = false) + private Long dbid; + + @javax.persistence.Column(nullable = false, updatable = false) + @CreatedDate + private Instant created; + + @javax.persistence.Column(name = "last_modified") + @LastModifiedDate + private Instant lastModified; + +} diff --git a/fda-query-service/services/src/main/java/at/tuwien/querystore/Query.java b/fda-query-service/services/src/main/java/at/tuwien/querystore/Query.java index 5b221f2652346496a6a7da287d76e29c92481431..bbdeb2b78386e69b0b94e3d29d056f4f915220b3 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/querystore/Query.java +++ b/fda-query-service/services/src/main/java/at/tuwien/querystore/Query.java @@ -9,10 +9,11 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; import javax.persistence.*; import java.io.Serializable; import java.time.Instant; +import java.util.List; @Data @Entity -@Table(name = "qs_queries") +@javax.persistence.Table(name = "qs_queries") @Builder @AllArgsConstructor @NoArgsConstructor @@ -30,35 +31,38 @@ public class Query implements Serializable { ) private Long id; - @Column(nullable = false) + @javax.persistence.Column(nullable = false) private Long cid; - @Column(nullable = false) + @javax.persistence.Column(nullable = false) private Long dbid; - @Column + @javax.persistence.Column private Instant execution; - @Column(nullable = false) + @javax.persistence.Column(nullable = false) private String query; - @Column(name = "query_normalized") + @javax.persistence.Column(name = "query_normalized") private String queryNormalized; - @Column(name = "query_hash", nullable = false) + @javax.persistence.Column(name = "query_hash", nullable = false) private String queryHash; - @Column(name = "result_hash") + @javax.persistence.Column(name = "result_hash") private String resultHash; - @Column(name = "result_number") + @javax.persistence.Column(name = "result_number") private Long resultNumber; - @Column(nullable = false, updatable = false) + @javax.persistence.Column(nullable = false, updatable = false) @CreatedDate private Instant created; - @Column(name = "last_modified") + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE) + private List<Table> tables; + + @javax.persistence.Column(name = "last_modified") @LastModifiedDate private Instant lastModified; diff --git a/fda-query-service/services/src/main/java/at/tuwien/querystore/Table.java b/fda-query-service/services/src/main/java/at/tuwien/querystore/Table.java new file mode 100644 index 0000000000000000000000000000000000000000..ee707cc8c115d087ad7f4914072640d8b28fa0b1 --- /dev/null +++ b/fda-query-service/services/src/main/java/at/tuwien/querystore/Table.java @@ -0,0 +1,48 @@ +package at.tuwien.querystore; + +import lombok.*; +import org.hibernate.annotations.GenericGenerator; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.*; +import java.io.Serializable; +import java.time.Instant; +import java.util.List; + +@Data +@Entity +@javax.persistence.Table(name = "qs_tables") +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ToString +@EntityListeners(AuditingEntityListener.class) +public class Table implements Serializable { + + @Id + @EqualsAndHashCode.Include + @GeneratedValue(generator = "table-sequence") + @GenericGenerator( + name = "table-sequence", + strategy = "enhanced-sequence", + parameters = @org.hibernate.annotations.Parameter(name = "sequence_name", value = "qs_tables_seq") + ) + private Long id; + + @javax.persistence.Column(nullable = false) + private Long dbid; + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE) + private List<Column> columns; + + @javax.persistence.Column(nullable = false, updatable = false) + @CreatedDate + private Instant created; + + @javax.persistence.Column(name = "last_modified") + @LastModifiedDate + private Instant lastModified; + +} diff --git a/fda-query-service/services/src/main/java/at/tuwien/repository/jpa/TableColumnRepository.java b/fda-query-service/services/src/main/java/at/tuwien/repository/jpa/TableColumnRepository.java index 9441d45125e3f54d6545bbcb3e4b4e99a05d1bbf..2d3a818d871ada46608d5b30b4603379d68e6161 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/repository/jpa/TableColumnRepository.java +++ b/fda-query-service/services/src/main/java/at/tuwien/repository/jpa/TableColumnRepository.java @@ -4,7 +4,11 @@ import at.tuwien.entities.database.table.columns.TableColumn; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.Optional; + @Repository public interface TableColumnRepository extends JpaRepository<TableColumn, Long> { + Optional<TableColumn> findByIdAndTidAndCdbid(Long id, Long tid, Long cdbid); + } diff --git a/fda-query-service/services/src/main/java/at/tuwien/seeder/Seeder.java b/fda-query-service/services/src/main/java/at/tuwien/seeder/Seeder.java index 241057caf951d628e2f8935bd4badb27a6a36182..544ccc3054cfa9b48228c2cae37470c4e74f2084 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/seeder/Seeder.java +++ b/fda-query-service/services/src/main/java/at/tuwien/seeder/Seeder.java @@ -1,10 +1,6 @@ package at.tuwien.seeder; -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.context.event.EventListener; - public interface Seeder { - @EventListener(ApplicationReadyEvent.class) void seed(); } diff --git a/fda-query-service/services/src/main/java/at/tuwien/service/StoreService.java b/fda-query-service/services/src/main/java/at/tuwien/service/StoreService.java index f22a56be03b80eb41a06e7e323a6ce46e9c416d4..ed49db862f2cb9469737dbe9477798dbc84535e5 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/service/StoreService.java +++ b/fda-query-service/services/src/main/java/at/tuwien/service/StoreService.java @@ -7,6 +7,7 @@ import at.tuwien.exception.*; import at.tuwien.querystore.Query; import org.springframework.stereotype.Service; +import java.time.Instant; import java.util.List; @Service @@ -58,12 +59,14 @@ public interface StoreService { * @param databaseId The database id. * @param result The query. * @param metadata The metadata. + * @param execution The execution time. * @return The stored query on success * @throws QueryStoreException The query store raised some error * @throws DatabaseNotFoundException The database id was not found in the metadata database * @throws ImageNotSupportedException The image is not supported */ - Query insert(Long containerId, Long databaseId, QueryResultDto result, ExecuteStatementDto metadata) throws QueryStoreException, - DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException; + Query insert(Long containerId, Long databaseId, QueryResultDto result, ExecuteStatementDto metadata, + Instant execution) throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException, + ContainerNotFoundException; } diff --git a/fda-query-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java b/fda-query-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java index 84c252991a43514719c2b2fbc697c5796ccf4982..020f64168ab252c5fb807efb4568de0a9c61108a 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java +++ b/fda-query-service/services/src/main/java/at/tuwien/service/impl/HibernateConnector.java @@ -3,7 +3,9 @@ package at.tuwien.service.impl; import at.tuwien.entities.container.image.ContainerImageEnvironmentItem; import at.tuwien.entities.container.image.ContainerImageEnvironmentItemType; import at.tuwien.entities.database.Database; +import at.tuwien.querystore.Column; import at.tuwien.querystore.Query; +import at.tuwien.querystore.Table; import lombok.extern.log4j.Log4j2; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; @@ -58,7 +60,9 @@ public abstract class HibernateConnector { .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) + .addAnnotatedClass(Table.class) + .addAnnotatedClass(Column.class); return configuration.buildSessionFactory(); } diff --git a/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java b/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java index 7f5636390176128a75fde4dbd078b1c7866ebc1e..f1dbcdaef74b21304531ad09ed226b7edf799e1a 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java +++ b/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java @@ -25,6 +25,7 @@ import javax.persistence.PersistenceException; import java.math.BigInteger; import java.time.DateTimeException; import java.time.Instant; +import java.util.LinkedList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -77,7 +78,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService throw new QueryMalformedException("Query not valid for this database", e); } /* map the result to the tables (with respective columns) from the statement metadata */ - final List<TableColumn> columns = parseColumns(statement); + final List<TableColumn> columns = parseColumns(databaseId, statement); final QueryResultDto result = queryMapper.resultListToQueryResultDto(columns, query.getResultList()); session.close(); factory.close(); @@ -234,13 +235,21 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService * @param statement The list of tables (ids) and referenced column ids. * @return The list of columns if successful */ - private List<TableColumn> parseColumns(ExecuteStatementDto statement) { - return statement.getColumns() - .stream() - .map(c -> tableColumnRepository.findById(c.getId())) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(Collectors.toList()); + private List<TableColumn> parseColumns(Long databaseId, ExecuteStatementDto statement) { + final List<TableColumn> columns = new LinkedList<>(); + final int[] idx = new int[]{0}; + statement.getTables() + .forEach(table -> { + columns.addAll(statement.getColumns() + .get(idx[0]++) + .stream() + .map(column -> tableColumnRepository + .findByIdAndTidAndCdbid(column.getId(), table.getId(), databaseId)) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList())); + }); + return columns; } } diff --git a/fda-query-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java b/fda-query-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java index 0d066d93132c2c262f1c1f0b6ae8957e30c0cd12..7fbda87023bc08a3391360c1f49c91d7bc973c87 100644 --- a/fda-query-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java +++ b/fda-query-service/services/src/main/java/at/tuwien/service/impl/StoreServiceImpl.java @@ -107,12 +107,12 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService public Query insert(Long containerId, Long databaseId, QueryResultDto result, SaveStatementDto metadata) throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException { - return insert(containerId, databaseId, result, queryMapper.saveStatementDtoToExecuteStatementDto(metadata)); + return insert(containerId, databaseId, result, queryMapper.saveStatementDtoToExecuteStatementDto(metadata), null); } @Override @Transactional(readOnly = true) - public Query insert(Long containerId, Long databaseId, QueryResultDto result, ExecuteStatementDto metadata) + public Query insert(Long containerId, Long databaseId, QueryResultDto result, ExecuteStatementDto metadata, Instant execution) throws QueryStoreException, DatabaseNotFoundException, ImageNotSupportedException, ContainerNotFoundException { /* find */ @@ -121,7 +121,7 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService if (!database.getContainer().getImage().getRepository().equals("mariadb")) { throw new ImageNotSupportedException("Currently only MariaDB is supported"); } - log.debug("Insert into database id {}, record {}, metadata {}", databaseId, result, metadata); + log.debug("Insert into database id {}, metadata {}", databaseId, metadata); /* save */ final SessionFactory factory = getSessionFactory(database, true); final Session session = factory.openSession(); @@ -134,7 +134,7 @@ public class StoreServiceImpl extends HibernateConnector implements StoreService .queryHash(DigestUtils.sha256Hex(metadata.getStatement())) .resultNumber(storeMapper.queryResultDtoToLong(result)) .resultHash(storeMapper.queryResultDtoToString(result)) - .execution(Instant.now()) + .execution(execution) .build(); session.save(query); transaction.commit(); diff --git a/fda-sensor-computer/main.py b/fda-sensor-computer/main.py index c54db1eba5332374e03105acc060e4b325c5c397..c0fcd5acc4fcd920a915dde91b3c87fa18f3186c 100644 --- a/fda-sensor-computer/main.py +++ b/fda-sensor-computer/main.py @@ -15,7 +15,7 @@ def send(temp): channel = connection.channel() ex = argv[1] key = argv[2] - channel.basic_publish(exchange=ex, routing_key=key, body=bytes('{"wifi":' + str(temp) + '}', encoding='utf8')) + channel.basic_publish(exchange=ex, routing_key=key, body=bytes('{"temp":' + str(temp) + '}', encoding='utf8')) connection.close() diff --git a/fda-table-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java b/fda-table-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java index a296d214fdb651e41c62c06a6a74d0bedd8406db..82b36fff670345c692f8ba58188a510de826a542 100644 --- a/fda-table-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java +++ b/fda-table-service/services/src/main/java/at/tuwien/seeder/impl/AbstractSeeder.java @@ -9,12 +9,20 @@ public abstract class AbstractSeeder { public final static Long CONTAINER_1_ID = 1L; + public final static Long CONTAINER_2_ID = 2L; + public final static Long DATABASE_1_ID = 1L; + public final static Long DATABASE_2_ID = 2L; + public final static Database DATABASE_1 = Database.builder() .id(DATABASE_1_ID) .build(); + public final static Database DATABASE_2 = Database.builder() + .id(DATABASE_2_ID) + .build(); + public final static Long TABLE_1_ID = 1L; public final static String TABLE_1_NAME = "Fahrzeiten Soll-Ist 2017"; public final static String TABLE_1_FALSE_ELEMENT = null; @@ -24,6 +32,15 @@ public abstract class AbstractSeeder { public final static String TABLE_1_SKIP_LINES = "1"; public final static String TABLE_1_DESCRIPTION = "The data table is a variance analysis of the times certain trams and busses should have departed and when they actually departed."; + public final static Long TABLE_2_ID = 2L; + public final static String TABLE_2_NAME = "Ethernet Temperature"; + public final static String TABLE_2_FALSE_ELEMENT = null; + public final static String TABLE_2_TRUE_ELEMENT = null; + public final static String TABLE_2_NULL_ELEMENT = null; + public final static Character TABLE_2_SEPERATOR = ','; + public final static String TABLE_2_SKIP_LINES = "1"; + public final static String TABLE_2_DESCRIPTION = "Temperature of the server's Ethernet module in degree Celsius"; + public final static Long IMAGE_DATE_3_ID = 3L; public final static TableCreateDto TABLE_1_CREATE_DTO = TableCreateDto.builder() @@ -367,4 +384,25 @@ public abstract class AbstractSeeder { .build()}) .build(); + public final static TableCreateDto TABLE_2_CREATE_DTO = TableCreateDto.builder() + .name(TABLE_2_NAME) + .description(TABLE_2_DESCRIPTION) + .falseElement(TABLE_2_FALSE_ELEMENT) + .trueElement(TABLE_2_TRUE_ELEMENT) + .nullElement(TABLE_2_NULL_ELEMENT) + .separator(TABLE_2_SEPERATOR) + .skipLines(TABLE_2_SKIP_LINES) + .columns(new ColumnCreateDto[]{ + ColumnCreateDto.builder() + .type(ColumnTypeDto.NUMBER) + .name("temp") + .nullAllowed(true) + .primaryKey(false) + .unique(false) + .dfid(null) + .checkExpression(null) + .enumValues(null) + .build()}) + .build(); + } diff --git a/fda-table-service/services/src/main/java/at/tuwien/seeder/impl/TableSeederImpl.java b/fda-table-service/services/src/main/java/at/tuwien/seeder/impl/TableSeederImpl.java index cdaadbed91bb6aa62efd2056e52939ac780a3634..f6dd4c8b76fab97185ea403eee1debbeb9dcd352 100644 --- a/fda-table-service/services/src/main/java/at/tuwien/seeder/impl/TableSeederImpl.java +++ b/fda-table-service/services/src/main/java/at/tuwien/seeder/impl/TableSeederImpl.java @@ -31,6 +31,8 @@ public class TableSeederImpl extends AbstractSeeder implements Seeder { } final Table table1 = tableService.createTable(CONTAINER_1_ID, DATABASE_1_ID, TABLE_1_CREATE_DTO); log.info("Seeded table id {}", table1.getId()); + final Table table2 = tableService.createTable(CONTAINER_2_ID, DATABASE_2_ID, TABLE_2_CREATE_DTO); + log.info("Seeded table id {}", table2.getId()); } } diff --git a/fda-ui/components/query/Builder.vue b/fda-ui/components/query/Builder.vue index 2577ed99793fdd7e3ab473cafb7de048ea02959c..2574d77c569f2c85d616676a8292c1f718474bb1 100644 --- a/fda-ui/components/query/Builder.vue +++ b/fda-ui/components/query/Builder.vue @@ -161,7 +161,7 @@ export default { })] } console.debug('send data', data) - const res = await this.$axios.put(`/api/container/${this.$route.params.container_id}/database/${this.databaseId}/query/execute`, data, { + const res = await this.$axios.put(`/api/container/${this.$route.params.container_id}/database/${this.databaseId}/query`, data, { headers: this.headers }) console.debug('query result', res) @@ -183,7 +183,7 @@ export default { const query = this.query.sql.replaceAll('`', '') this.loading = true try { - const res = await this.$axios.post(`/api/container/${this.$route.params.container_id}/database/${this.databaseId}/query/save`, { statement: query }, { + const res = await this.$axios.post(`/api/container/${this.$route.params.container_id}/database/${this.databaseId}/query`, { statement: query }, { headers: this.headers }) console.debug('query result', res) diff --git a/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue b/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue index d99119cc37ad0092e1271641cb58393c0947ed08..2cc72b4c278401a7cdb3ac277365a5ee033c3bc1 100644 --- a/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue +++ b/fda-ui/pages/container/_container_id/database/_database_id/query/_query_id/index.vue @@ -7,7 +7,7 @@ <v-btn color="blue-grey white--text" class="mr-2" :disabled="!query.execution || identifier.id || !token" @click.stop="persistQueryDialog = true"> <v-icon left>mdi-fingerprint</v-icon> Persist </v-btn> - <v-btn color="primary" :disabled="!token"> + <v-btn color="primary" :disabled="!token" @click.stop="reExecute"> <v-icon left>mdi-run</v-icon> Re-Execute </v-btn> </v-toolbar-title> @@ -164,6 +164,19 @@ export default { this.loading = false } this.loading = false + }, + async reExecute () { + try { + this.loading = true + const res = await this.$axios.put(`/api/container/${this.$route.params.container_id}/database/${this.$route.params.database_id}/query/${this.$route.params.query_id}`, {}, { + headers: this.headers + }) + console.debug('re-execute query', res.data) + } catch (err) { + console.error('Could not re-execute query', err) + this.$toast.error('Could not re-execute query') + } + this.loading = false } } } diff --git a/fda-ui/pages/container/index.vue b/fda-ui/pages/container/index.vue index ef77bd366441fb983e171e147a6eda8aa09ba0da..39aa3876e4bc5368af5e710a5bee39ddbac002cb 100644 --- a/fda-ui/pages/container/index.vue +++ b/fda-ui/pages/container/index.vue @@ -49,6 +49,7 @@ <CreateDB @close="createDbDialog = false" /> </v-dialog> </v-card> + <v-breadcrumbs :items="items" class="pa-0 mt-2" /> </div> </template> <script> @@ -65,6 +66,9 @@ export default { return { createDbDialog: false, databases: [], + items: [ + { text: 'Databases', href: '/container' } + ], loading: true, error: false, iconSelect: mdiDatabaseArrowRightOutline