swaggerblueprint

Blueprint project for spring boot application with OpenApi Swagger docs
git clone git://git.wimdupont.com/swaggerblueprint.git
Log | Files | Refs | README | LICENSE

commit 206240d936b15c67462df6adf979eb26ee33196b
parent a8917d4744851c5284ddd6c277e8ebc24e3ddf3a
Author: Wim Dupont <wim@wimdupont.com>
Date:   Mon,  6 Feb 2023 22:31:59 +0100

added request methods and sb3 upgrade

Diffstat:
Mpom.xml | 6+++---
Msrc/main/java/com/wimdupont/swagger/blueprint/config/SwaggerConfig.java | 3+--
Msrc/main/java/com/wimdupont/swagger/blueprint/controller/BlueprintController.java | 32++++++++++++++++++++++++++++++--
Msrc/main/java/com/wimdupont/swagger/blueprint/controller/dto/BlueprintDto.java | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Asrc/main/java/com/wimdupont/swagger/blueprint/exception/EntityNotFoundException.java | 12++++++++++++
Msrc/main/java/com/wimdupont/swagger/blueprint/service/BlueprintService.java | 33+++++++++++++++++++++++++++++----
Msrc/main/resources/application.properties | 1+
7 files changed, 158 insertions(+), 20 deletions(-)

diff --git a/pom.xml b/pom.xml @@ -10,11 +10,11 @@ <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> - <version>2.5.6</version> + <version>3.0.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> - <springdoc-openapi.version>1.5.12</springdoc-openapi.version> + <springdoc-openapi.version>2.0.2</springdoc-openapi.version> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> @@ -31,7 +31,7 @@ </dependency> <dependency> <groupId>org.springdoc</groupId> - <artifactId>springdoc-openapi-ui</artifactId> + <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>${springdoc-openapi.version}</version> </dependency> </dependencies> diff --git a/src/main/java/com/wimdupont/swagger/blueprint/config/SwaggerConfig.java b/src/main/java/com/wimdupont/swagger/blueprint/config/SwaggerConfig.java @@ -2,7 +2,7 @@ package com.wimdupont.swagger.blueprint.config; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; -import org.springdoc.core.GroupedOpenApi; +import org.springdoc.core.models.GroupedOpenApi; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -12,7 +12,6 @@ import java.net.URL; import java.nio.file.Files; @Configuration -@SuppressWarnings("unused") public class SwaggerConfig { private static final String DOCUMENTATION_FILE = "documentation.md"; diff --git a/src/main/java/com/wimdupont/swagger/blueprint/controller/BlueprintController.java b/src/main/java/com/wimdupont/swagger/blueprint/controller/BlueprintController.java @@ -3,20 +3,48 @@ package com.wimdupont.swagger.blueprint.controller; import com.wimdupont.swagger.blueprint.controller.dto.BlueprintDto; import com.wimdupont.swagger.blueprint.service.BlueprintService; import io.swagger.v3.oas.annotations.Operation; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Set; +import java.util.UUID; @RestController @RequestMapping("/blueprints") -@SuppressWarnings("unused") -public record BlueprintController(BlueprintService blueprintService) { +public class BlueprintController { + + private final BlueprintService blueprintService; + + public BlueprintController(BlueprintService blueprintService) { + this.blueprintService = blueprintService; + } @GetMapping @Operation(summary = "Retrieve blueprints", description = "This will list all the unique blueprints") public Set<BlueprintDto> getBlueprints() { return blueprintService.getBlueprints(); } + + @PostMapping + @Operation(summary = "Create blueprint", description = "This will create a new blueprint") + public BlueprintDto createBlueprint(@RequestBody BlueprintDto blueprintDto) { + return blueprintService.createBlueprint(blueprintDto); + } + + @PutMapping("/{id}") + public BlueprintDto updateBlueprint(@PathVariable UUID id, @RequestBody BlueprintDto blueprintDto) { + return blueprintService.updateBlueprint(id, blueprintDto); + } + + @DeleteMapping("/{id}") + public void deleteBlueprint(@PathVariable UUID id) { + blueprintService.deleteBlueprint(id); + } + } diff --git a/src/main/java/com/wimdupont/swagger/blueprint/controller/dto/BlueprintDto.java b/src/main/java/com/wimdupont/swagger/blueprint/controller/dto/BlueprintDto.java @@ -1,16 +1,89 @@ package com.wimdupont.swagger.blueprint.controller.dto; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; +import java.util.UUID; -public record BlueprintDto( - @NotNull - @Schema(description = "Name of the blueprint", example = "blueprint-name") - String name, +@JsonDeserialize(builder = BlueprintDto.Builder.class) +public class BlueprintDto { + @NotNull + @Schema(accessMode = AccessMode.READ_ONLY, description = "Unique identifier of the blueprint", example = "030e5b9d-b4ed-4900-af24-cb2eac570056") + UUID id; - @Min(10) - @Schema(description = "Number of the blueprint", example = "42") - Integer number) { + @NotNull + @Schema(description = "Name of the blueprint", example = "blueprint-name") + String name; + + @Min(10) + @Schema(description = "Number of the blueprint", example = "42") + Integer number; + + private BlueprintDto(Builder builder) { + setId(builder.id); + setName(builder.name); + setNumber(builder.number); + } + + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + this.number = number; + } + + @JsonPOJOBuilder(withPrefix = "") + public static final class Builder { + private @NotNull UUID id; + private @NotNull String name; + private @Min(10) Integer number; + + private Builder() { + } + + public static Builder newBuilder() { + return new Builder(); + } + + public Builder id(@NotNull UUID val) { + id = val; + return this; + } + + public Builder name(@NotNull String val) { + name = val; + return this; + } + + public Builder number(@Min(10) Integer val) { + number = val; + return this; + } + + public BlueprintDto build() { + return new BlueprintDto(this); + } + } } diff --git a/src/main/java/com/wimdupont/swagger/blueprint/exception/EntityNotFoundException.java b/src/main/java/com/wimdupont/swagger/blueprint/exception/EntityNotFoundException.java @@ -0,0 +1,12 @@ +package com.wimdupont.swagger.blueprint.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.BAD_REQUEST) +public class EntityNotFoundException extends RuntimeException { + + public <T> EntityNotFoundException(Class<T> clazz, String id) { + super(String.format("Entity (%s) not found for id: %s", clazz.getSimpleName(), id)); + } +} diff --git a/src/main/java/com/wimdupont/swagger/blueprint/service/BlueprintService.java b/src/main/java/com/wimdupont/swagger/blueprint/service/BlueprintService.java @@ -1,18 +1,43 @@ package com.wimdupont.swagger.blueprint.service; import com.wimdupont.swagger.blueprint.controller.dto.BlueprintDto; +import com.wimdupont.swagger.blueprint.exception.EntityNotFoundException; import org.springframework.stereotype.Service; import java.util.HashSet; import java.util.Set; +import java.util.UUID; @Service public class BlueprintService { + private final Set<BlueprintDto> blueprintDtoSet = new HashSet<>(); + + public BlueprintService() { + blueprintDtoSet.add(BlueprintDto.Builder.newBuilder().id(UUID.randomUUID()).name("blueprint-one").number(420).build()); + blueprintDtoSet.add(BlueprintDto.Builder.newBuilder().id(UUID.randomUUID()).name("blueprint-two").number(666).build()); + } + public Set<BlueprintDto> getBlueprints() { - Set<BlueprintDto> blueprintDtos = new HashSet<>(); - blueprintDtos.add(new BlueprintDto("blueprint-one", 420)); - blueprintDtos.add(new BlueprintDto("blueprint-two", 666)); - return blueprintDtos; + return blueprintDtoSet; + } + + public BlueprintDto createBlueprint(BlueprintDto blueprintDto) { + blueprintDto.setId(UUID.randomUUID()); + blueprintDtoSet.add(blueprintDto); + return blueprintDto; + } + + public BlueprintDto updateBlueprint(UUID id, BlueprintDto blueprintDto) { + var old = getBlueprints().stream().filter(f -> f.getId().equals(id)).findAny() + .orElseThrow(() -> new EntityNotFoundException(BlueprintDto.class, id.toString())); + old.setName(blueprintDto.getName()); + old.setNumber(blueprintDto.getNumber()); + return old; + } + + public void deleteBlueprint(UUID id) { + getBlueprints().remove(getBlueprints().stream().filter(f -> f.getId().equals(id)).findAny() + .orElseThrow(() -> new EntityNotFoundException(BlueprintDto.class, id.toString()))); } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties @@ -1,2 +1,3 @@ springdoc.packagesToScan=com.wimdupont.swagger.blueprint springdoc.pathsToMatch=/v1, /blueprints/** +server.error.include-message=ALWAYS