From 7f166e6da2086e6a3aa39139750830e1f08af661 Mon Sep 17 00:00:00 2001 From: Martin Weise <martin.weise@tuwien.ac.at> Date: Tue, 16 Mar 2021 22:23:20 +0100 Subject: [PATCH] decorate the endpoint --- README.md | 8 +++- .../api/dto/container/ContainerDto.java | 17 ++++---- .../api/dto/container/ContainerStateDto.java | 8 ++++ .../container/DatabaseContainerBriefDto.java | 2 +- .../dto/container/DatabaseContainerDto.java | 12 +----- .../api/dto/container/IpAddressDto.java | 14 +++++++ .../DatabaseContainerCreateResponseDto.java | 14 ------- .../java/at/tuwien/config/SwaggerConfig.java | 3 +- .../DatabaseContainerController.java | 41 +++++++++++-------- .../mapper/DatabaseContainerMapper.java | 25 +++++------ .../at/tuwien/service/ContainerService.java | 3 +- 11 files changed, 74 insertions(+), 73 deletions(-) create mode 100644 fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/ContainerStateDto.java create mode 100644 fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/IpAddressDto.java delete mode 100644 fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/database/DatabaseContainerCreateResponseDto.java diff --git a/README.md b/README.md index d9d76944c4..caadd4a9c6 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,16 @@ Everything is handled by compose, just build it by running: docker-compose build ``` +## Develop + +The endpoints are documented with Swagger 2.1 and OpenAPI 3.0. The current specification for the front-end is obtainable programatically from [http://fda-container-managing-service/swagger-resources](http://localhost:9091/swagger-resources). + +For easy visualization use OpenAPI at [http://fda-container-managing-service/swagger-ui/](http://localhost:9091/swagger-ui/) + ## Deployment The pipeline is set-up to build and test all commits. A commit to dev or master branch triggers additional jobs. -### Development - A commit to `dev` triggers the following pipeline. It deploys the docker images to the docker registry hosted on the fda-runner server and deploys it also to a test server (fda-deployment) at TU Wien.  diff --git a/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/ContainerDto.java b/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/ContainerDto.java index 6e23c906f4..5d3bad43a9 100644 --- a/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/ContainerDto.java +++ b/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/ContainerDto.java @@ -3,20 +3,17 @@ package at.tuwien.api.dto.container; import lombok.Getter; import lombok.Setter; +import java.net.InetAddress; +import java.time.Instant; + @Getter @Setter -public class ContainerDto { - - private String containerId; - - private String created; - - private String containerName; +public class ContainerDto extends DatabaseContainerBriefDto { - private String databaseName; + private ContainerStateDto status; - private String status; + private IpAddressDto ipAddress; - private String ipAddress; + private Instant created; } diff --git a/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/ContainerStateDto.java b/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/ContainerStateDto.java new file mode 100644 index 0000000000..acd2aeab93 --- /dev/null +++ b/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/ContainerStateDto.java @@ -0,0 +1,8 @@ +package at.tuwien.api.dto.container; + +import lombok.Getter; + +@Getter +public enum ContainerStateDto { + CREATED, RESTARTING, RUNNING, PAUSED, EXITED, DEAD +} diff --git a/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/DatabaseContainerBriefDto.java b/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/DatabaseContainerBriefDto.java index e8afd33ce8..76f18c7c29 100644 --- a/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/DatabaseContainerBriefDto.java +++ b/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/DatabaseContainerBriefDto.java @@ -6,9 +6,9 @@ import lombok.Setter; @Getter @Setter -@Builder public class DatabaseContainerBriefDto { private String id; + private String containerName; } diff --git a/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/DatabaseContainerDto.java b/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/DatabaseContainerDto.java index 50461db0da..be67da83a8 100644 --- a/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/DatabaseContainerDto.java +++ b/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/DatabaseContainerDto.java @@ -5,18 +5,8 @@ import lombok.Setter; @Getter @Setter -public class DatabaseContainerDto { - - private String containerId; - - private String created; - - private String containerName; +public class DatabaseContainerDto extends ContainerDto { private String databaseName; - private String status; - - private String ipAddress; - } diff --git a/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/IpAddressDto.java b/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/IpAddressDto.java new file mode 100644 index 0000000000..e98b708ca0 --- /dev/null +++ b/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/container/IpAddressDto.java @@ -0,0 +1,14 @@ +package at.tuwien.api.dto.container; + +import lombok.Getter; +import lombok.Setter; + +import java.net.InetAddress; + +@Getter +@Setter +public class IpAddressDto { + + private String ipv4; + +} diff --git a/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/database/DatabaseContainerCreateResponseDto.java b/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/database/DatabaseContainerCreateResponseDto.java deleted file mode 100644 index b168e9cbdf..0000000000 --- a/fda-container-managing-service/api/src/main/java/at/tuwien/api/dto/database/DatabaseContainerCreateResponseDto.java +++ /dev/null @@ -1,14 +0,0 @@ -package at.tuwien.api.dto.database; - -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Builder -public class DatabaseContainerCreateResponseDto { - - private String containerId; - -} diff --git a/fda-container-managing-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java b/fda-container-managing-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java index 797c456972..af8b3f514a 100644 --- a/fda-container-managing-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java +++ b/fda-container-managing-service/rest-service/src/main/java/at/tuwien/config/SwaggerConfig.java @@ -8,7 +8,6 @@ import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.util.Collections; @@ -22,7 +21,7 @@ public class SwaggerConfig { .groupName("database-api") .apiInfo(apiInfo()) .select() - .paths(PathSelectors.ant("/api/database.*")) + .paths(PathSelectors.ant("/api/**")) .build(); } diff --git a/fda-container-managing-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseContainerController.java b/fda-container-managing-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseContainerController.java index 749d270731..b49d8739c9 100644 --- a/fda-container-managing-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseContainerController.java +++ b/fda-container-managing-service/rest-service/src/main/java/at/tuwien/endpoints/DatabaseContainerController.java @@ -3,7 +3,6 @@ package at.tuwien.endpoints; import at.tuwien.api.dto.container.ContainerChangeDto; import at.tuwien.api.dto.container.DatabaseContainerBriefDto; import at.tuwien.api.dto.container.DatabaseContainerDto; -import at.tuwien.api.dto.database.DatabaseContainerCreateResponseDto; import at.tuwien.api.dto.database.DatabaseContainerCreateRequestDto; import at.tuwien.entity.DatabaseContainer; import at.tuwien.exception.ContainerNotFoundException; @@ -11,6 +10,7 @@ import at.tuwien.exception.DockerClientException; import at.tuwien.exception.ImageNotFoundException; import at.tuwien.mapper.DatabaseContainerMapper; import at.tuwien.service.ContainerService; +import io.swagger.annotations.ApiOperation; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -37,50 +37,57 @@ public class DatabaseContainerController { } @GetMapping("/database") - public ResponseEntity<List<DatabaseContainerBriefDto>> listDatabaseContainers() { + @ApiOperation(value = "List all database containers", notes = "Lists the database containers in the metadata database.") + public ResponseEntity<List<DatabaseContainerBriefDto>> findAll() { final List<DatabaseContainer> containers = containerService.getAll(); return ResponseEntity.ok() .body(containers.stream() - .map(containerMapper::databaseContainerToDataBaseContainerBriefDto) + .map(containerMapper::databaseContainerToDatabaseContainerBriefDto) .collect(Collectors.toList())); } @PostMapping("/database") - public ResponseEntity<DatabaseContainerCreateResponseDto> create(@RequestBody DatabaseContainerCreateRequestDto data) + @ApiOperation(value = "Creates a new database containers", notes = "Creates a new database container whose image is registered in the metadata database too. Currently for development there is only one image supported 'postgres:12-alpine' as for temporal tables extension requires version 12.") + public ResponseEntity<DatabaseContainerDto> create(@RequestBody DatabaseContainerCreateRequestDto data) throws ImageNotFoundException { final DatabaseContainer container = containerService.create(data); log.debug("Create new database {} in container {} with id {}", data.getDatabaseName(), data.getContainerName(), container.getContainerId()); return ResponseEntity.status(HttpStatus.CREATED) - .body(containerMapper.databaseContainerToCreateDatabaseResponseDto(container)); + .body(containerMapper.databaseContainerToDatabaseContainerDto(container)); } @GetMapping("/database/{id}") + @ApiOperation(value = "Get all informations about a database container", notes = "Since we follow the REST-principle, this method provides more informaiton than the findAll method.") public ResponseEntity<DatabaseContainerDto> findById(@RequestParam String id) throws ContainerNotFoundException { final DatabaseContainer container = containerService.getById(id); return ResponseEntity.ok() - .body(containerMapper.databaseContainerToDataBaseContainerDto(container)); + .body(containerMapper.databaseContainerToDatabaseContainerDto(container)); } @PutMapping("/database/{id}") - public ResponseEntity<DatabaseContainerBriefDto> change(@RequestParam String id, @RequestBody ContainerChangeDto changeDto) throws ContainerNotFoundException, DockerClientException { - final DatabaseContainer container; + @ApiOperation(value = "Change the state of a database container", notes = "The new state can only be one of START/STOP/REMOVE.", code = 202) + public ResponseEntity<?> change(@RequestParam String id, @RequestBody ContainerChangeDto changeDto) throws ContainerNotFoundException, DockerClientException { + if (changeDto.getAction().equals(START) || changeDto.getAction().equals(STOP) || changeDto.getAction().equals(REMOVE)) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .build(); + } if (changeDto.getAction().equals(START)) { - container = containerService.start(id); + containerService.start(id); } else if (changeDto.getAction().equals(STOP)) { - container = containerService.stop(id); + containerService.stop(id); } else if (changeDto.getAction().equals(REMOVE)) { - container = containerService.remove(id); - } else { - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .build(); + containerService.remove(id); } return ResponseEntity.status(HttpStatus.ACCEPTED) - .body(containerMapper.databaseContainerToDataBaseContainerBriefDto(container)); + .build(); } @DeleteMapping("/database/{id}") - public ResponseEntity<DatabaseContainerBriefDto> deleteDatabaseContainer(@RequestParam String id) { - return ResponseEntity.status(HttpStatus.ACCEPTED).build(); + @ApiOperation(value = "Delete a database container.") + public ResponseEntity deleteDatabaseContainer(@RequestParam String id) throws ContainerNotFoundException, DockerClientException { + containerService.remove(id); + return ResponseEntity.status(HttpStatus.OK) + .build(); } } diff --git a/fda-container-managing-service/services/src/main/java/at/tuwien/mapper/DatabaseContainerMapper.java b/fda-container-managing-service/services/src/main/java/at/tuwien/mapper/DatabaseContainerMapper.java index 279119f7f5..4519a0094b 100644 --- a/fda-container-managing-service/services/src/main/java/at/tuwien/mapper/DatabaseContainerMapper.java +++ b/fda-container-managing-service/services/src/main/java/at/tuwien/mapper/DatabaseContainerMapper.java @@ -2,11 +2,11 @@ package at.tuwien.mapper; import at.tuwien.api.dto.container.DatabaseContainerBriefDto; import at.tuwien.api.dto.container.DatabaseContainerDto; -import at.tuwien.api.dto.database.DatabaseContainerCreateResponseDto; +import at.tuwien.api.dto.container.IpAddressDto; import at.tuwien.entity.ContainerImage; +import at.tuwien.entity.DatabaseContainer; import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.model.Container; -import at.tuwien.entity.DatabaseContainer; import com.github.dockerjava.api.model.NetworkSettings; import org.mapstruct.Mapper; import org.mapstruct.Mapping; @@ -20,13 +20,6 @@ public interface DatabaseContainerMapper { @Mapping(source = "created", target = "containerCreated"), }) DatabaseContainer inspectContainerResponseToDatabaseContainer(InspectContainerResponse containerResponse); -// public DatabaseContainer map(InspectContainerResponse containerResponse) { -// DatabaseContainer databaseContainer = new DatabaseContainer(); -// String ipAddress = containerResponse.getNetworkSettings().getNetworks().get("bridge").getIpAddress(); -// String dbName = Arrays.stream(containerResponse.getConfig().getEnv()).filter(s -> s.startsWith("POSTGRES_DB=")).findFirst().get(); -// databaseContainer.setStatus(containerResponse.getState().getStatus()); -// return databaseContainer; -// } default String networkSettingsNetworksBridgeToIpAddress(NetworkSettings data) { return data.getNetworks().get("bridge").getIpAddress(); @@ -35,16 +28,20 @@ public interface DatabaseContainerMapper { default ContainerImage imageToContainerImage(String image) { int index = image.indexOf(":"); return new ContainerImage().builder() - .repository(image.substring(0,index)) - .tag(image.substring(index+1)) + .repository(image.substring(0, index)) + .tag(image.substring(index + 1)) .build(); } DatabaseContainer containerToDatabaseContainer(Container data); - DatabaseContainerBriefDto databaseContainerToDataBaseContainerBriefDto(DatabaseContainer data); + DatabaseContainerBriefDto databaseContainerToDatabaseContainerBriefDto(DatabaseContainer data); + + @Mappings({ + @Mapping(target = "ipAddress.ipv4", source = "containerCreated"), + }) + DatabaseContainerDto databaseContainerToDatabaseContainerDto(DatabaseContainer data); - DatabaseContainerDto databaseContainerToDataBaseContainerDto(DatabaseContainer data); + IpAddressDto ipAddressToIpAddressDto(String data); - DatabaseContainerCreateResponseDto databaseContainerToCreateDatabaseResponseDto(DatabaseContainer data); } diff --git a/fda-container-managing-service/services/src/main/java/at/tuwien/service/ContainerService.java b/fda-container-managing-service/services/src/main/java/at/tuwien/service/ContainerService.java index cd248e60cb..9db0810567 100644 --- a/fda-container-managing-service/services/src/main/java/at/tuwien/service/ContainerService.java +++ b/fda-container-managing-service/services/src/main/java/at/tuwien/service/ContainerService.java @@ -92,7 +92,7 @@ public class ContainerService { return container; } - public DatabaseContainer remove(String containerId) throws ContainerNotFoundException, DockerClientException { + public void remove(String containerId) throws ContainerNotFoundException, DockerClientException { final DatabaseContainer container = containerRepository.findByContainerId(containerId); if (container == null) { throw new ContainerNotFoundException("no container with this id in metadata database"); @@ -103,7 +103,6 @@ public class ContainerService { throw new DockerClientException("docker client failed", e); } log.debug("Removed container {}", containerId); - return container; } public DatabaseContainer getById(String containerId) throws ContainerNotFoundException { -- GitLab