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

Reverted more changes

parent b136cb26
Branches
Tags
2 merge requests!81New stable release,!47Resolve "Show error messages from response"
Showing
with 116 additions and 208 deletions
......@@ -132,6 +132,7 @@ public abstract class BaseUnitTest {
.id(DATABASE_1_ID)
.name(DATABASE_1_NAME)
.internalName(DATABASE_1_INTERNALNAME)
.isPublic(DATABASE_1_PUBLIC)
.container(CONTAINER_1)
.created(DATABASE_1_CREATED)
.tables(List.of())
......@@ -158,6 +159,7 @@ public abstract class BaseUnitTest {
.id(DATABASE_2_ID)
.name(DATABASE_2_NAME)
.internalName(DATABASE_2_INTERNALNAME)
.isPublic(DATABASE_2_PUBLIC)
.container(CONTAINER_2)
.created(DATABASE_2_CREATED)
.tables(List.of())
......
......@@ -45,7 +45,7 @@ public interface DatabaseMapper {
DatabaseDto databaseToDatabaseDto(Database data);
default String databaseToRawCreateDatabaseQuery(Database database) {
return "CREATE DATABASE `" + database.getInternalName() + "`;";
return "CREATE DATABASE " + database.getInternalName() + ";";
}
default String imageToRawGrantReadonlyAccessQuery() {
......@@ -53,7 +53,7 @@ public interface DatabaseMapper {
}
default String databaseToRawDeleteDatabaseQuery(Database database) {
return "DROP DATABASE `" + database.getInternalName() + "`;";
return "DROP DATABASE " + database.getInternalName() + ";";
}
}
......@@ -7,6 +7,4 @@ import org.springframework.stereotype.Repository;
@Repository
public interface ContainerRepository extends JpaRepository<Container, Long> {
/* keep */
}
......@@ -14,7 +14,4 @@ public interface DatabaseRepository extends JpaRepository<Database, Long> {
@Query("select d from Database d where d.container.id = :containerId")
List<Database> findAllByContainerId(@Param("containerId") Long containerId);
@Query("select d from Database d where d.container.id = :containerId and d.creator.username = :username")
List<Database> findAllMine(@Param("containerId") Long containerId, @Param("username") String username);
}
package at.tuwien.repository.jpa;
import at.tuwien.entities.user.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
}
......@@ -32,10 +32,6 @@ public class ContainerDto {
@Parameter(name = "container name", example = "Weather World")
private String name;
@NotNull
@Parameter(name = "user")
private UserDto creator;
@NotBlank
@JsonProperty("internal_name")
@Parameter(name = "container internal name", example = "weather-world")
......
......@@ -35,10 +35,6 @@ public class DatabaseDto {
@Parameter(name = "database internal name", example = "weather_australia")
private String internalName;
@NotNull
@Parameter(name = "user")
private UserDto creator;
@NotBlank
@Parameter(name = "database description", example = "Weather Australia 2009-2021")
private String description;
......
......@@ -37,10 +37,6 @@ public class QueryDto {
@Parameter(name = "creator id", example = "1")
private Long createdBy;
@NotNull(message = "creator is required")
@Parameter(name = "creator")
private UserDto creator;
@Parameter(name = "execution time", example = "2022-01-01 08:00:00.000")
private Instant execution;
......
......@@ -31,10 +31,6 @@ public class TableDto {
@Parameter(name = "table internal name", example = "weather_australia")
private String internalName;
@NotNull
@Parameter(name = "user")
private UserDto creator;
@NotBlank
@Parameter(name = "topic name", example = "fda.c1.d1.t1")
private String topic;
......
......@@ -31,10 +31,6 @@ public class ColumnDto {
@Parameter(name = "internal name", example = "mdb_date", required = true)
private String internalName;
@NotNull
@Parameter(name = "user")
private UserDto creator;
@NotBlank
@JsonProperty("date_format")
@Parameter(name = "date format", example = "1")
......
......@@ -33,10 +33,6 @@ public class IdentifierDto {
@Parameter(name = "query id", example = "1")
private Long qid;
@NotNull
@Parameter(name = "user")
private UserDto creator;
@NotBlank
@Parameter(name = "query title", example = "Select all weather events for 2012")
private String title;
......
package at.tuwien.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
public class SortDataException extends Exception {
public SortDataException(String msg) {
super(msg);
}
public SortDataException(String msg, Throwable thr) {
super(msg, thr);
}
public SortDataException(Throwable thr) {
super(thr);
}
}
package at.tuwien.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "User not found")
public class UserNotFoundException extends Exception {
public UserNotFoundException(String message) {
super(message);
}
public UserNotFoundException(String message, Throwable thr) {
super(message, thr);
}
public UserNotFoundException(Throwable thr) {
super(thr);
}
}
......@@ -38,9 +38,6 @@ public class Query implements Serializable {
@javax.persistence.Column(nullable = false)
private Long dbid;
@javax.persistence.Column(nullable = false)
private Long createdBy;
@javax.persistence.Column
private Instant execution;
......@@ -63,6 +60,9 @@ public class Query implements Serializable {
@CreatedDate
private Instant created;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
private List<Table> tables;
@javax.persistence.Column(name = "last_modified")
@LastModifiedDate
private Instant lastModified;
......
package at.tuwien.repository.jpa;
import at.tuwien.entities.user.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
}
......@@ -193,18 +193,20 @@
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${springfox.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>2.4.21</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/application*.yml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
......
......@@ -7,10 +7,12 @@ import org.springframework.data.elasticsearch.repository.config.EnableElasticsea
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import springfox.documentation.oas.annotations.EnableOpenApi;
@SpringBootApplication
@EnableJpaAuditing
@EnableOpenApi
@EnableTransactionManagement
@EnableElasticsearchRepositories(basePackages = {"at.tuwien.repository.elastic"})
@EnableJpaRepositories(basePackages = {"at.tuwien.repository.jpa"})
......
package at.tuwien.config;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import java.util.Collections;
@Configuration
@EnableOpenApi
public class SwaggerConfig {
@Value("${app.version:unknown}")
private String version;
@Bean
public OpenAPI springShopOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("Database Repository Table Service API")
.contact(new Contact()
.name("Prof. Andreas Rauber")
.email("andreas.rauber@tuwien.ac.at"))
.description("Service that manages the tables")
.version(version)
.license(new License()
.name("Apache 2.0")
.url("https://www.apache.org/licenses/LICENSE-2.0")))
.externalDocs(new ExternalDocumentation()
.description("Wiki Documentation")
.url("https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/wikis"));
public Docket tableApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.paths(PathSelectors.ant("/api/**"))
.build();
}
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("table-service")
.pathsToMatch("/api/**")
.build();
private ApiInfo apiInfo() {
return new ApiInfo("FDA-Table-Service API",
"Service API for table service",
"1.0",
null,
new Contact("Ao.Univ.Prof. Andreas Rauber", "http://www.ifs.tuwien.ac.at/~andi/", "rauber@ifs.tuwien.ac.at"),
"API license",
null,
Collections.emptyList());
}
}
......@@ -6,8 +6,11 @@ import at.tuwien.exception.*;
import at.tuwien.mapper.TableMapper;
import at.tuwien.service.MessageQueueService;
import at.tuwien.service.TableService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import at.tuwien.service.impl.RabbitMqService;
import at.tuwien.service.impl.TableServiceImpl;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
......@@ -40,7 +43,11 @@ public class TableEndpoint {
@GetMapping
@Transactional(readOnly = true)
@Operation(summary = "List tables")
@ApiOperation(value = "List all tables", notes = "Lists the tables in the metadata database for this database.")
@ApiResponses({
@ApiResponse(code = 200, message = "All tables are listed."),
@ApiResponse(code = 401, message = "Not authorized to list all tables."),
})
public ResponseEntity<List<TableBriefDto>> findAll(@NotNull @PathVariable("id") Long id,
@NotNull @PathVariable("databaseId") Long databaseId)
throws DatabaseNotFoundException {
......@@ -53,13 +60,21 @@ public class TableEndpoint {
@PostMapping
@Transactional
@PreAuthorize("hasRole('ROLE_RESEARCHER')")
@Operation(summary = "Create table", security = @SecurityRequirement(name = "bearerAuth"))
@ApiOperation(value = "Create a table", notes = "Creates a new table for a database, requires a running container.")
@ApiResponses({
@ApiResponse(code = 201, message = "The table was created."),
@ApiResponse(code = 400, message = "The creation form contains invalid data."),
@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 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, TableNameExistsException,
ContainerNotFoundException, UserNotFoundException {
ContainerNotFoundException {
final Table table = tableService.createTable(id, databaseId, createDto);
amqpService.create(table);
return ResponseEntity.status(HttpStatus.CREATED)
......@@ -69,7 +84,12 @@ public class TableEndpoint {
@GetMapping("/{tableId}")
@Transactional(readOnly = true)
@Operation(summary = "Find some table")
@ApiOperation(value = "Get information about table", notes = "Lists the information of a table from the metadata database for this database.")
@ApiResponses({
@ApiResponse(code = 200, message = "All tables are listed."),
@ApiResponse(code = 401, message = "Not authorized to list all tables."),
@ApiResponse(code = 404, message = "Table not found in metadata database."),
})
public ResponseEntity<TableDto> findById(@NotNull @PathVariable("id") Long id,
@NotNull @PathVariable("databaseId") Long databaseId,
@NotNull @PathVariable("tableId") Long tableId)
......@@ -80,18 +100,29 @@ public class TableEndpoint {
@PutMapping("/{tableId}")
@Transactional
@PreAuthorize("hasRole('ROLE_RESEARCHER')")
@Operation(summary = "Update some table", security = @SecurityRequirement(name = "bearerAuth"))
@ApiOperation(value = "Update a table", notes = "Update a table in the database.")
@ApiResponses({
@ApiResponse(code = 200, message = "Updated the table."),
@ApiResponse(code = 400, message = "The update form contains invalid data."),
@ApiResponse(code = 401, message = "Not authorized to update tables."),
@ApiResponse(code = 404, message = "The table is not found in database."),
})
public ResponseEntity<TableBriefDto> update(@NotNull @PathVariable("id") Long id,
@NotNull @PathVariable("databaseId") Long databaseId,
@NotNull @PathVariable("tableId") Long tableId) {
// TODO
return ResponseEntity.unprocessableEntity().body(new TableBriefDto());
}
@DeleteMapping("/{tableId}")
@Transactional
@PreAuthorize("hasRole('ROLE_DEVELOPER') or hasRole('ROLE_DATA_STEWARD')")
@Operation(summary = "Delete some table", security = @SecurityRequirement(name = "bearerAuth"))
@ApiOperation(value = "Delete a table", notes = "Delete a table in the database.")
@ApiResponses({
@ApiResponse(code = 200, message = "Deleted the table."),
@ApiResponse(code = 401, message = "Not authorized to delete tables."),
@ApiResponse(code = 404, message = "The table is not found in database."),
})
@ResponseStatus(HttpStatus.OK)
public void delete(@NotNull @PathVariable("id") Long id,
@NotNull @PathVariable("databaseId") Long databaseId,
......
......@@ -7,49 +7,34 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
@ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
@ExceptionHandler(AmqpException.class)
public ResponseEntity<ApiErrorDto> handle(AmqpException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.NOT_ACCEPTABLE)
.message(e.getLocalizedMessage())
.code("error.database.queue")
.build();
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(ArbitraryPrimaryKeysException.class)
public ResponseEntity<ApiErrorDto> handle(ArbitraryPrimaryKeysException e, WebRequest request) {
@ExceptionHandler({AmqpException.class})
public ResponseEntity<Object> handle(AmqpException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.BAD_REQUEST)
.message(e.getLocalizedMessage())
.code("error.database.primary")
.code("error.amqp.queue")
.build();
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(ContainerNotFoundException.class)
public ResponseEntity<ApiErrorDto> handle(ContainerNotFoundException e, WebRequest request) {
@ExceptionHandler({ArbitraryPrimaryKeysException.class})
public ResponseEntity<Object> handle(ArbitraryPrimaryKeysException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.NOT_FOUND)
.status(HttpStatus.BAD_REQUEST)
.message(e.getLocalizedMessage())
.code("error.database.container")
.code("error.keys.primary")
.build();
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler(DatabaseConnectionException.class)
public ResponseEntity<ApiErrorDto> handle(DatabaseConnectionException e, WebRequest request) {
@ExceptionHandler({DatabaseConnectionException.class})
public ResponseEntity<Object> handle(DatabaseConnectionException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.METHOD_NOT_ALLOWED)
.message(e.getLocalizedMessage())
......@@ -58,9 +43,8 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(DatabaseNotFoundException.class)
public ResponseEntity<ApiErrorDto> handle(DatabaseNotFoundException e, WebRequest request) {
@ExceptionHandler({DatabaseNotFoundException.class})
public ResponseEntity<Object> handle(DatabaseNotFoundException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.NOT_FOUND)
.message(e.getLocalizedMessage())
......@@ -69,9 +53,8 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(DataProcessingException.class)
public ResponseEntity<ApiErrorDto> handle(DataProcessingException e, WebRequest request) {
@ExceptionHandler({DataProcessingException.class})
public ResponseEntity<Object> handle(DataProcessingException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.BAD_REQUEST)
.message(e.getLocalizedMessage())
......@@ -80,9 +63,8 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(FileStorageException.class)
public ResponseEntity<ApiErrorDto> handle(FileStorageException e, WebRequest request) {
@ExceptionHandler({FileStorageException.class})
public ResponseEntity<Object> handle(FileStorageException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.BAD_REQUEST)
.message(e.getLocalizedMessage())
......@@ -91,9 +73,8 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ResponseStatus(HttpStatus.CONFLICT)
@ExceptionHandler(ImageNotSupportedException.class)
public ResponseEntity<ApiErrorDto> handle(ImageNotSupportedException e, WebRequest request) {
@ExceptionHandler({ImageNotSupportedException.class})
public ResponseEntity<Object> handle(ImageNotSupportedException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.CONFLICT)
.message(e.getLocalizedMessage())
......@@ -102,42 +83,38 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
@ExceptionHandler(PaginationException.class)
public ResponseEntity<ApiErrorDto> handle(PaginationException e, WebRequest request) {
@ExceptionHandler({PaginationException.class})
public ResponseEntity<Object> handle(PaginationException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.METHOD_NOT_ALLOWED)
.status(HttpStatus.CONFLICT)
.message(e.getLocalizedMessage())
.code("error.database.pagination")
.build();
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(TableMalformedException.class)
public ResponseEntity<ApiErrorDto> handle(TableMalformedException e, WebRequest request) {
@ExceptionHandler({TableNameExistsException.class})
public ResponseEntity<Object> handle(TableNameExistsException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.BAD_REQUEST)
.status(HttpStatus.CONFLICT)
.message(e.getLocalizedMessage())
.code("error.database.table")
.code("error.database.name")
.build();
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ResponseStatus(HttpStatus.CONFLICT)
@ExceptionHandler(TableNameExistsException.class)
public ResponseEntity<ApiErrorDto> handle(TableNameExistsException e, WebRequest request) {
@ExceptionHandler({TableMalformedException.class})
public ResponseEntity<Object> handle(TableMalformedException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.CONFLICT)
.status(HttpStatus.BAD_REQUEST)
.message(e.getLocalizedMessage())
.code("error.database.name")
.code("error.database.table")
.build();
return new ResponseEntity<>(response, new HttpHeaders(), response.getStatus());
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(TableNotFoundException.class)
public ResponseEntity<ApiErrorDto> handle(TableNotFoundException e, WebRequest request) {
@ExceptionHandler({TableNotFoundException.class})
public ResponseEntity<Object> handle(TableNotFoundException e, WebRequest request) {
final ApiErrorDto response = ApiErrorDto.builder()
.status(HttpStatus.NOT_FOUND)
.message(e.getLocalizedMessage())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment