From 8b6ed826b69bcdec0e29877889a20c23f06e59ac Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Thu, 21 Nov 2024 13:17:02 -0800 Subject: [PATCH 01/15] Create Project Repo --- .../wfprev/common/entities/CommonModel.java | 5 + .../nrs/wfprev/common/enums/CodeTables.java | 15 ++ .../wfprev/controllers/CodesController.java | 106 ++++++++++ .../controllers/ProgramAreaController.java | 187 +++++++++++++++++ ...Controller.java => ProjectController.java} | 188 +++++++----------- .../ExampleCodeResourceAssembler.java | 96 --------- .../assemblers/ExampleResourceAssembler.java | 110 ---------- .../ForestAreaCodeResourceAssembler.java | 75 +++++++ .../GeneralScopeCodeResourceAssembler.java | 75 +++++++ .../ProgramAreaResourceAssembler.java | 65 ++++++ .../assemblers/ProjectResourceAssembler.java | 115 +++++++++++ .../nrs/wfprev/data/model/ExampleEntity.java | 163 --------------- ...eEntity.java => ForestAreaCodeEntity.java} | 12 +- .../data/model/GeneralScopeCodeEntity.java | 80 ++++++++ .../wfprev/data/model/ProgramAreaEntity.java | 71 +++++++ .../nrs/wfprev/data/model/ProjectEntity.java | 175 ++++++++++++++++ .../data/repositories/ExampleRepository.java | 31 --- .../ForestAreaCodeRepository.java | 11 + .../GeneralScopeCodeRepository.java | 10 + ...sitory.java => ProgramAreaRepository.java} | 5 +- .../data/repositories/ProjectRepository.java | 10 + .../wfprev/data/resources/ExampleModel.java | 53 ----- .../data/resources/ForestAreaCodeModel.java | 33 +++ ...eModel.java => GeneralScopeCodeModel.java} | 34 ++-- .../data/resources/ProgramAreaModel.java | 27 +++ .../wfprev/data/resources/ProjectModel.java | 56 ++++++ .../gov/nrs/wfprev/services/CodesService.java | 72 +++++++ .../nrs/wfprev/services/ExampleService.java | 105 ---------- .../wfprev/services/ProgramAreaService.java | 74 +++++++ .../nrs/wfprev/services/ProjectService.java | 75 +++++++ 30 files changed, 1435 insertions(+), 699 deletions(-) create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/{ExampleController.java => ProjectController.java} (54%) delete mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ExampleCodeResourceAssembler.java delete mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ExampleResourceAssembler.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProgramAreaResourceAssembler.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java delete mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ExampleEntity.java rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/{ExampleCodeEntity.java => ForestAreaCodeEntity.java} (88%) create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/GeneralScopeCodeEntity.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProgramAreaEntity.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectEntity.java delete mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ExampleRepository.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ForestAreaCodeRepository.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/GeneralScopeCodeRepository.java rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/{ExampleCodeRepository.java => ProgramAreaRepository.java} (61%) create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectRepository.java delete mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ExampleModel.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ForestAreaCodeModel.java rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/{ExampleCodeModel.java => GeneralScopeCodeModel.java} (61%) create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProgramAreaModel.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectModel.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java delete mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ExampleService.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProgramAreaService.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/entities/CommonModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/entities/CommonModel.java index 4b064720b..f972ac36e 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/entities/CommonModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/entities/CommonModel.java @@ -15,6 +15,11 @@ @Data @EqualsAndHashCode(callSuper = false) public abstract class CommonModel> extends RepresentationModel implements Serializable { + private Integer revisionCount; + private String createUser; + private Date createDate; + private String updateUser; + private Date updateDate; public String eTag() { return ETag.generate(this); } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java new file mode 100644 index 000000000..4dadae413 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java @@ -0,0 +1,15 @@ +package ca.bc.gov.nrs.wfprev.common.enums; + +public enum CodeTables { + FOREST_AREA("forestAreaCode"), + GENERAL_SCOPE("generalScopeCode"); + + private final String text; + private CodeTables(final String text) { + this.text = text; + } + @Override + public String toString() { + return text; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java new file mode 100644 index 000000000..c8f6eb9a1 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java @@ -0,0 +1,106 @@ +package ca.bc.gov.nrs.wfprev.controllers; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import ca.bc.gov.nrs.common.wfone.rest.resource.HeaderConstants; +import ca.bc.gov.nrs.common.wfone.rest.resource.MessageListRsrc; +import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; +import ca.bc.gov.nrs.wfprev.common.controllers.CommonController; +import ca.bc.gov.nrs.wfprev.common.entities.CommonModel; +import ca.bc.gov.nrs.wfprev.services.CodesService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.extensions.Extension; +import io.swagger.v3.oas.annotations.extensions.ExtensionProperty; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import lombok.extern.slf4j.Slf4j; + +@RestController +@Slf4j +@RequestMapping(value="/codes") +public class CodesController extends CommonController { + private CodesService codesService; + + public CodesController(CodesService codesService) { + super(CodesController.class.getName()); + this.codesService = codesService; + } + + @GetMapping("/{codeTable}") + @Operation(summary = "Fetch all Forest Area Code Resources", + description = "Fetch all Forest Area Code Resources", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CollectionModel.class))), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity getCodes(@PathVariable("codeTable") String codeTable) { + log.debug(" >> getCodes"); + ResponseEntity response; + + try { + switch(codeTable) { + case "forestAreaCodes": + response = ok(codesService.getAllForestAreaCodes()); + break; + case "generalScopeCodes": + response = ok(codesService.getAllGeneralScopeCodes()); + break; + default: + response = internalServerError(); + } + } catch (ServiceException e) { + response = internalServerError(); + log.error(" ### Error while fetching codes", e); + } + + log.debug(" << getCodes"); + return response; + } + + @GetMapping("/{codeTable}/{id}") + @Operation(summary = "Fetch a Code Resource", + description = "Fetch a Code Resource", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CollectionModel.class))), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity getCodeById(@PathVariable("codeTable") String codeTable, @PathVariable("id") String id) { + log.debug(" >> getCodeById"); + CommonModel resource; + ResponseEntity response; + + try { + switch(codeTable) { + case "forestAreaCodes": + resource = codesService.getForestAreaCodeById(id); + break; + case "generalScopeCodes": + resource = codesService.getGeneralScopeCodeById(id); + break; + default: + resource = null; + } + + response = resource == null ? notFound() : ok(resource); + } catch (ServiceException e) { + response = internalServerError(); + log.error(" ### Error while fetching code", e); + } + + log.debug(" << getCodeById"); + return response; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java new file mode 100644 index 000000000..ccad88ab3 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java @@ -0,0 +1,187 @@ +package ca.bc.gov.nrs.wfprev.controllers; + +import java.util.Date; +import java.util.UUID; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.http.ResponseEntity; +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 ca.bc.gov.nrs.common.wfone.rest.resource.HeaderConstants; +import ca.bc.gov.nrs.common.wfone.rest.resource.MessageListRsrc; +import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; +import ca.bc.gov.nrs.wfprev.common.controllers.CommonController; +import ca.bc.gov.nrs.wfprev.data.resources.ProgramAreaModel; +import ca.bc.gov.nrs.wfprev.services.ProgramAreaService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.extensions.Extension; +import io.swagger.v3.oas.annotations.extensions.ExtensionProperty; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import lombok.extern.slf4j.Slf4j; + + +@RestController +@Slf4j +@RequestMapping(value="/programAreas") +public class ProgramAreaController extends CommonController { + private ProgramAreaService programAreaService; + + public ProgramAreaController(ProgramAreaService programAreaService) { + super(ProgramAreaController.class.getName()); + this.programAreaService = programAreaService; + } + + @GetMapping("/") + @Operation(summary = "Fetch all Program Area Resources", + description = "Fetch all Program Area Resources", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CollectionModel.class))), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity> getAllProgramAreas() { + log.debug(" >> getAllProgramAreas"); + ResponseEntity> response; + + try { + response = ok(programAreaService.getAllProgramAreas()); + } catch (ServiceException e) { + response = internalServerError(); + log.error(" ### Error while fetching program areas", e); + } + + log.debug(" << getAllProgramAreas"); + return response; + } + + @GetMapping("/{id}") + @Operation(summary = "Fetch program area by ID", + description = "Fetch program area by ID", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProgramAreaModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity getById(@PathVariable("id") String id) { + log.debug(" >> getById {}", id); + ResponseEntity response; + + try { + ProgramAreaModel resource = programAreaService.getProgramAreaById(id); + response = resource == null ? notFound() : ok(resource); + } catch(ServiceException e) { + response = internalServerError(); + log.error(" ### Error while fetching Program Area {}", id, e); + } + + log.debug(" << getById"); + return response; + } + + @PostMapping("/") + @Operation(summary = "Create a Program Area Resource", + description = "Create a Program Area Resource", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "OK", content = @Content(schema = @Schema(implementation = ProgramAreaModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity createProgramArea(@RequestBody ProgramAreaModel resource) { + log.debug(" >> createProgramArea"); + ResponseEntity response; + + try { + // set the default values for a newly created resource + resource.setCreateDate(new Date()); + resource.setCreateUser(getWebAdeAuthentication().getUserId()); + resource.setUpdateUser(getWebAdeAuthentication().getUserId()); + resource.setRevisionCount(0); + resource.setProgramAreaGuid(UUID.randomUUID().toString()); + + ProgramAreaModel newResource = programAreaService.createOrUpdateProgramArea(resource); + response = newResource == null ? badRequest() : created(newResource); + } catch(ServiceException e) { + response = internalServerError(); + log.error(" ### Error while creating resource", e); + } + + log.debug(" << createProgramArea"); + return response; + } + + @PutMapping("/{id}") + @Operation(summary = "Update Program Area Resource", + description = "Update Program Area Resource", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProgramAreaModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity updateProgramArea(@RequestBody ProgramAreaModel resource, @PathVariable("id") String id) { + log.debug(" >> updateProgramArea"); + ResponseEntity response; + + try { + // Update the UpdatedBy + resource.setUpdateUser(getWebAdeAuthentication().getUserId()); + // ensure that the user hasn't changed the primary key + if (id.equalsIgnoreCase(resource.getProgramAreaGuid())) { + ProgramAreaModel updatedResource = programAreaService.createOrUpdateProgramArea(resource); + response = updatedResource == null ? badRequest() : ok(updatedResource); + } else { + response = badRequest(); + } + } catch(ServiceException e) { + // most responses here will actually be Bad Requests, not Internal Server Errors + // This would be an ideal place to expand the "Catch" and return sensible + // HTTP status codes + response = internalServerError(); + log.error(" ### Error while updating Program Area", e); + } + + log.debug(" << updateProgramArea"); + return response; + } + + @DeleteMapping("/{id}") + @Operation(summary = "Delete Program Area Resource", + description = "Delete Program Area Resource", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProgramAreaModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity deleteProgramArea(@PathVariable("id") String id) { + log.debug(" >> deleteProgramArea"); + ResponseEntity response; + + try { + ProgramAreaModel resource = programAreaService.deleteProgramArea(id); + response = resource == null ? badRequest() : created(resource); + } catch(ServiceException e) { + // most responses here will actually be Bad Requests, not Internal Server Errors + // This would be an ideal place to expand the "Catch" and return sensible + // HTTP status codes + response = internalServerError(); + log.error(" ### Error while updating Program Area", e); + } + + log.debug(" << deleteProgramArea"); + return response; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ExampleController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java similarity index 54% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ExampleController.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java index e7337a6f9..5ebb6760d 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ExampleController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java @@ -5,6 +5,7 @@ import org.springframework.hateoas.CollectionModel; import org.springframework.http.ResponseEntity; +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; @@ -17,9 +18,8 @@ import ca.bc.gov.nrs.common.wfone.rest.resource.MessageListRsrc; import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; import ca.bc.gov.nrs.wfprev.common.controllers.CommonController; -import ca.bc.gov.nrs.wfprev.data.resources.ExampleCodeModel; -import ca.bc.gov.nrs.wfprev.data.resources.ExampleModel; -import ca.bc.gov.nrs.wfprev.services.ExampleService; +import ca.bc.gov.nrs.wfprev.data.resources.ProjectModel; +import ca.bc.gov.nrs.wfprev.services.ProjectService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; @@ -34,130 +34,114 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import lombok.extern.slf4j.Slf4j; -/** - * Your Rest controller. This is where you define the request mappings that consumers - * can hit. This should include any additional rules needed for the security implementation - * - * Typically, a controller will not contain any direct business logic. This should be in - * service implementations. The controller will only handle passing the request through - * to services (after validation, etc), and returning the response. - * - * This means that even though we have repository objects here in the controller for this - * example, generally, you won't do that unless it's for something really simple that - * doesn't need a service implementation - * - * Note: We could use the more traditional Java Interface/Impl architecture if desired - * This allows us to put a lot of the annotation mess for swagger out of the way of implementation - */ - @RestController @Slf4j -@RequestMapping(value="/wfprev") -public class ExampleController extends CommonController { - private ExampleService exampleService; +@RequestMapping(value="/projects") +public class ProjectController extends CommonController { + private ProjectService projectService; - public ExampleController(ExampleService exampleService) { - super(ExampleController.class.getName()); - this.exampleService = exampleService; + public ProjectController(ProjectService projectService) { + super(ProjectController.class.getName()); + this.projectService = projectService; } - @GetMapping("/examples") - @Operation(summary = "Fetch all Example Resources", - description = "Fetch all Example Resources", + @GetMapping("/") + @Operation(summary = "Fetch all Program Area Resources", + description = "Fetch all Program Area Resources", security = @SecurityRequirement(name = "Webade-OAUTH2", - scopes = { "ExampleScope" }), + scopes = { "WFPREV" }), extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CollectionModel.class))), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) - public ResponseEntity> getAllExamples() { - log.debug(" >> getAllExamples"); - ResponseEntity> response; + public ResponseEntity> getAllProjects() { + log.debug(" >> getAllProjects"); + ResponseEntity> response; try { - response = ok(exampleService.getAllExamples()); + response = ok(projectService.getAllProjects()); } catch (ServiceException e) { response = internalServerError(); - log.error(" ### Error while fetching examples", e); + log.error(" ### Error while fetching Projects", e); } - log.debug(" << getAllExamples"); + log.debug(" << getAllProjects"); return response; } - - @GetMapping("/examples/{id}") - @Operation(summary = "Fetch an Example Resource by ID", - description = "Fetch an Example Resource by ID", + + @GetMapping("/{id}") + @Operation(summary = "Fetch program area by ID", + description = "Fetch program area by ID", security = @SecurityRequirement(name = "Webade-OAUTH2", - scopes = { "ExampleScope" }), + scopes = { "WFPREV" }), extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) - @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ExampleModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProjectModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) - public ResponseEntity getExampleById(@PathVariable("id") String id) { - log.debug(" >> getExampleById {}", id); - ResponseEntity response; + public ResponseEntity getById(@PathVariable("id") String id) { + log.debug(" >> getById {}", id); + ResponseEntity response; try { - ExampleModel resource = exampleService.getExampleById(id); + ProjectModel resource = projectService.getProjectById(id); response = resource == null ? notFound() : ok(resource); } catch(ServiceException e) { response = internalServerError(); - log.error(" ### Error while fetching example {}", id, e); + log.error(" ### Error while fetching project {}", id, e); } - log.debug(" << getExampleById"); + log.debug(" << getById"); return response; } - @PostMapping("/examples") - @Operation(summary = "Create an Example Resource", - description = "Create an Example Resource", + @PostMapping("/") + @Operation(summary = "Create a Program Area Resource", + description = "Create a Program Area Resource", security = @SecurityRequirement(name = "Webade-OAUTH2", - scopes = { "ExampleScope" }), + scopes = { "WFPREV" }), extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) - @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "OK", content = @Content(schema = @Schema(implementation = ExampleModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "OK", content = @Content(schema = @Schema(implementation = ProjectModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) - public ResponseEntity createExample(@RequestBody ExampleModel resource) { - log.debug(" >> createExample"); - ResponseEntity response; + public ResponseEntity createProject(@RequestBody ProjectModel resource) { + log.debug(" >> createProject"); + ResponseEntity response; try { // set the default values for a newly created resource resource.setCreateDate(new Date()); - resource.setCreatedBy(getWebAdeAuthentication().getUserId()); - resource.setUpdatedBy(getWebAdeAuthentication().getUserId()); + resource.setCreateUser(getWebAdeAuthentication().getUserId()); + resource.setUpdateUser(getWebAdeAuthentication().getUserId()); resource.setRevisionCount(0); - resource.setExampleGuid(UUID.randomUUID().toString()); + resource.setProgramAreaGuid(UUID.randomUUID().toString()); - ExampleModel newResource = exampleService.createOrUpdateExample(resource); + ProjectModel newResource = projectService.createOrUpdateProject(resource); response = newResource == null ? badRequest() : created(newResource); } catch(ServiceException e) { response = internalServerError(); log.error(" ### Error while creating resource", e); } - log.debug(" << createExample"); + log.debug(" << createProject"); return response; } - @PutMapping("/examples/{id}") - @Operation(summary = "Create an Example Resource", - description = "Create an Example Resource", + @PutMapping("/{id}") + @Operation(summary = "Update Program Area Resource", + description = "Update Program Area Resource", security = @SecurityRequirement(name = "Webade-OAUTH2", - scopes = { "ExampleScope" }), + scopes = { "WFPREV" }), extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) - @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "OK", content = @Content(schema = @Schema(implementation = ExampleModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProjectModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) - public ResponseEntity updateExample(@RequestBody ExampleModel resource, @PathVariable("id") String id) { - log.debug(" >> updateExample"); - ResponseEntity response; + public ResponseEntity updateProject(@RequestBody ProjectModel resource, @PathVariable("id") String id) { + log.debug(" >> updateProject"); + ResponseEntity response; try { // Update the UpdatedBy - resource.setUpdatedBy(getWebAdeAuthentication().getUserId()); + resource.setUpdateUser(getWebAdeAuthentication().getUserId()); // ensure that the user hasn't changed the primary key - if (id.equalsIgnoreCase(resource.getExampleGuid())) { - ExampleModel updatedResource = exampleService.createOrUpdateExample(resource); - response = updatedResource == null ? badRequest() : created(updatedResource); + if (id.equalsIgnoreCase(resource.getProgramAreaGuid())) { + ProjectModel updatedResource = projectService.createOrUpdateProject(resource); + response = updatedResource == null ? badRequest() : ok(updatedResource); } else { response = badRequest(); } @@ -166,57 +150,37 @@ public ResponseEntity updateExample(@RequestBody ExampleModel reso // This would be an ideal place to expand the "Catch" and return sensible // HTTP status codes response = internalServerError(); - log.error(" ### Error while updating resource", e); + log.error(" ### Error while updating Program Area", e); } - log.debug(" << updateExample"); + log.debug(" << updateProject"); return response; } - - @GetMapping("/exampleCodes") - @Operation(summary = "Fetch all Example Code Resources", - description = "Fetch all Example Code ResourceS", - security = @SecurityRequirement(name = "Webade-OAUTH2", - scopes = { "ExampleScope" }), - extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) - @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CollectionModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) - @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) - public ResponseEntity> getAllExampleCodes() { - log.debug(" >> getAllExampleCodes"); - ResponseEntity> response; - try { - response = ok(exampleService.getAllExampleCodes()); - } catch (ServiceException e) { - response = internalServerError(); - log.error(" ### Error while fetching exampleCodes", e); - } - - log.debug(" << getAllExampleCodes"); - return response; - } - - @GetMapping("/exampleCodes/{id}") - @Operation(summary = "Fetch an Example Code Resource by ID", - description = "Fetch an Example Code Resource by ID", - security = @SecurityRequirement(name = "Webade-OAUTH2", - scopes = { "ExampleScope" }), - extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) - @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ExampleCodeModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @DeleteMapping("/{id}") + @Operation(summary = "Delete Program Area Resource", + description = "Delete Program Area Resource", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProjectModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) - public ResponseEntity getExampleCodeById(@PathVariable("id") String id) { - log.debug(" >> getExampleCodeById {}", id); - ResponseEntity response; + public ResponseEntity deleteProject(@PathVariable("id") String id) { + log.debug(" >> deleteProject"); + ResponseEntity response; try { - ExampleCodeModel resource = exampleService.getExampleCodeById(id); - response = resource == null ? notFound() : ok(resource); + ProjectModel resource = projectService.deleteProject(id); + response = resource == null ? badRequest() : created(resource); } catch(ServiceException e) { + // most responses here will actually be Bad Requests, not Internal Server Errors + // This would be an ideal place to expand the "Catch" and return sensible + // HTTP status codes response = internalServerError(); - log.error(" ### Error while fetching exampleCode {}", id, e); + log.error(" ### Error while updating Program Area", e); } - - log.debug(" << getExampleCodeById"); + + log.debug(" << deleteProject"); return response; } } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ExampleCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ExampleCodeResourceAssembler.java deleted file mode 100644 index 00e2c466c..000000000 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ExampleCodeResourceAssembler.java +++ /dev/null @@ -1,96 +0,0 @@ -package ca.bc.gov.nrs.wfprev.data.assemblers; - -import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; -import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import org.springframework.hateoas.CollectionModel; -import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; -import org.springframework.stereotype.Component; - -import ca.bc.gov.nrs.wfprev.data.model.ExampleCodeEntity; -import ca.bc.gov.nrs.wfprev.controllers.ExampleController; -import ca.bc.gov.nrs.wfprev.data.resources.ExampleCodeModel; - -@Component -public class ExampleCodeResourceAssembler extends RepresentationModelAssemblerSupport { - - public ExampleCodeResourceAssembler() { - super(ExampleController.class, ExampleCodeModel.class); - } - - public ExampleCodeEntity toEntity(ExampleCodeModel resource) { - ExampleCodeEntity entity = new ExampleCodeEntity(); - - entity.setExampleCode(resource.getExampleCode()); - entity.setDescription(resource.getDescription()); - entity.setDisplayOrder(resource.getDisplayOrder()); - entity.setEffectiveDate(resource.getEffectiveDate()); - entity.setExpiryDate(resource.getExpiryDate()); - entity.setRevisionCount(resource.getRevisionCount()); - entity.setCreatedBy(resource.getCreatedBy()); - entity.setCreateDate(resource.getCreateDate()); - entity.setUpdatedBy(resource.getUpdatedBy()); - entity.setUpdateDate(resource.getUpdateDate()); - - return entity; - } - - @Override - public ExampleCodeModel toModel(ExampleCodeEntity entity) { - ExampleCodeModel resource = instantiateModel(entity); - - resource.add(linkTo( - methodOn(ExampleController.class) - .getExampleCodeById(entity.getExampleCode())) - .withSelfRel()); - - resource.setExampleCode(entity.getExampleCode()); - resource.setDescription(entity.getDescription()); - resource.setDisplayOrder(entity.getDisplayOrder()); - resource.setEffectiveDate(entity.getEffectiveDate()); - resource.setExpiryDate(entity.getExpiryDate()); - resource.setRevisionCount(entity.getRevisionCount()); - resource.setCreatedBy(entity.getCreatedBy()); - resource.setCreateDate(entity.getCreateDate()); - resource.setUpdatedBy(entity.getUpdatedBy()); - resource.setUpdateDate(entity.getUpdateDate()); - - return resource; - } - - @Override - public CollectionModel toCollectionModel(Iterable entities) - { - CollectionModel resources = super.toCollectionModel(entities); - - resources.add(linkTo(methodOn(ExampleController.class).getAllExampleCodes()).withSelfRel()); - - return resources; - } - - private List toExampleCodeModel(List exampleCodes) { - if (exampleCodes.isEmpty()) - return Collections.emptyList(); - - return exampleCodes.stream() - .map(exampleCode -> ExampleCodeModel.builder() - .exampleCode(exampleCode.getExampleCode()) - .createDate(exampleCode.getCreateDate()) - .createdBy(exampleCode.getCreatedBy()) - .description(exampleCode.getDescription()) - .displayOrder(exampleCode.getDisplayOrder()) - .effectiveDate(exampleCode.getEffectiveDate()) - .expiryDate(exampleCode.getExpiryDate()) - .revisionCount(exampleCode.getRevisionCount()) - .updateDate(exampleCode.getUpdateDate()) - .updatedBy(exampleCode.getUpdatedBy()) - .build().add(linkTo(methodOn(ExampleController.class) - .getExampleCodeById(exampleCode.getExampleCode())) - .withSelfRel())) - .collect(Collectors.toList()); - } -} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ExampleResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ExampleResourceAssembler.java deleted file mode 100644 index 39c4cb093..000000000 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ExampleResourceAssembler.java +++ /dev/null @@ -1,110 +0,0 @@ -package ca.bc.gov.nrs.wfprev.data.assemblers; - -import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; -import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import org.springframework.hateoas.CollectionModel; -import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; -import org.springframework.stereotype.Component; - -import ca.bc.gov.nrs.wfprev.data.model.ExampleEntity; -import ca.bc.gov.nrs.wfprev.controllers.ExampleController; -import ca.bc.gov.nrs.wfprev.data.resources.ExampleModel; - -/** - * Resource Assmebler. This will construct the Resources from the Model objects - * This does the translations needed to take a Resource (the json implementation) - * and convert it to the DB representation, or vice versa. It's a basic DAO/DTO - * transformer factory. This allows you to define Collection resources as well - */ - -@Component -public class ExampleResourceAssembler extends RepresentationModelAssemblerSupport{ - - public ExampleResourceAssembler() { - super(ExampleController.class, ExampleModel.class); - } - - public ExampleEntity toEntity(ExampleModel resource) { - ExampleEntity entity = new ExampleEntity(); - - entity.setExampleGuid(resource.getExampleGuid()); - entity.setExampleCode(resource.getExampleCode()); - entity.setExampleText(resource.getExampleText()); - entity.setExampleVar(resource.getExampleVar()); - entity.setExampleNum(resource.getExampleNum()); - entity.setExampleInd(resource.getExampleInd()); - entity.setLastUpdatedTimestamp(resource.getLastUpdatedTimestamp()); - entity.setRevisionCount(resource.getRevisionCount()); - entity.setCreatedBy(resource.getCreatedBy()); - entity.setCreateDate(resource.getCreateDate()); - entity.setUpdatedBy(resource.getUpdatedBy()); - entity.setUpdateDate(resource.getUpdateDate()); - - return entity; - } - - @Override - public ExampleModel toModel(ExampleEntity entity) { - ExampleModel resource = instantiateModel(entity); - - resource.add(linkTo( - methodOn(ExampleController.class) - .getExampleById(entity.getExampleGuid())) - .withSelfRel()); - - resource.setExampleGuid(entity.getExampleGuid()); - resource.setExampleCode(entity.getExampleCode()); - resource.setExampleText(entity.getExampleText()); - resource.setExampleVar(entity.getExampleVar()); - resource.setExampleNum(entity.getExampleNum()); - resource.setExampleInd(entity.getExampleInd()); - resource.setLastUpdatedTimestamp(entity.getLastUpdatedTimestamp()); - resource.setRevisionCount(entity.getRevisionCount()); - resource.setCreatedBy(entity.getCreatedBy()); - resource.setCreateDate(entity.getCreateDate()); - resource.setUpdatedBy(entity.getUpdatedBy()); - resource.setUpdateDate(entity.getUpdateDate()); - - return resource; - } - - @Override - public CollectionModel toCollectionModel(Iterable entities) - { - CollectionModel resources = super.toCollectionModel(entities); - - resources.add(linkTo(methodOn(ExampleController.class).getAllExamples()).withSelfRel()); - - return resources; - } - - private List toExampleModel(List examples) { - if (examples.isEmpty()) - return Collections.emptyList(); - - return examples.stream() - .map(example -> ExampleModel.builder() - .exampleGuid(example.getExampleGuid()) - .createDate(example.getCreateDate()) - .createdBy(example.getCreatedBy()) - .exampleCode(example.getExampleCode()) - .exampleInd(example.getExampleInd()) - .exampleNum(example.getExampleNum()) - .exampleText(example.getExampleText()) - .exampleVar(example.getExampleVar()) - .lastUpdatedTimestamp(example.getLastUpdatedTimestamp()) - .revisionCount(example.getRevisionCount()) - .updateDate(example.getUpdateDate()) - .updatedBy(example.getUpdatedBy()) - .build() - .add(linkTo(methodOn(ExampleController.class) - .getExampleById(example.getExampleGuid())) - .withSelfRel())) - .collect(Collectors.toList()); - } -} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java new file mode 100644 index 000000000..7b5e4e3aa --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java @@ -0,0 +1,75 @@ +package ca.bc.gov.nrs.wfprev.data.assemblers; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; +import org.springframework.stereotype.Component; + +import ca.bc.gov.nrs.wfprev.data.model.ForestAreaCodeEntity; +import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; +import ca.bc.gov.nrs.wfprev.controllers.CodesController; +import ca.bc.gov.nrs.wfprev.data.resources.ForestAreaCodeModel; + +@Component +public class ForestAreaCodeResourceAssembler extends RepresentationModelAssemblerSupport { + + public ForestAreaCodeResourceAssembler() { + super(CodesController.class, ForestAreaCodeModel.class); + } + + public ForestAreaCodeEntity toEntity(ForestAreaCodeModel resource) { + ForestAreaCodeEntity entity = new ForestAreaCodeEntity(); + + entity.setForestAreaCode(resource.getForestAreaCode()); + entity.setDescription(resource.getDescription()); + entity.setDisplayOrder(resource.getDisplayOrder()); + entity.setEffectiveDate(resource.getEffectiveDate()); + entity.setExpiryDate(resource.getExpiryDate()); + entity.setRevisionCount(resource.getRevisionCount()); + entity.setCreateUser(resource.getCreateUser()); + entity.setCreateDate(resource.getCreateDate()); + entity.setUpdateUser(resource.getUpdateUser()); + entity.setUpdateDate(resource.getUpdateDate()); + + return entity; + } + + @Override + public ForestAreaCodeModel toModel(ForestAreaCodeEntity entity) { + ForestAreaCodeModel resource = instantiateModel(entity); + + resource.add(linkTo( + methodOn(CodesController.class) + .getCodeById(CodeTables.FOREST_AREA.toString(), entity.getForestAreaCode())) + .withSelfRel()); + + resource.setForestAreaCode(entity.getForestAreaCode()); + resource.setDescription(entity.getDescription()); + resource.setDisplayOrder(entity.getDisplayOrder()); + resource.setEffectiveDate(entity.getEffectiveDate()); + resource.setExpiryDate(entity.getExpiryDate()); + resource.setRevisionCount(entity.getRevisionCount()); + resource.setCreateUser(entity.getCreateUser()); + resource.setCreateDate(entity.getCreateDate()); + resource.setUpdateUser(entity.getUpdateUser()); + resource.setUpdateDate(entity.getUpdateDate()); + + return resource; + } + + @Override + public CollectionModel toCollectionModel(Iterable entities) + { + CollectionModel resources = super.toCollectionModel(entities); + + resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.FOREST_AREA.toString())).withSelfRel()); + + return resources; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java new file mode 100644 index 000000000..4afdaba76 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java @@ -0,0 +1,75 @@ +package ca.bc.gov.nrs.wfprev.data.assemblers; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; +import org.springframework.stereotype.Component; + +import ca.bc.gov.nrs.wfprev.data.model.GeneralScopeCodeEntity; +import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; +import ca.bc.gov.nrs.wfprev.controllers.CodesController; +import ca.bc.gov.nrs.wfprev.data.resources.GeneralScopeCodeModel; + +@Component +public class GeneralScopeCodeResourceAssembler extends RepresentationModelAssemblerSupport { + + public GeneralScopeCodeResourceAssembler() { + super(CodesController.class, GeneralScopeCodeModel.class); + } + + public GeneralScopeCodeEntity toEntity(GeneralScopeCodeModel resource) { + GeneralScopeCodeEntity entity = new GeneralScopeCodeEntity(); + + entity.setGeneralScopeCode(resource.getGeneralScopeCode()); + entity.setDescription(resource.getDescription()); + entity.setDisplayOrder(resource.getDisplayOrder()); + entity.setEffectiveDate(resource.getEffectiveDate()); + entity.setExpiryDate(resource.getExpiryDate()); + entity.setRevisionCount(resource.getRevisionCount()); + entity.setCreateUser(resource.getCreateUser()); + entity.setCreateDate(resource.getCreateDate()); + entity.setUpdateUser(resource.getUpdateUser()); + entity.setUpdateDate(resource.getUpdateDate()); + + return entity; + } + + @Override + public GeneralScopeCodeModel toModel(GeneralScopeCodeEntity entity) { + GeneralScopeCodeModel resource = instantiateModel(entity); + + resource.add(linkTo( + methodOn(CodesController.class) + .getCodeById(CodeTables.GENERAL_SCOPE.toString(), entity.getGeneralScopeCode())) + .withSelfRel()); + + resource.setGeneralScopeCode(entity.getGeneralScopeCode()); + resource.setDescription(entity.getDescription()); + resource.setDisplayOrder(entity.getDisplayOrder()); + resource.setEffectiveDate(entity.getEffectiveDate()); + resource.setExpiryDate(entity.getExpiryDate()); + resource.setRevisionCount(entity.getRevisionCount()); + resource.setCreateUser(entity.getCreateUser()); + resource.setCreateDate(entity.getCreateDate()); + resource.setUpdateUser(entity.getUpdateUser()); + resource.setUpdateDate(entity.getUpdateDate()); + + return resource; + } + + @Override + public CollectionModel toCollectionModel(Iterable entities) + { + CollectionModel resources = super.toCollectionModel(entities); + + resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.GENERAL_SCOPE.toString())).withSelfRel()); + + return resources; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProgramAreaResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProgramAreaResourceAssembler.java new file mode 100644 index 000000000..2d33c0717 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProgramAreaResourceAssembler.java @@ -0,0 +1,65 @@ +package ca.bc.gov.nrs.wfprev.data.assemblers; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; +import org.springframework.stereotype.Component; + +import ca.bc.gov.nrs.wfprev.data.model.ProgramAreaEntity; +import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; +import ca.bc.gov.nrs.wfprev.controllers.CodesController; +import ca.bc.gov.nrs.wfprev.controllers.ProgramAreaController; +import ca.bc.gov.nrs.wfprev.data.resources.ProgramAreaModel; + +@Component +public class ProgramAreaResourceAssembler extends RepresentationModelAssemblerSupport { + + public ProgramAreaResourceAssembler() { + super(ProgramAreaController.class, ProgramAreaModel.class); + } + + public ProgramAreaEntity toEntity(ProgramAreaModel resource) { + ProgramAreaEntity entity = new ProgramAreaEntity(); + + entity.setProgramAreaGuid(resource.getProgramAreaGuid()); + entity.setProgramAreaName(resource.getProgramAreaName()); + entity.setRevisionCount(resource.getRevisionCount()); + entity.setCreateUser(resource.getCreateUser()); + entity.setCreateDate(resource.getCreateDate()); + entity.setUpdateUser(resource.getUpdateUser()); + entity.setUpdateDate(resource.getUpdateDate()); + + return entity; + } + + @Override + public ProgramAreaModel toModel(ProgramAreaEntity entity) { + ProgramAreaModel resource = instantiateModel(entity); + + resource.add(linkTo( + methodOn(ProgramAreaController.class) + .getById(entity.getProgramAreaGuid())) + .withSelfRel()); + + resource.setProgramAreaGuid(entity.getProgramAreaGuid()); + resource.setProgramAreaName(entity.getProgramAreaName()); + resource.setRevisionCount(entity.getRevisionCount()); + resource.setCreateUser(entity.getCreateUser()); + resource.setCreateDate(entity.getCreateDate()); + resource.setUpdateUser(entity.getUpdateUser()); + resource.setUpdateDate(entity.getUpdateDate()); + + return resource; + } + + @Override + public CollectionModel toCollectionModel(Iterable entities) + { + CollectionModel resources = super.toCollectionModel(entities); + + resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.GENERAL_SCOPE.toString())).withSelfRel()); + + return resources; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java new file mode 100644 index 000000000..ac299ca98 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java @@ -0,0 +1,115 @@ +package ca.bc.gov.nrs.wfprev.data.assemblers; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; +import org.springframework.stereotype.Component; + +import ca.bc.gov.nrs.wfprev.data.model.ProjectEntity; +import ca.bc.gov.nrs.wfprev.controllers.ProjectController; +import ca.bc.gov.nrs.wfprev.data.resources.ProjectModel; + +@Component +public class ProjectResourceAssembler extends RepresentationModelAssemblerSupport { + + public ProjectResourceAssembler() { + super(ProjectController.class, ProjectModel.class); + } + + public ProjectEntity toEntity(ProjectModel resource) { + ProjectEntity entity = new ProjectEntity(); + + entity.setProjectGuid(resource.getProjectGuid()); + entity.setProjectTypeCode(resource.getProjectTypeCode()); + entity.setProjectNumber(resource.getProjectNumber()); + entity.setSiteUnitName(resource.getSiteUnitName()); + entity.setForestAreaCode(resource.getForestAreaCode()); + entity.setGeneralScopeCode(resource.getGeneralScopeCode()); + entity.setProgramAreaGuid(resource.getProgramAreaGuid()); + entity.setForestRegionOrgUnitId(resource.getForestRegionOrgUnitId()); + entity.setForestDistrictOrgUnitId(resource.getForestDistrictOrgUnitId()); + entity.setFireCentreOrgUnitId(resource.getFireCentreOrgUnitId()); + entity.setBcParksRegionOrgUnitId(resource.getBcParksRegionOrgUnitId()); + entity.setBcParksSectionOrgUnitId(resource.getBcParksSectionOrgUnitId()); + entity.setProjectName(resource.getProjectName()); + entity.setProjectLead(resource.getProjectLead()); + entity.setProjectLeadEmailAddress(resource.getProjectLeadEmailAddress()); + entity.setProjectDescription(resource.getProjectDescription()); + entity.setClosestCommunityName(resource.getClosestCommunityName()); + entity.setTotalFundingRequestAmount(resource.getTotalFundingRequestAmount()); + entity.setTotalAllocatedAmount(resource.getTotalAllocatedAmount()); + entity.setTotalPlannedProjectSizeHa(resource.getTotalPlannedProjectSizeHa()); + entity.setTotalPlannedCostPerHectare(resource.getTotalPlannedCostPerHectare()); + entity.setTotalActualAmount(resource.getTotalActualAmount()); + entity.setTotalProjectSizeHa(resource.getTotalProjectSizeHa()); + entity.setTotalCostPerHectareAmount(resource.getTotalCostPerHectareAmount()); + entity.setIsMultiFiscalYearProj(resource.getIsMultiFiscalYearProj()); + entity.setLatitude(resource.getLatitude()); + entity.setLongitude(resource.getLongitude()); + entity.setLastProgressUpdateTimestamp(resource.getLastProgressUpdateTimestamp()); + entity.setRevisionCount(resource.getRevisionCount()); + entity.setCreateUser(resource.getCreateUser()); + entity.setCreateDate(resource.getCreateDate()); + entity.setUpdateUser(resource.getUpdateUser()); + entity.setUpdateDate(resource.getUpdateDate()); + + return entity; + } + + @Override + public ProjectModel toModel(ProjectEntity entity) { + ProjectModel resource = instantiateModel(entity); + + resource.add(linkTo( + methodOn(ProjectController.class) + .getById(entity.getProgramAreaGuid())) + .withSelfRel()); + + resource.setProjectGuid(entity.getProjectGuid()); + resource.setProjectTypeCode(entity.getProjectTypeCode()); + resource.setProjectNumber(entity.getProjectNumber()); + resource.setSiteUnitName(entity.getSiteUnitName()); + resource.setForestAreaCode(entity.getForestAreaCode()); + resource.setGeneralScopeCode(entity.getGeneralScopeCode()); + resource.setProgramAreaGuid(entity.getProgramAreaGuid()); + resource.setForestRegionOrgUnitId(entity.getForestRegionOrgUnitId()); + resource.setForestDistrictOrgUnitId(entity.getForestDistrictOrgUnitId()); + resource.setFireCentreOrgUnitId(entity.getFireCentreOrgUnitId()); + resource.setBcParksRegionOrgUnitId(entity.getBcParksRegionOrgUnitId()); + resource.setBcParksSectionOrgUnitId(entity.getBcParksSectionOrgUnitId()); + resource.setProjectName(entity.getProjectName()); + resource.setProjectLead(entity.getProjectLead()); + resource.setProjectLeadEmailAddress(entity.getProjectLeadEmailAddress()); + resource.setProjectDescription(entity.getProjectDescription()); + resource.setClosestCommunityName(entity.getClosestCommunityName()); + resource.setTotalFundingRequestAmount(entity.getTotalFundingRequestAmount()); + resource.setTotalAllocatedAmount(entity.getTotalAllocatedAmount()); + resource.setTotalPlannedProjectSizeHa(entity.getTotalPlannedProjectSizeHa()); + resource.setTotalPlannedCostPerHectare(entity.getTotalPlannedCostPerHectare()); + resource.setTotalActualAmount(entity.getTotalActualAmount()); + resource.setTotalProjectSizeHa(entity.getTotalProjectSizeHa()); + resource.setTotalCostPerHectareAmount(entity.getTotalCostPerHectareAmount()); + resource.setIsMultiFiscalYearProj(entity.getIsMultiFiscalYearProj()); + resource.setLatitude(entity.getLatitude()); + resource.setLongitude(entity.getLongitude()); + resource.setLastProgressUpdateTimestamp(entity.getLastProgressUpdateTimestamp()); + resource.setRevisionCount(entity.getRevisionCount()); + resource.setCreateUser(entity.getCreateUser()); + resource.setCreateDate(entity.getCreateDate()); + resource.setUpdateUser(entity.getUpdateUser()); + resource.setUpdateDate(entity.getUpdateDate()); + + return resource; + } + + @Override + public CollectionModel toCollectionModel(Iterable entities) + { + CollectionModel resources = super.toCollectionModel(entities); + + resources.add(linkTo(methodOn(ProjectController.class).getAllProjects()).withSelfRel()); + + return resources; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ExampleEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ExampleEntity.java deleted file mode 100644 index 045a6b9e0..000000000 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ExampleEntity.java +++ /dev/null @@ -1,163 +0,0 @@ -package ca.bc.gov.nrs.wfprev.data.model; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.util.Date; -import java.util.UUID; - -import org.hibernate.annotations.NotFound; -import org.hibernate.annotations.NotFoundAction; -import org.hibernate.annotations.UuidGenerator; -import org.springframework.data.annotation.CreatedBy; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedBy; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.rest.core.annotation.RestResource; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import ca.bc.gov.nrs.wfprev.common.converters.BooleanConverter; -import ca.bc.gov.nrs.wfprev.common.validators.Latitude; -import ca.bc.gov.nrs.wfprev.common.validators.Longitude; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.PrePersist; -import jakarta.persistence.PreUpdate; -import jakarta.persistence.PreRemove; -import jakarta.persistence.PostPersist; -import jakarta.persistence.PostUpdate; -import jakarta.persistence.PostRemove; -import jakarta.persistence.CascadeType; -import jakarta.persistence.Column; -import jakarta.persistence.Convert; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Table; -import jakarta.persistence.Version; -import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; - -/** - * A really simple example resource model. Doesn't match the example model but enough for a demo - */ - -@Entity -@Table(name = "EXAMPLE_TABLE") -@JsonIgnoreProperties(ignoreUnknown = false) -@Data -@EqualsAndHashCode(callSuper = false) -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class ExampleEntity implements Serializable { - private static final long serialVersionUID = 1L; - - @Id - @UuidGenerator - @GeneratedValue(strategy = GenerationType.UUID) - @Column(name = "example_guid") - private String exampleGuid; - - //@NotFound(action = NotFoundAction.IGNORE) - //@RestResource(exported = false) - //@ManyToOne(fetch = FetchType.LAZY, optional = true, cascade = CascadeType.REFRESH) - //@JoinColumn(name="example_code") - @Column(name="example_code") - private String exampleCode; - - @Column(name = "example_text") - private String exampleText; - - @Column(name = "example_var", length = 25) - private String exampleVar; - - @Column(name = "example_num", precision = 10, scale = 3) - private BigDecimal exampleNum; - - @Column(name = "example_ind") - @Convert(converter = BooleanConverter.class) - @NotNull - private Boolean exampleInd; - - @LastModifiedDate - @Column(name="last_updated_timestamp") - private Long lastUpdatedTimestamp; - - // alternative way to set column definitions - @Column(name = "revision_count", columnDefinition="Decimal(10) default '0'") - @NotNull - @Version // Version enables optomistic locks. This will detect conflicts. - private Integer revisionCount; - - @CreatedBy - @NotNull - @Column(name="create_user", length = 64) - private String createdBy; - - @CreatedDate - @NotNull - @Column(name="create_date") - private Date createDate; - - @LastModifiedBy - @NotNull - @Column(name="update_user", length = 64) - private String updatedBy; - - @LastModifiedDate - @NotNull - @Column(name="update_date") - private Date updateDate; - - // Example for spatial columns - //@Latitude - //@NotNull - //private Double latitude; - - //@Longitude - //@NotNull - //private Double longitude; - - //@Column(columnDefinition = "GEOMETRY(Point,4326)", nullable = false) - //private Point geometry; - - - /*** Events that must trigger BEFORE pushing changes to the Database with this entity *******/ - @PrePersist - public void prePersist() { - // do stuff you need to do before you write to the DB (POST) - } - - @PreUpdate - public void preUpdate() { - // as above, but on Update events only - } - - @PreRemove - public void preDelete() { - // Before delete is executed - } - - /*** Events that must trigger AFTER pushing changes to the Database with this entity *******/ - @PostPersist - public void postPersist() { - // do stuff you need to do after you write to the DB (POST) - } - - @PostUpdate - public void postUpdate() { - // as above, but on Update events only - } - - @PostRemove - public void postDelete() { - // After delete is executed - } -} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ExampleCodeEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ForestAreaCodeEntity.java similarity index 88% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ExampleCodeEntity.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ForestAreaCodeEntity.java index 2660942eb..b575b0ee2 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ExampleCodeEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ForestAreaCodeEntity.java @@ -23,20 +23,20 @@ import lombok.NoArgsConstructor; @Entity -@Table(name = "EXAMPLE_CODE") +@Table(name = "forest_area_code") @JsonIgnoreProperties(ignoreUnknown = false) @Data @EqualsAndHashCode(callSuper = false) @Builder @AllArgsConstructor @NoArgsConstructor -public class ExampleCodeEntity implements Serializable { +public class ForestAreaCodeEntity implements Serializable { private static final long serialVersionUID = 1L; @Id - @Column(name = "example_code") + @Column(name = "forest_area_code") @NotNull - private String exampleCode; + private String forestAreaCode; @NotNull @Column(name = "description", length = 200) @@ -61,7 +61,7 @@ public class ExampleCodeEntity implements Serializable { @CreatedBy @NotNull @Column(name="create_user", length = 64) - private String createdBy; + private String createUser; @CreatedDate @NotNull @@ -71,7 +71,7 @@ public class ExampleCodeEntity implements Serializable { @LastModifiedBy @NotNull @Column(name="update_user", length = 64) - private String updatedBy; + private String updateUser; @LastModifiedDate @NotNull diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/GeneralScopeCodeEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/GeneralScopeCodeEntity.java new file mode 100644 index 000000000..c223b174d --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/GeneralScopeCodeEntity.java @@ -0,0 +1,80 @@ +package ca.bc.gov.nrs.wfprev.data.model; + +import java.io.Serializable; + +import java.util.Date; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import jakarta.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.persistence.Version; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "general_scope_code") +@JsonIgnoreProperties(ignoreUnknown = false) +@Data +@EqualsAndHashCode(callSuper = false) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class GeneralScopeCodeEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "general_scope_code") + @NotNull + private String generalScopeCode; + + @NotNull + @Column(name = "description", length = 200) + private String description; + + @Column(name = "display_order", length = 3) + private Integer displayOrder; + + @NotNull + @Column(name = "effective_date", length = 200) + private Date effectiveDate; + + @NotNull + @Column(name = "expiry_date", length = 200) + private Date expiryDate; + + @Column(name = "revision_count", columnDefinition="Decimal(10) default '0'") + @NotNull + @Version + private Integer revisionCount; + + @CreatedBy + @NotNull + @Column(name="create_user", length = 64) + private String createUser; + + @CreatedDate + @NotNull + @Column(name="create_date") + private Date createDate; + + @LastModifiedBy + @NotNull + @Column(name="update_user", length = 64) + private String updateUser; + + @LastModifiedDate + @NotNull + @Column(name="update_date") + private Date updateDate; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProgramAreaEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProgramAreaEntity.java new file mode 100644 index 000000000..36574c116 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProgramAreaEntity.java @@ -0,0 +1,71 @@ +package ca.bc.gov.nrs.wfprev.data.model; + +import java.io.Serializable; +import java.util.Date; + +import org.hibernate.annotations.UuidGenerator; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.Version; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "program_area") +@JsonIgnoreProperties(ignoreUnknown = false) +@Data +@EqualsAndHashCode(callSuper = false) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProgramAreaEntity implements Serializable { + @Id + @UuidGenerator + @GeneratedValue(strategy = GenerationType.UUID) + @Column(name = "program_area_guid") + private String programAreaGuid; + + @NotNull + @Column(name="program_area_name", length = 100) + private String programAreaName; + + @Column(name = "revision_count", columnDefinition="Decimal(10) default '0'") + @NotNull + @Version + private Integer revisionCount; + + @CreatedBy + @NotNull + @Column(name="create_user", length = 64) + private String createUser; + + @CreatedDate + @NotNull + @Column(name="create_date") + private Date createDate; + + @LastModifiedBy + @NotNull + @Column(name="update_user", length = 64) + private String updateUser; + + @LastModifiedDate + @NotNull + @Column(name="update_date") + private Date updateDate; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectEntity.java new file mode 100644 index 000000000..95157b231 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectEntity.java @@ -0,0 +1,175 @@ +package ca.bc.gov.nrs.wfprev.data.model; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +import org.hibernate.annotations.UuidGenerator; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import ca.bc.gov.nrs.wfprev.common.converters.BooleanConverter; +import ca.bc.gov.nrs.wfprev.common.validators.Latitude; +import ca.bc.gov.nrs.wfprev.common.validators.Longitude; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.Version; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "project") +@JsonIgnoreProperties(ignoreUnknown = false) +@Data +@EqualsAndHashCode(callSuper = false) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProjectEntity implements Serializable { + @Id + @UuidGenerator + @GeneratedValue(strategy = GenerationType.UUID) + @Column(name = "project_guid") + private String projectGuid; + + //@NotFound(action = NotFoundAction.IGNORE) + //@RestResource(exported = false) + //@ManyToOne(fetch = FetchType.LAZY, optional = true, cascade = CascadeType.REFRESH) + //@JoinColumn(name="project_type_code") + @Column(name="project_type_code") + private String projectTypeCode; + + @Column(name = "project_number", columnDefinition="Decimal(10)") + @NotNull + private Integer projectNumber; + + @NotNull + @Column(name="site_unit_name", length = 250) + private String siteUnitName; + + //@NotFound(action = NotFoundAction.IGNORE) + //@RestResource(exported = false) + //@ManyToOne(fetch = FetchType.LAZY, optional = true, cascade = CascadeType.REFRESH) + //@JoinColumn(name="forest_area_code") + @Column(name="forest_area_code") + private String forestAreaCode; + + //@NotFound(action = NotFoundAction.IGNORE) + //@RestResource(exported = false) + //@ManyToOne(fetch = FetchType.LAZY, optional = true, cascade = CascadeType.REFRESH) + //@JoinColumn(name="general_scope_code") + @Column(name="general_scope_code") + private String generalScopeCode; + + @Column(name = "program_area_guid") + @NotNull + private String programAreaGuid; + + @Column(name = "forest_region_org_unit_id", columnDefinition="Decimal(10)") + private Integer forestRegionOrgUnitId; + + @Column(name = "forest_district_org_unit_id", columnDefinition="Decimal(10)") + private Integer forestDistrictOrgUnitId; + + @Column(name = "fire_centre_org_unit_id", columnDefinition="Decimal(10)") + private Integer fireCentreOrgUnitId; + + @Column(name = "bc_parks_region_org_unit_id", columnDefinition="Decimal(10)") + private Integer bcParksRegionOrgUnitId; + + @Column(name = "bcParksSectionOrgUnitId", columnDefinition="Decimal(10)") + private Integer bcParksSectionOrgUnitId; + + @NotNull + @Column(name="project_name", length = 300) + private String projectName; + + @Column(name="project_lead", length = 300) + private String projectLead; + + @Column(name="project_lead_email_address", length = 100) + private String projectLeadEmailAddress; + + @Column(name="project_description", length = 4000) + private String projectDescription; + + @Column(name="closest_community_name", length = 250) + private String closestCommunityName; + + @Column(name = "total_funding_request_amount", precision = 15, scale = 2) + private BigDecimal totalFundingRequestAmount; + + @Column(name = "total_allocated_amount", precision = 15, scale = 2) + private BigDecimal totalAllocatedAmount; + + @Column(name = "total_planned_project_size_ha", columnDefinition="Decimal(15, 4) default '0'") + private BigDecimal totalPlannedProjectSizeHa; + + @Column(name = "total_planned_cost_per_hectare", columnDefinition="Decimal(15, 2) default '0'") + private BigDecimal totalPlannedCostPerHectare; + + @NotNull + @Column(name = "total_actual_amount", columnDefinition="Decimal(15, 2) default '0'") + private BigDecimal totalActualAmount; + + @Column(name = "total_project_size_ha", columnDefinition="Decimal(15, 4) default '0'") + private BigDecimal totalProjectSizeHa; + + @Column(name = "total_cost_per_hectare_amount", columnDefinition="Decimal(15, 2) default '0'") + private BigDecimal totalCostPerHectareAmount; + + @NotNull + @Column(name = "is_multi_fiscal_year_proj_ind") + @Convert(converter = BooleanConverter.class) + @Builder.Default + private Boolean isMultiFiscalYearProj = false; + + @Column(name = "latitude", precision = 9, scale = 6) + @Latitude + private Double latitude; + + @Column(name = "longitude", precision = 9, scale = 6) + @Longitude + private Double longitude; + + @Column(name="last_progress_update_timestamp") + private Date lastProgressUpdateTimestamp; + + @Column(name = "revision_count", columnDefinition="Decimal(10) default '0'") + @NotNull + @Version + private Integer revisionCount; + + @CreatedBy + @NotNull + @Column(name="create_user", length = 64) + private String createUser; + + @CreatedDate + @NotNull + @Column(name="create_date") + private Date createDate; + + @LastModifiedBy + @NotNull + @Column(name="update_user", length = 64) + private String updateUser; + + @LastModifiedDate + @NotNull + @Column(name="update_date") + private Date updateDate; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ExampleRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ExampleRepository.java deleted file mode 100644 index 61f9982ed..000000000 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ExampleRepository.java +++ /dev/null @@ -1,31 +0,0 @@ -package ca.bc.gov.nrs.wfprev.data.repositories; - -import java.util.UUID; - -import org.springframework.data.rest.core.annotation.RepositoryRestResource; - -import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; -import ca.bc.gov.nrs.wfprev.data.model.ExampleEntity; - -/** - * Example repository rest resource - * If you use "Exported = false", it will disable the autogenerated "endpoints" that - * are accessible in a resful way, and you can use this Repository in a Controller - * This is the standard pattern we'd prefer - * - * if you set a path, and exported = true (the default), all of the standard JPA functions - * and any custom ones you define here, will be exposed as endpoints. This can have some - * advantages, but it also leads to some confusion on where endpoints are defined so its - * generally easier to understand it via a Controller - * - * Search/query methods added here will be accessible wherever you use the repository, so this - * is a great place to put standard jpaQueries (like the one that exists on CommonRepository already) - * - * Note, if you want to use myBatis instead, you won't need this stuff. - */ - -//@RepositoryRestResource(collectionResourceRel="example", path="example") -@RepositoryRestResource(exported = false) -public interface ExampleRepository extends CommonRepository { - -} \ No newline at end of file diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ForestAreaCodeRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ForestAreaCodeRepository.java new file mode 100644 index 000000000..c4f3c1368 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ForestAreaCodeRepository.java @@ -0,0 +1,11 @@ +package ca.bc.gov.nrs.wfprev.data.repositories; + +import org.springframework.data.rest.core.annotation.RepositoryRestResource; + +import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; +import ca.bc.gov.nrs.wfprev.data.model.ForestAreaCodeEntity; + +@RepositoryRestResource(exported = false) +public interface ForestAreaCodeRepository extends CommonRepository { + +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/GeneralScopeCodeRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/GeneralScopeCodeRepository.java new file mode 100644 index 000000000..da808cc3a --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/GeneralScopeCodeRepository.java @@ -0,0 +1,10 @@ +package ca.bc.gov.nrs.wfprev.data.repositories; + +import ca.bc.gov.nrs.wfprev.data.model.GeneralScopeCodeEntity; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; +import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; + +@RepositoryRestResource(exported = false) +public interface GeneralScopeCodeRepository extends CommonRepository { + +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ExampleCodeRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProgramAreaRepository.java similarity index 61% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ExampleCodeRepository.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProgramAreaRepository.java index 5c72168bb..0576e2696 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ExampleCodeRepository.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProgramAreaRepository.java @@ -1,11 +1,10 @@ package ca.bc.gov.nrs.wfprev.data.repositories; +import ca.bc.gov.nrs.wfprev.data.model.ProgramAreaEntity; import org.springframework.data.rest.core.annotation.RepositoryRestResource; - import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; -import ca.bc.gov.nrs.wfprev.data.model.ExampleCodeEntity; @RepositoryRestResource(exported = false) -public interface ExampleCodeRepository extends CommonRepository { +public interface ProgramAreaRepository extends CommonRepository { } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectRepository.java new file mode 100644 index 000000000..fc882d8bd --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectRepository.java @@ -0,0 +1,10 @@ +package ca.bc.gov.nrs.wfprev.data.repositories; + +import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; +import ca.bc.gov.nrs.wfprev.data.model.ProjectEntity; + +@RepositoryRestResource(exported = false) +public interface ProjectRepository extends CommonRepository { + +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ExampleModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ExampleModel.java deleted file mode 100644 index ebd0a6854..000000000 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ExampleModel.java +++ /dev/null @@ -1,53 +0,0 @@ -package ca.bc.gov.nrs.wfprev.data.resources; - -import java.math.BigDecimal; -import java.util.Date; -import java.util.UUID; - -import org.springframework.hateoas.server.core.Relation; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonRootName; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -import ca.bc.gov.nrs.wfprev.common.entities.CommonModel; -import ca.bc.gov.nrs.wfprev.data.model.ExampleCodeEntity; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; - -/** - * The Resource model for objects - * It's annoying to have an Entity model and a resource model as it feels like - * a double-implementation of the same thing, but this can be really important - * if you want your resource model to behave or be structured differently than - * the data model represented in the "model" objects. They also serve two different - * purposes. This model is Java->json representation out to the consumer requesting - * data. The model is Java->db representation and has definitions specific to - * JPA and working with the data. You can keep your json and data rules - * and implementation seperate this way - */ -@Data -@EqualsAndHashCode(callSuper = false) -@JsonRootName(value = "example") -@Relation(collectionRelation = "examples") -@JsonInclude(Include.NON_NULL) -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class ExampleModel extends CommonModel { - private String exampleGuid; - private String exampleCode; - private String exampleText; - private String exampleVar; - private BigDecimal exampleNum; - private Boolean exampleInd; - private Long lastUpdatedTimestamp; - private Integer revisionCount; - private String createdBy; - private Date createDate; - private String updatedBy; - private Date updateDate; -} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ForestAreaCodeModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ForestAreaCodeModel.java new file mode 100644 index 000000000..435a2dd81 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ForestAreaCodeModel.java @@ -0,0 +1,33 @@ +package ca.bc.gov.nrs.wfprev.data.resources; + +import java.util.Date; + +import org.springframework.hateoas.server.core.Relation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonRootName; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import ca.bc.gov.nrs.wfprev.common.entities.CommonModel; + +@Data +@EqualsAndHashCode(callSuper = false) +@JsonRootName(value = "forestAreaCode") +@Relation(collectionRelation = "forestAreaCode") +@JsonInclude(Include.NON_NULL) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ForestAreaCodeModel extends CommonModel { + private String forestAreaCode; + private String description; + private Integer displayOrder; + private Date effectiveDate; + private Date expiryDate; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ExampleCodeModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/GeneralScopeCodeModel.java similarity index 61% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ExampleCodeModel.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/GeneralScopeCodeModel.java index f9e78549e..c108d0768 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ExampleCodeModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/GeneralScopeCodeModel.java @@ -2,37 +2,31 @@ import java.util.Date; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; +import org.springframework.hateoas.server.core.Relation; import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonRootName; import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonRootName; import ca.bc.gov.nrs.wfprev.common.entities.CommonModel; - -import org.springframework.hateoas.server.core.Relation; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; @Data @EqualsAndHashCode(callSuper = false) -@JsonRootName(value = "exampleCode") -@Relation(collectionRelation = "exampleCodes") +@JsonRootName(value = "generalScopeCode") +@Relation(collectionRelation = "generalScopeCode") @JsonInclude(Include.NON_NULL) @Builder @AllArgsConstructor @NoArgsConstructor -public class ExampleCodeModel extends CommonModel { - private String exampleCode; +public class GeneralScopeCodeModel extends CommonModel { + private String generalScopeCode; private String description; - private Integer displayOrder; - private Date effectiveDate; - private Date expiryDate; - private Integer revisionCount; - private String createdBy; - private Date createDate; - private String updatedBy; - private Date updateDate; + private Integer displayOrder; + private Date effectiveDate; + private Date expiryDate; } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProgramAreaModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProgramAreaModel.java new file mode 100644 index 000000000..a2ce6bc44 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProgramAreaModel.java @@ -0,0 +1,27 @@ +package ca.bc.gov.nrs.wfprev.data.resources; + +import org.springframework.hateoas.server.core.Relation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +import ca.bc.gov.nrs.wfprev.common.entities.CommonModel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Data +@EqualsAndHashCode(callSuper = false) +@JsonRootName(value = "programArea") +@Relation(collectionRelation = "programArea") +@JsonInclude(Include.NON_NULL) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProgramAreaModel extends CommonModel { + private String programAreaGuid; + private String programAreaName; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectModel.java new file mode 100644 index 000000000..2ef34e2a5 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectModel.java @@ -0,0 +1,56 @@ +package ca.bc.gov.nrs.wfprev.data.resources; + +import java.math.BigDecimal; +import java.util.Date; + +import org.springframework.hateoas.server.core.Relation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +import ca.bc.gov.nrs.wfprev.common.entities.CommonModel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Data +@EqualsAndHashCode(callSuper = false) +@JsonRootName(value = "programArea") +@Relation(collectionRelation = "programArea") +@JsonInclude(Include.NON_NULL) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProjectModel extends CommonModel { + private String projectGuid; + private String projectTypeCode; // CODE + private Integer projectNumber; + private String siteUnitName; + private String forestAreaCode; // CODE + private String generalScopeCode; // CODE + private String programAreaGuid; // FK + private Integer forestRegionOrgUnitId; + private Integer forestDistrictOrgUnitId; + private Integer fireCentreOrgUnitId; + private Integer bcParksRegionOrgUnitId; + private Integer bcParksSectionOrgUnitId; + private String projectName; + private String projectLead; + private String projectLeadEmailAddress; + private String projectDescription; + private String closestCommunityName; + private BigDecimal totalFundingRequestAmount; + private BigDecimal totalAllocatedAmount; + private BigDecimal totalPlannedProjectSizeHa; + private BigDecimal totalPlannedCostPerHectare; + private BigDecimal totalActualAmount; + private BigDecimal totalProjectSizeHa; + private BigDecimal totalCostPerHectareAmount; + private Boolean isMultiFiscalYearProj; + private Double latitude; + private Double longitude; + private Date lastProgressUpdateTimestamp; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java new file mode 100644 index 000000000..29043111a --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java @@ -0,0 +1,72 @@ +package ca.bc.gov.nrs.wfprev.services; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.stereotype.Component; + +import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; +import ca.bc.gov.nrs.wfprev.common.services.CommonService; +import ca.bc.gov.nrs.wfprev.data.assemblers.ForestAreaCodeResourceAssembler; +import ca.bc.gov.nrs.wfprev.data.assemblers.GeneralScopeCodeResourceAssembler; +import ca.bc.gov.nrs.wfprev.data.model.ForestAreaCodeEntity; +import ca.bc.gov.nrs.wfprev.data.model.GeneralScopeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.repositories.ForestAreaCodeRepository; +import ca.bc.gov.nrs.wfprev.data.repositories.GeneralScopeCodeRepository; +import ca.bc.gov.nrs.wfprev.data.resources.ForestAreaCodeModel; +import ca.bc.gov.nrs.wfprev.data.resources.GeneralScopeCodeModel; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class CodesService implements CommonService { + private ForestAreaCodeRepository forestAreaCodeRepository; + private ForestAreaCodeResourceAssembler forestAreaCodeResourceAssembler; + private GeneralScopeCodeRepository generalScopeCodeRepository; + private GeneralScopeCodeResourceAssembler generalScopeCodeResourceAssembler; + + public CodesService(ForestAreaCodeRepository forestAreaCodeRepository, ForestAreaCodeResourceAssembler forestAreaCodeResourceAssembler, + GeneralScopeCodeRepository generalScopeCodeRepository, GeneralScopeCodeResourceAssembler generalScopeCodeResourceAssembler) { + this.forestAreaCodeRepository = forestAreaCodeRepository; + this.forestAreaCodeResourceAssembler = forestAreaCodeResourceAssembler; + this.generalScopeCodeRepository = generalScopeCodeRepository; + this.generalScopeCodeResourceAssembler = generalScopeCodeResourceAssembler; + } + + /** FOREST AREA CODES **/ + public CollectionModel getAllForestAreaCodes() throws ServiceException { + try { + List entities = new ArrayList<>(); + return forestAreaCodeResourceAssembler.toCollectionModel(entities); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + public ForestAreaCodeModel getForestAreaCodeById(String id) throws ServiceException { + try { + return forestAreaCodeRepository.findById(id).map(forestAreaCodeResourceAssembler::toModel).orElse(null); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + /** GENERAL SCOPE CODES **/ + public CollectionModel getAllGeneralScopeCodes() throws ServiceException { + try { + List entities = new ArrayList<>(); + return generalScopeCodeResourceAssembler.toCollectionModel(entities); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + public GeneralScopeCodeModel getGeneralScopeCodeById(String id) throws ServiceException { + try { + return generalScopeCodeRepository.findById(id).map(generalScopeCodeResourceAssembler::toModel).orElse(null); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ExampleService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ExampleService.java deleted file mode 100644 index b69cb1f92..000000000 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ExampleService.java +++ /dev/null @@ -1,105 +0,0 @@ -package ca.bc.gov.nrs.wfprev.services; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import org.springframework.hateoas.CollectionModel; -import org.springframework.stereotype.Component; - -import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; -import ca.bc.gov.nrs.wfprev.common.services.CommonService; -import ca.bc.gov.nrs.wfprev.data.assemblers.ExampleCodeResourceAssembler; -import ca.bc.gov.nrs.wfprev.data.assemblers.ExampleResourceAssembler; -import ca.bc.gov.nrs.wfprev.data.model.ExampleCodeEntity; -import ca.bc.gov.nrs.wfprev.data.model.ExampleEntity; -import ca.bc.gov.nrs.wfprev.data.repositories.ExampleCodeRepository; -import ca.bc.gov.nrs.wfprev.data.repositories.ExampleRepository; -import ca.bc.gov.nrs.wfprev.data.resources.ExampleCodeModel; -import ca.bc.gov.nrs.wfprev.data.resources.ExampleModel; -import jakarta.transaction.Transactional; -import lombok.extern.slf4j.Slf4j; - -/** - * Service implementation. Services should map nearly 1:1 with your controllers, and act - * as the "business logic" layer to your controller. Ideally we can keep this split up - * by resource/endpoint so a single service doesn't wind up getting insanely large. - * Other services can communicate with each other, so autowire sercvices together - * where needed. - * - * Note: If you make a service and don't implement CommonService, be sure to add - * the @Component annotation if you intend to autowire this anywhere else. - */ -@Slf4j -@Component -public class ExampleService implements CommonService { - /* The Repository Objects used in this Service */ - private ExampleRepository exampleRepository; - private ExampleCodeRepository exampleCodeRepository; - /* The resource assemblers. Use this to convert Entity to Resource and vice-versa */ - private ExampleResourceAssembler exampleResourceAssembler; - private ExampleCodeResourceAssembler exampleCodeResourceAssembler; - - public ExampleService(ExampleRepository exampleRepository, ExampleCodeRepository exampleCodeRepository, ExampleResourceAssembler exampleResourceAssembler, ExampleCodeResourceAssembler exampleCodeResourceAssembler) { - this.exampleRepository = exampleRepository; - this.exampleCodeRepository = exampleCodeRepository; - this.exampleResourceAssembler = exampleResourceAssembler; - this.exampleCodeResourceAssembler = exampleCodeResourceAssembler; - } - - public CollectionModel getAllExamples() throws ServiceException { - try { - // List entities = exampleRepository.findAll(); - List entities = new ArrayList<>(); - return exampleResourceAssembler.toCollectionModel(entities); - } catch(Exception e) { - throw new ServiceException(e.getLocalizedMessage(), e); - } - } - - public ExampleModel getExampleById(String id) throws ServiceException { - try {ExampleModel exampleModel = new ExampleModel(); - exampleModel.setExampleGuid(id); - return exampleModel; - // return exampleRepository.findById(id).map(exampleResourceAssembler::toModel).orElse(null); - } catch(Exception e) { - throw new ServiceException(e.getLocalizedMessage(), e); - } - } - - @Transactional - public ExampleModel createOrUpdateExample(ExampleModel resource) throws ServiceException { - try { - resource.setLastUpdatedTimestamp(new Date().getTime()); - resource.setUpdateDate(new Date()); - - ExampleEntity oldEntity = exampleResourceAssembler.toEntity(resource); - // ExampleEntity newEntity = exampleRepository.saveAndFlush(oldEntity); - - return exampleResourceAssembler.toModel(oldEntity); - } catch(Exception e) { - throw new ServiceException(e.getLocalizedMessage(), e); - } - } - - public CollectionModel getAllExampleCodes() throws ServiceException { - try { - // List entities = exampleCodeRepository.findAll(); - List entities = new ArrayList<>(); - return exampleCodeResourceAssembler.toCollectionModel(entities); - } catch(Exception e) { - throw new ServiceException(e.getLocalizedMessage(), e); - } - } - - public ExampleCodeModel getExampleCodeById(String id) throws ServiceException { - try { - ExampleCodeModel exampleCodeModel = new ExampleCodeModel(); - exampleCodeModel.setExampleCode(id); - return exampleCodeModel; - // return exampleCodeRepository.findById(id).map(exampleCodeResourceAssembler::toModel).orElse(null); - } catch(Exception e) { - throw new ServiceException(e.getLocalizedMessage(), e); - } - } -} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProgramAreaService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProgramAreaService.java new file mode 100644 index 000000000..ca9d8b74f --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProgramAreaService.java @@ -0,0 +1,74 @@ +package ca.bc.gov.nrs.wfprev.services; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.stereotype.Component; + +import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; +import ca.bc.gov.nrs.wfprev.common.services.CommonService; +import ca.bc.gov.nrs.wfprev.data.assemblers.ProgramAreaResourceAssembler; +import ca.bc.gov.nrs.wfprev.data.model.ProgramAreaEntity; +import ca.bc.gov.nrs.wfprev.data.repositories.ProgramAreaRepository; +import ca.bc.gov.nrs.wfprev.data.resources.ProgramAreaModel; +import jakarta.transaction.Transactional; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class ProgramAreaService implements CommonService { + private ProgramAreaRepository programAreaRepository; + private ProgramAreaResourceAssembler programAreaResourceAssembler; + + public ProgramAreaService(ProgramAreaRepository programAreaRepository, ProgramAreaResourceAssembler programAreaResourceAssembler) { + this.programAreaRepository = programAreaRepository; + this.programAreaResourceAssembler = programAreaResourceAssembler; + } + + public CollectionModel getAllProgramAreas() throws ServiceException { + try { + List entities = new ArrayList<>(); + return programAreaResourceAssembler.toCollectionModel(entities); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + public ProgramAreaModel getProgramAreaById(String id) throws ServiceException { + try { + return programAreaRepository.findById(id).map(programAreaResourceAssembler::toModel).orElse(null); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + @Transactional + public ProgramAreaModel createOrUpdateProgramArea(ProgramAreaModel resource) throws ServiceException { + try { + resource.setUpdateDate(new Date()); + + ProgramAreaEntity oldEntity = programAreaResourceAssembler.toEntity(resource); + ProgramAreaEntity newEntity = programAreaRepository.saveAndFlush(oldEntity); + + return programAreaResourceAssembler.toModel(newEntity); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + @Transactional + public ProgramAreaModel deleteProgramArea(String id) throws ServiceException { + try { + ProgramAreaModel model = getProgramAreaById(id); + + ProgramAreaEntity entity = programAreaResourceAssembler.toEntity(model); + programAreaRepository.delete(entity); + + return programAreaResourceAssembler.toModel(entity); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java new file mode 100644 index 000000000..9c57c23c8 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java @@ -0,0 +1,75 @@ +package ca.bc.gov.nrs.wfprev.services; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.stereotype.Component; + +import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; +import ca.bc.gov.nrs.wfprev.common.services.CommonService; +import ca.bc.gov.nrs.wfprev.data.assemblers.ProjectResourceAssembler; +import ca.bc.gov.nrs.wfprev.data.model.ProjectEntity; +import ca.bc.gov.nrs.wfprev.data.repositories.ProjectRepository; +import ca.bc.gov.nrs.wfprev.data.resources.ProjectModel; +import jakarta.transaction.Transactional; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class ProjectService implements CommonService { + private ProjectRepository projectRepository; + private ProjectResourceAssembler projectResourceAssembler; + + public ProjectService(ProjectRepository projectRepository, ProjectResourceAssembler projectResourceAssembler) { + this.projectRepository = projectRepository; + this.projectResourceAssembler = projectResourceAssembler; + } + + public CollectionModel getAllProjects() throws ServiceException { + try { + List entities = new ArrayList<>(); + return projectResourceAssembler.toCollectionModel(entities); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + public ProjectModel getProjectById(String id) throws ServiceException { + try { + return projectRepository.findById(id).map(projectResourceAssembler::toModel).orElse(null); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + @Transactional + public ProjectModel createOrUpdateProject(ProjectModel resource) throws ServiceException { + try { + resource.setUpdateDate(new Date()); + + ProjectEntity oldEntity = projectResourceAssembler.toEntity(resource); + ProjectEntity newEntity = projectRepository.saveAndFlush(oldEntity); + + return projectResourceAssembler.toModel(newEntity); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + @Transactional + public ProjectModel deleteProject(String id) throws ServiceException { + try { + ProjectModel model = getProjectById(id); + + ProjectEntity entity = projectResourceAssembler.toEntity(model); + projectRepository.delete(entity); + + return projectResourceAssembler.toModel(entity); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } +} + From 764d581b514668b4f5f5a5ceafa6bd92fb39ab0f Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Thu, 21 Nov 2024 14:00:57 -0800 Subject: [PATCH 02/15] Add project boundary, geometry configs --- .../ProjectBoundaryController.java | 186 ++++++++++++++++++ .../wfprev/controllers/ProjectController.java | 26 +-- .../ProjectBoundaryResourceAssembler.java | 85 ++++++++ .../assemblers/ProjectResourceAssembler.java | 1 + .../data/model/ProjectBoundaryEntity.java | 118 +++++++++++ .../ProjectBoundaryRepository.java | 10 + .../data/resources/ProjectBoundaryModel.java | 42 ++++ .../wfprev/data/resources/ProjectModel.java | 4 +- .../services/ProjectBoundaryService.java | 74 +++++++ 9 files changed, 531 insertions(+), 15 deletions(-) create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectBoundaryResourceAssembler.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectBoundaryEntity.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectBoundaryRepository.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectBoundaryModel.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectBoundaryService.java diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java new file mode 100644 index 000000000..c411a1b1d --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java @@ -0,0 +1,186 @@ +package ca.bc.gov.nrs.wfprev.controllers; + +import java.util.Date; +import java.util.UUID; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.http.ResponseEntity; +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 ca.bc.gov.nrs.common.wfone.rest.resource.HeaderConstants; +import ca.bc.gov.nrs.common.wfone.rest.resource.MessageListRsrc; +import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; +import ca.bc.gov.nrs.wfprev.common.controllers.CommonController; +import ca.bc.gov.nrs.wfprev.data.resources.ProjectBoundaryModel; +import ca.bc.gov.nrs.wfprev.services.ProjectBoundaryService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.extensions.Extension; +import io.swagger.v3.oas.annotations.extensions.ExtensionProperty; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import lombok.extern.slf4j.Slf4j; + +@RestController +@Slf4j +@RequestMapping(value="/projectBoundaries") +public class ProjectBoundaryController extends CommonController { + private ProjectBoundaryService projectBoundaryService; + + public ProjectBoundaryController(ProjectBoundaryService projectBoundaryService) { + super(ProjectBoundaryController.class.getName()); + this.projectBoundaryService = projectBoundaryService; + } + + @GetMapping("/") + @Operation(summary = "Fetch all Project Boundary Resources", + description = "Fetch all Project Boundary Resources", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = CollectionModel.class))), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity> getAllProjectBoundaries() { + log.debug(" >> getAllProjectBoundaries"); + ResponseEntity> response; + + try { + response = ok(projectBoundaryService.getAllProjectBoundaries()); + } catch (ServiceException e) { + response = internalServerError(); + log.error(" ### Error while fetching Projects", e); + } + + log.debug(" << getAllProjectBoundaries"); + return response; + } + + @GetMapping("/{id}") + @Operation(summary = "Fetch project boundary by ID", + description = "Fetch project boundary by ID", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProjectBoundaryModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity getById(@PathVariable("id") String id) { + log.debug(" >> getById {}", id); + ResponseEntity response; + + try { + ProjectBoundaryModel resource = projectBoundaryService.getProjectBoundaryById(id); + response = resource == null ? notFound() : ok(resource); + } catch(ServiceException e) { + response = internalServerError(); + log.error(" ### Error while fetching project {}", id, e); + } + + log.debug(" << getById"); + return response; + } + + @PostMapping("/") + @Operation(summary = "Create a project boundary Resource", + description = "Create a project boundary Resource", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "OK", content = @Content(schema = @Schema(implementation = ProjectBoundaryModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity createProjectBoundary(@RequestBody ProjectBoundaryModel resource) { + log.debug(" >> createProjectBoundary"); + ResponseEntity response; + + try { + // set the default values for a newly created resource + resource.setCreateDate(new Date()); + resource.setCreateUser(getWebAdeAuthentication().getUserId()); + resource.setUpdateUser(getWebAdeAuthentication().getUserId()); + resource.setRevisionCount(0); + resource.setProjectBoundaryGuid(UUID.randomUUID().toString()); + + ProjectBoundaryModel newResource = projectBoundaryService.createOrUpdateProjectBoundary(resource); + response = newResource == null ? badRequest() : created(newResource); + } catch(ServiceException e) { + response = internalServerError(); + log.error(" ### Error while creating resource", e); + } + + log.debug(" << createProjectBoundary"); + return response; + } + + @PutMapping("/{id}") + @Operation(summary = "Update Project Boundary Resource", + description = "Update Project Boundary Resource", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProjectBoundaryModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity updateProjectBoundary(@RequestBody ProjectBoundaryModel resource, @PathVariable("id") String id) { + log.debug(" >> updateProjectBoundary"); + ResponseEntity response; + + try { + // Update the UpdatedBy + resource.setUpdateUser(getWebAdeAuthentication().getUserId()); + // ensure that the user hasn't changed the primary key + if (id.equalsIgnoreCase(resource.getProjectBoundaryGuid())) { + ProjectBoundaryModel updatedResource = projectBoundaryService.createOrUpdateProjectBoundary(resource); + response = updatedResource == null ? badRequest() : ok(updatedResource); + } else { + response = badRequest(); + } + } catch(ServiceException e) { + // most responses here will actually be Bad Requests, not Internal Server Errors + // This would be an ideal place to expand the "Catch" and return sensible + // HTTP status codes + response = internalServerError(); + log.error(" ### Error while updating Program Area", e); + } + + log.debug(" << updateProjectBoundary"); + return response; + } + + @DeleteMapping("/{id}") + @Operation(summary = "Delete Project Boundary Resource", + description = "Delete Project Boundary Resource", + security = @SecurityRequirement(name = "Webade-OAUTH2", + scopes = { "WFPREV" }), + extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) + @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = ProjectBoundaryModel.class)), headers = { @Header(name = "ETag", description = "The ETag response-header field provides the current value of the entity tag for the requested variant.", schema = @Schema(implementation = String.class)) }), @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))), @ApiResponse(responseCode = "403", description = "Forbidden"), @ApiResponse(responseCode = "404", description = "Not Found"), @ApiResponse(responseCode = "409", description = "Conflict"), @ApiResponse(responseCode = "412", description = "Precondition Failed"), @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(schema = @Schema(implementation = MessageListRsrc.class))) }) + @Parameters({ @Parameter(name = HeaderConstants.VERSION_HEADER, description = HeaderConstants.VERSION_HEADER_DESCRIPTION, required = false, schema = @Schema(implementation = Integer.class), in = ParameterIn.HEADER), @Parameter(name = HeaderConstants.IF_MATCH_HEADER, description = HeaderConstants.IF_MATCH_DESCRIPTION, required = true, schema = @Schema(implementation = String.class), in = ParameterIn.HEADER) }) + public ResponseEntity deleteProjectBoundary(@PathVariable("id") String id) { + log.debug(" >> deleteProjectBoundary"); + ResponseEntity response; + + try { + ProjectBoundaryModel resource = projectBoundaryService.deleteProjectBoundary(id); + response = resource == null ? badRequest() : ok(resource); + } catch(ServiceException e) { + // most responses here will actually be Bad Requests, not Internal Server Errors + // This would be an ideal place to expand the "Catch" and return sensible + // HTTP status codes + response = internalServerError(); + log.error(" ### Error while updating Project Boundary", e); + } + + log.debug(" << deleteProjectBoundary"); + return response; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java index 5ebb6760d..f5beefa76 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java @@ -46,8 +46,8 @@ public ProjectController(ProjectService projectService) { } @GetMapping("/") - @Operation(summary = "Fetch all Program Area Resources", - description = "Fetch all Program Area Resources", + @Operation(summary = "Fetch all Project Resources", + description = "Fetch all Project Resources", security = @SecurityRequirement(name = "Webade-OAUTH2", scopes = { "WFPREV" }), extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) @@ -69,8 +69,8 @@ public ResponseEntity> getAllProjects() { } @GetMapping("/{id}") - @Operation(summary = "Fetch program area by ID", - description = "Fetch program area by ID", + @Operation(summary = "Fetch Project by ID", + description = "Fetch Project by ID", security = @SecurityRequirement(name = "Webade-OAUTH2", scopes = { "WFPREV" }), extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) @@ -93,8 +93,8 @@ public ResponseEntity getById(@PathVariable("id") String id) { } @PostMapping("/") - @Operation(summary = "Create a Program Area Resource", - description = "Create a Program Area Resource", + @Operation(summary = "Create a Project Resource", + description = "Create a Project Resource", security = @SecurityRequirement(name = "Webade-OAUTH2", scopes = { "WFPREV" }), extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) @@ -124,8 +124,8 @@ public ResponseEntity createProject(@RequestBody ProjectModel reso } @PutMapping("/{id}") - @Operation(summary = "Update Program Area Resource", - description = "Update Program Area Resource", + @Operation(summary = "Update Project Resource", + description = "Update Project Resource", security = @SecurityRequirement(name = "Webade-OAUTH2", scopes = { "WFPREV" }), extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) @@ -150,7 +150,7 @@ public ResponseEntity updateProject(@RequestBody ProjectModel reso // This would be an ideal place to expand the "Catch" and return sensible // HTTP status codes response = internalServerError(); - log.error(" ### Error while updating Program Area", e); + log.error(" ### Error while updating Project", e); } log.debug(" << updateProject"); @@ -158,8 +158,8 @@ public ResponseEntity updateProject(@RequestBody ProjectModel reso } @DeleteMapping("/{id}") - @Operation(summary = "Delete Program Area Resource", - description = "Delete Program Area Resource", + @Operation(summary = "Delete Project Resource", + description = "Delete Project Resource", security = @SecurityRequirement(name = "Webade-OAUTH2", scopes = { "WFPREV" }), extensions = { @Extension(properties = { @ExtensionProperty(name = "auth-type", value = "#{wso2.x-auth-type.app_and_app_user}"), @ExtensionProperty(name = "throttling-tier", value = "Unlimited") }) }) @@ -171,13 +171,13 @@ public ResponseEntity deleteProject(@PathVariable("id") String id) try { ProjectModel resource = projectService.deleteProject(id); - response = resource == null ? badRequest() : created(resource); + response = resource == null ? badRequest() : ok(resource); } catch(ServiceException e) { // most responses here will actually be Bad Requests, not Internal Server Errors // This would be an ideal place to expand the "Catch" and return sensible // HTTP status codes response = internalServerError(); - log.error(" ### Error while updating Program Area", e); + log.error(" ### Error while updating Project", e); } log.debug(" << deleteProject"); diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectBoundaryResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectBoundaryResourceAssembler.java new file mode 100644 index 000000000..e8bbda9e3 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectBoundaryResourceAssembler.java @@ -0,0 +1,85 @@ +package ca.bc.gov.nrs.wfprev.data.assemblers; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; +import org.springframework.stereotype.Component; + +import ca.bc.gov.nrs.wfprev.data.model.ProjectBoundaryEntity; +import ca.bc.gov.nrs.wfprev.controllers.ProjectBoundaryController; +import ca.bc.gov.nrs.wfprev.data.resources.ProjectBoundaryModel; + +@Component +public class ProjectBoundaryResourceAssembler extends RepresentationModelAssemblerSupport { + + public ProjectBoundaryResourceAssembler() { + super(ProjectBoundaryController.class, ProjectBoundaryModel.class); + } + + public ProjectBoundaryEntity toEntity(ProjectBoundaryModel resource) { + ProjectBoundaryEntity entity = new ProjectBoundaryEntity(); + + entity.setProjectBoundaryGuid(resource.getProjectBoundaryGuid()); + entity.setProjectGuid(resource.getProjectGuid()); + entity.setSystemStartTimestamp(resource.getSystemStartTimestamp()); + entity.setSystemEndTimestamp(resource.getSystemEndTimestamp()); + entity.setMappingLabel(resource.getMappingLabel()); + entity.setCollectionDate(resource.getCollectionDate()); + entity.setCollectionMethod(resource.getCollectionMethod()); + entity.setCollectorName(resource.getCollectorName()); + entity.setBoundarySizeHa(resource.getBoundarySizeHa()); + entity.setBoundaryComment(resource.getBoundaryComment()); + entity.setLocationGeometry(resource.getLocationGeometry()); + entity.setBoundaryGeometry(resource.getBoundaryGeometry()); + entity.setRevisionCount(resource.getRevisionCount()); + entity.setCreateUser(resource.getCreateUser()); + entity.setCreateDate(resource.getCreateDate()); + entity.setUpdateUser(resource.getUpdateUser()); + entity.setUpdateDate(resource.getUpdateDate()); + + return entity; + } + + @Override + public ProjectBoundaryModel toModel(ProjectBoundaryEntity entity) { + ProjectBoundaryModel resource = instantiateModel(entity); + + resource.add(linkTo( + methodOn(ProjectBoundaryController.class) + .getById(entity.getProjectBoundaryGuid())) + .withSelfRel()); + + resource.setProjectBoundaryGuid(entity.getProjectBoundaryGuid()); + resource.setProjectGuid(entity.getProjectGuid()); + resource.setSystemStartTimestamp(entity.getSystemStartTimestamp()); + resource.setSystemEndTimestamp(entity.getSystemEndTimestamp()); + resource.setMappingLabel(entity.getMappingLabel()); + resource.setCollectionDate(entity.getCollectionDate()); + resource.setCollectionMethod(entity.getCollectionMethod()); + resource.setCollectorName(entity.getCollectorName()); + resource.setBoundarySizeHa(entity.getBoundarySizeHa()); + resource.setBoundaryComment(entity.getBoundaryComment()); + resource.setLocationGeometry(entity.getLocationGeometry()); + resource.setBoundaryGeometry(entity.getBoundaryGeometry()); + resource.setRevisionCount(entity.getRevisionCount()); + resource.setRevisionCount(entity.getRevisionCount()); + resource.setCreateUser(entity.getCreateUser()); + resource.setCreateDate(entity.getCreateDate()); + resource.setUpdateUser(entity.getUpdateUser()); + resource.setUpdateDate(entity.getUpdateDate()); + + return resource; + } + + @Override + public CollectionModel toCollectionModel(Iterable entities) + { + CollectionModel resources = super.toCollectionModel(entities); + + resources.add(linkTo(methodOn(ProjectBoundaryController.class).getAllProjectBoundaries()).withSelfRel()); + + return resources; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java index ac299ca98..0a6a201e9 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java @@ -1,4 +1,5 @@ package ca.bc.gov.nrs.wfprev.data.assemblers; + import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectBoundaryEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectBoundaryEntity.java new file mode 100644 index 000000000..0a0d87c02 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectBoundaryEntity.java @@ -0,0 +1,118 @@ +package ca.bc.gov.nrs.wfprev.data.model; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +import org.hibernate.annotations.UuidGenerator; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.Point; + +import ca.bc.gov.nrs.common.wfone.rest.resource.transformers.GeoJsonJacksonDeserializer; +import ca.bc.gov.nrs.common.wfone.rest.resource.transformers.GeoJsonJacksonSerializer; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.Version; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "project_boundary") +@JsonIgnoreProperties(ignoreUnknown = false) +@Data +@EqualsAndHashCode(callSuper = false) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProjectBoundaryEntity implements Serializable { + @Id + @UuidGenerator + @GeneratedValue(strategy = GenerationType.UUID) + @Column(name = "project_boundary_guid") + private String projectBoundaryGuid; + + @Column(name = "project_guid") + @NotNull + private String projectGuid; + + @NotNull + @Column(name="system_start_timestamp") + private Date systemStartTimestamp; + + @NotNull + @Column(name="system_end_timestamp") + private Date systemEndTimestamp; + + @Column(name="mapping_label", length = 250) + private String mappingLabel; + + @NotNull + @Column(name="collection_date") + private Date collectionDate; + + @Column(name="collection_method", length = 4000) + private String collectionMethod; + + @Column(name="collector_name", length = 100) + private String collectorName; + + @NotNull + @Column(name = "boundary_size_ha", precision = 19, scale = 4) + private BigDecimal boundarySizeHa; + + @Column(name="boundary_comment", length = 2000) + private String boundaryComment; + + @NotNull + @JsonSerialize(using=GeoJsonJacksonSerializer.class) + @JsonDeserialize(using=GeoJsonJacksonDeserializer.class) + @Column(name="location_geometry", columnDefinition = "geometry(Point,4326)") + public Point locationGeometry; + + @NotNull + @JsonSerialize(using=GeoJsonJacksonSerializer.class) + @JsonDeserialize(using=GeoJsonJacksonDeserializer.class) + @Column(name="boundary_geometry", columnDefinition = "geometry(Geometry,4326)") + public Geometry boundaryGeometry; + + @Column(name = "revision_count", columnDefinition="Decimal(10) default '0'") + @NotNull + @Version + private Integer revisionCount; + + @CreatedBy + @NotNull + @Column(name="create_user", length = 64) + private String createUser; + + @CreatedDate + @NotNull + @Column(name="create_date") + private Date createDate; + + @LastModifiedBy + @NotNull + @Column(name="update_user", length = 64) + private String updateUser; + + @LastModifiedDate + @NotNull + @Column(name="update_date") + private Date updateDate; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectBoundaryRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectBoundaryRepository.java new file mode 100644 index 000000000..f820e1c7c --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectBoundaryRepository.java @@ -0,0 +1,10 @@ +package ca.bc.gov.nrs.wfprev.data.repositories; + +import ca.bc.gov.nrs.wfprev.data.model.ProjectBoundaryEntity; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; +import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; + +@RepositoryRestResource(exported = false) +public interface ProjectBoundaryRepository extends CommonRepository { + +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectBoundaryModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectBoundaryModel.java new file mode 100644 index 000000000..791ce30a3 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectBoundaryModel.java @@ -0,0 +1,42 @@ +package ca.bc.gov.nrs.wfprev.data.resources; + +import java.math.BigDecimal; +import java.util.Date; + +import org.springframework.hateoas.server.core.Relation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonRootName; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.Point; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +import ca.bc.gov.nrs.wfprev.common.entities.CommonModel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Data +@EqualsAndHashCode(callSuper = false) +@JsonRootName(value = "projectBoundary") +@Relation(collectionRelation = "projectBoundary") +@JsonInclude(Include.NON_NULL) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProjectBoundaryModel extends CommonModel { + private String projectBoundaryGuid; + private String projectGuid; + private Date systemStartTimestamp; + private Date systemEndTimestamp; + private String mappingLabel; + private Date collectionDate; + private String collectionMethod; + private String collectorName; + private BigDecimal boundarySizeHa; + private String boundaryComment; + private Point locationGeometry; + private Geometry boundaryGeometry; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectModel.java index 2ef34e2a5..6ef07d5fc 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectModel.java @@ -18,8 +18,8 @@ @Data @EqualsAndHashCode(callSuper = false) -@JsonRootName(value = "programArea") -@Relation(collectionRelation = "programArea") +@JsonRootName(value = "project") +@Relation(collectionRelation = "project") @JsonInclude(Include.NON_NULL) @Builder @AllArgsConstructor diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectBoundaryService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectBoundaryService.java new file mode 100644 index 000000000..234a98519 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectBoundaryService.java @@ -0,0 +1,74 @@ +package ca.bc.gov.nrs.wfprev.services; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.stereotype.Component; + +import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; +import ca.bc.gov.nrs.wfprev.common.services.CommonService; +import ca.bc.gov.nrs.wfprev.data.assemblers.ProjectBoundaryResourceAssembler; +import ca.bc.gov.nrs.wfprev.data.model.ProjectBoundaryEntity; +import ca.bc.gov.nrs.wfprev.data.repositories.ProjectBoundaryRepository; +import ca.bc.gov.nrs.wfprev.data.resources.ProjectBoundaryModel; +import jakarta.transaction.Transactional; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class ProjectBoundaryService implements CommonService { + private ProjectBoundaryRepository projectBoundaryRepository; + private ProjectBoundaryResourceAssembler projectBoundaryResourceAssembler; + + public ProjectBoundaryService(ProjectBoundaryRepository projectBoundaryRepository, ProjectBoundaryResourceAssembler projectBoundaryResourceAssembler) { + this.projectBoundaryRepository = projectBoundaryRepository; + this.projectBoundaryResourceAssembler = projectBoundaryResourceAssembler; + } + + public CollectionModel getAllProjectBoundaries() throws ServiceException { + try { + List entities = new ArrayList<>(); + return projectBoundaryResourceAssembler.toCollectionModel(entities); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + public ProjectBoundaryModel getProjectBoundaryById(String id) throws ServiceException { + try { + return projectBoundaryRepository.findById(id).map(projectBoundaryResourceAssembler::toModel).orElse(null); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + @Transactional + public ProjectBoundaryModel createOrUpdateProjectBoundary(ProjectBoundaryModel resource) throws ServiceException { + try { + resource.setUpdateDate(new Date()); + + ProjectBoundaryEntity oldEntity = projectBoundaryResourceAssembler.toEntity(resource); + ProjectBoundaryEntity newEntity = projectBoundaryRepository.saveAndFlush(oldEntity); + + return projectBoundaryResourceAssembler.toModel(newEntity); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + @Transactional + public ProjectBoundaryModel deleteProjectBoundary(String id) throws ServiceException { + try { + ProjectBoundaryModel model = getProjectBoundaryById(id); + + ProjectBoundaryEntity entity = projectBoundaryResourceAssembler.toEntity(model); + projectBoundaryRepository.delete(entity); + + return projectBoundaryResourceAssembler.toModel(entity); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } +} From df064ddb118a8b1f2c97b6ee8d81851a5b2f2026 Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Thu, 21 Nov 2024 14:20:30 -0800 Subject: [PATCH 03/15] Add Project Type Code --- .../nrs/wfprev/common/enums/CodeTables.java | 5 +- .../wfprev/controllers/CodesController.java | 7 ++ .../ProjectTypeCodeResourceAssembler.java | 71 +++++++++++++++++ .../data/model/ProjectTypeCodeEntity.java | 79 +++++++++++++++++++ .../ProjectTypeCodeRepository.java | 11 +++ .../data/resources/ProjectBoundaryModel.java | 2 +- .../data/resources/ProjectTypeCodeModel.java | 32 ++++++++ .../gov/nrs/wfprev/services/CodesService.java | 29 ++++++- 8 files changed, 232 insertions(+), 4 deletions(-) create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectTypeCodeEntity.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectTypeCodeRepository.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectTypeCodeModel.java diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java index 4dadae413..3839a8292 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java @@ -1,8 +1,9 @@ package ca.bc.gov.nrs.wfprev.common.enums; public enum CodeTables { - FOREST_AREA("forestAreaCode"), - GENERAL_SCOPE("generalScopeCode"); + FOREST_AREA("forestAreaCodes"), + GENERAL_SCOPE("generalScopeCodes"), + PROJECT_TYPE("projectTypeCodes"); private final String text; private CodeTables(final String text) { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java index c8f6eb9a1..d991699d7 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java @@ -12,6 +12,7 @@ import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; import ca.bc.gov.nrs.wfprev.common.controllers.CommonController; import ca.bc.gov.nrs.wfprev.common.entities.CommonModel; +import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; import ca.bc.gov.nrs.wfprev.services.CodesService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -57,6 +58,9 @@ public ResponseEntity getCodes(@PathVariable("codeTable") String codeTable) { case "generalScopeCodes": response = ok(codesService.getAllGeneralScopeCodes()); break; + case "projectTypeCodes": + response = ok(codesService.getAllProjectTypeCodes()); + break; default: response = internalServerError(); } @@ -90,6 +94,9 @@ public ResponseEntity getCodeById(@PathVariable("codeTable") String codeTable, @ case "generalScopeCodes": resource = codesService.getGeneralScopeCodeById(id); break; + case "projectTypeCodes": + resource = codesService.getProjectTypeCodeById(id); + break; default: resource = null; } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java new file mode 100644 index 000000000..ec5015679 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java @@ -0,0 +1,71 @@ +package ca.bc.gov.nrs.wfprev.data.assemblers; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; +import org.springframework.stereotype.Component; + +import ca.bc.gov.nrs.wfprev.data.model.ProjectTypeCodeEntity; +import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; +import ca.bc.gov.nrs.wfprev.controllers.CodesController; +import ca.bc.gov.nrs.wfprev.data.resources.ProjectTypeCodeModel; + +@Component +public class ProjectTypeCodeResourceAssembler extends RepresentationModelAssemblerSupport { + + public ProjectTypeCodeResourceAssembler() { + super(CodesController.class, ProjectTypeCodeModel.class); + } + + public ProjectTypeCodeEntity toEntity(ProjectTypeCodeModel resource) { + ProjectTypeCodeEntity entity = new ProjectTypeCodeEntity(); + + entity.setProjectTypeCode(resource.getProjectTypeCode()); + entity.setDescription(resource.getDescription()); + entity.setDisplayOrder(resource.getDisplayOrder()); + entity.setEffectiveDate(resource.getEffectiveDate()); + entity.setExpiryDate(resource.getExpiryDate()); + entity.setRevisionCount(resource.getRevisionCount()); + entity.setCreateUser(resource.getCreateUser()); + entity.setCreateDate(resource.getCreateDate()); + entity.setUpdateUser(resource.getUpdateUser()); + entity.setUpdateDate(resource.getUpdateDate()); + + return entity; + } + + @Override + public ProjectTypeCodeModel toModel(ProjectTypeCodeEntity entity) { + ProjectTypeCodeModel resource = instantiateModel(entity); + + resource.add(linkTo( + methodOn(CodesController.class) + .getCodeById(CodeTables.PROJECT_TYPE.toString(), entity.getProjectTypeCode())) + .withSelfRel()); + + resource.setProjectTypeCode(entity.getProjectTypeCode()); + resource.setDescription(entity.getDescription()); + resource.setDisplayOrder(entity.getDisplayOrder()); + resource.setEffectiveDate(entity.getEffectiveDate()); + resource.setExpiryDate(entity.getExpiryDate()); + resource.setRevisionCount(entity.getRevisionCount()); + resource.setCreateUser(entity.getCreateUser()); + resource.setCreateDate(entity.getCreateDate()); + resource.setUpdateUser(entity.getUpdateUser()); + resource.setUpdateDate(entity.getUpdateDate()); + + return resource; + } + + @Override + public CollectionModel toCollectionModel(Iterable entities) + { + CollectionModel resources = super.toCollectionModel(entities); + + resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.PROJECT_TYPE.toString())).withSelfRel()); + + return resources; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectTypeCodeEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectTypeCodeEntity.java new file mode 100644 index 000000000..b6c3f36ba --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectTypeCodeEntity.java @@ -0,0 +1,79 @@ +package ca.bc.gov.nrs.wfprev.data.model; +import java.io.Serializable; + +import java.util.Date; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import jakarta.persistence.Id; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.persistence.Version; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "project_type_code") +@JsonIgnoreProperties(ignoreUnknown = false) +@Data +@EqualsAndHashCode(callSuper = false) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProjectTypeCodeEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "project_type_code") + @NotNull + private String projectTypeCode; + + @NotNull + @Column(name = "description", length = 200) + private String description; + + @Column(name = "display_order", length = 3) + private Integer displayOrder; + + @NotNull + @Column(name = "effective_date", length = 200) + private Date effectiveDate; + + @NotNull + @Column(name = "expiry_date", length = 200) + private Date expiryDate; + + @Column(name = "revision_count", columnDefinition="Decimal(10) default '0'") + @NotNull + @Version + private Integer revisionCount; + + @CreatedBy + @NotNull + @Column(name="create_user", length = 64) + private String createUser; + + @CreatedDate + @NotNull + @Column(name="create_date") + private Date createDate; + + @LastModifiedBy + @NotNull + @Column(name="update_user", length = 64) + private String updateUser; + + @LastModifiedDate + @NotNull + @Column(name="update_date") + private Date updateDate; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectTypeCodeRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectTypeCodeRepository.java new file mode 100644 index 000000000..0f7c352dd --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectTypeCodeRepository.java @@ -0,0 +1,11 @@ +package ca.bc.gov.nrs.wfprev.data.repositories; + +import org.springframework.data.rest.core.annotation.RepositoryRestResource; + +import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; +import ca.bc.gov.nrs.wfprev.data.model.ProjectTypeCodeEntity; + +@RepositoryRestResource(exported = false) +public interface ProjectTypeCodeRepository extends CommonRepository { + +} \ No newline at end of file diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectBoundaryModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectBoundaryModel.java index 791ce30a3..694ba4c20 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectBoundaryModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectBoundaryModel.java @@ -26,7 +26,7 @@ @Builder @AllArgsConstructor @NoArgsConstructor -public class ProjectBoundaryModel extends CommonModel { +public class ProjectBoundaryModel extends CommonModel { private String projectBoundaryGuid; private String projectGuid; private Date systemStartTimestamp; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectTypeCodeModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectTypeCodeModel.java new file mode 100644 index 000000000..8f1f1b486 --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectTypeCodeModel.java @@ -0,0 +1,32 @@ +package ca.bc.gov.nrs.wfprev.data.resources; + +import java.util.Date; + +import org.springframework.hateoas.server.core.Relation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonRootName; + +import ca.bc.gov.nrs.wfprev.common.entities.CommonModel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Data +@EqualsAndHashCode(callSuper = false) +@JsonRootName(value = "projectTypeCode") +@Relation(collectionRelation = "projectTypeCode") +@JsonInclude(Include.NON_NULL) +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProjectTypeCodeModel extends CommonModel { + private String projectTypeCode; + private String description; + private Integer displayOrder; + private Date effectiveDate; + private Date expiryDate; +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java index 29043111a..b687fc833 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java @@ -10,12 +10,16 @@ import ca.bc.gov.nrs.wfprev.common.services.CommonService; import ca.bc.gov.nrs.wfprev.data.assemblers.ForestAreaCodeResourceAssembler; import ca.bc.gov.nrs.wfprev.data.assemblers.GeneralScopeCodeResourceAssembler; +import ca.bc.gov.nrs.wfprev.data.assemblers.ProjectTypeCodeResourceAssembler; import ca.bc.gov.nrs.wfprev.data.model.ForestAreaCodeEntity; import ca.bc.gov.nrs.wfprev.data.model.GeneralScopeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.model.ProjectTypeCodeEntity; import ca.bc.gov.nrs.wfprev.data.repositories.ForestAreaCodeRepository; import ca.bc.gov.nrs.wfprev.data.repositories.GeneralScopeCodeRepository; +import ca.bc.gov.nrs.wfprev.data.repositories.ProjectTypeCodeRepository; import ca.bc.gov.nrs.wfprev.data.resources.ForestAreaCodeModel; import ca.bc.gov.nrs.wfprev.data.resources.GeneralScopeCodeModel; +import ca.bc.gov.nrs.wfprev.data.resources.ProjectTypeCodeModel; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -25,13 +29,18 @@ public class CodesService implements CommonService { private ForestAreaCodeResourceAssembler forestAreaCodeResourceAssembler; private GeneralScopeCodeRepository generalScopeCodeRepository; private GeneralScopeCodeResourceAssembler generalScopeCodeResourceAssembler; + private ProjectTypeCodeRepository projectTypeCodeRepository; + private ProjectTypeCodeResourceAssembler projectTypeCodeResourceAssembler; public CodesService(ForestAreaCodeRepository forestAreaCodeRepository, ForestAreaCodeResourceAssembler forestAreaCodeResourceAssembler, - GeneralScopeCodeRepository generalScopeCodeRepository, GeneralScopeCodeResourceAssembler generalScopeCodeResourceAssembler) { + GeneralScopeCodeRepository generalScopeCodeRepository, GeneralScopeCodeResourceAssembler generalScopeCodeResourceAssembler, + ProjectTypeCodeRepository projectTypeCodeRepository, ProjectTypeCodeResourceAssembler projectTypeCodeResourceAssembler) { this.forestAreaCodeRepository = forestAreaCodeRepository; this.forestAreaCodeResourceAssembler = forestAreaCodeResourceAssembler; this.generalScopeCodeRepository = generalScopeCodeRepository; this.generalScopeCodeResourceAssembler = generalScopeCodeResourceAssembler; + this.projectTypeCodeRepository = projectTypeCodeRepository; + this.projectTypeCodeResourceAssembler = projectTypeCodeResourceAssembler; } /** FOREST AREA CODES **/ @@ -69,4 +78,22 @@ public GeneralScopeCodeModel getGeneralScopeCodeById(String id) throws ServiceEx throw new ServiceException(e.getLocalizedMessage(), e); } } + + /** PROJECT TYPE CODES **/ + public CollectionModel getAllProjectTypeCodes() throws ServiceException { + try { + List entities = new ArrayList<>(); + return projectTypeCodeResourceAssembler.toCollectionModel(entities); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } + + public ProjectTypeCodeModel getProjectTypeCodeById(String id) throws ServiceException { + try { + return projectTypeCodeRepository.findById(id).map(projectTypeCodeResourceAssembler::toModel).orElse(null); + } catch(Exception e) { + throw new ServiceException(e.getLocalizedMessage(), e); + } + } } From 07bc4357f8ced911d7d9e06191459e38424b5ac7 Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Thu, 21 Nov 2024 14:28:06 -0800 Subject: [PATCH 04/15] Add Code table const list --- .../nrs/wfprev/common/enums/CodeTables.java | 17 +++------- .../wfprev/controllers/CodesController.java | 33 ++++++++++--------- .../ForestAreaCodeResourceAssembler.java | 8 ++--- .../GeneralScopeCodeResourceAssembler.java | 4 +-- .../ProjectTypeCodeResourceAssembler.java | 4 +-- 5 files changed, 28 insertions(+), 38 deletions(-) diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java index 3839a8292..1c9d57df5 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/enums/CodeTables.java @@ -1,16 +1,7 @@ package ca.bc.gov.nrs.wfprev.common.enums; -public enum CodeTables { - FOREST_AREA("forestAreaCodes"), - GENERAL_SCOPE("generalScopeCodes"), - PROJECT_TYPE("projectTypeCodes"); - - private final String text; - private CodeTables(final String text) { - this.text = text; - } - @Override - public String toString() { - return text; - } +public class CodeTables { + public static final String FOREST_AREA_CODE = "forestAreaCodes"; + public static final String GENERAL_SCOPE_CODE = "generalScopeCodes"; + public static final String PROJECT_TYPE_CODE = "projectTypeCodes"; } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java index d991699d7..641e0c79f 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/CodesController.java @@ -52,18 +52,20 @@ public ResponseEntity getCodes(@PathVariable("codeTable") String codeTable) { try { switch(codeTable) { - case "forestAreaCodes": + case CodeTables.FOREST_AREA_CODE -> { response = ok(codesService.getAllForestAreaCodes()); - break; - case "generalScopeCodes": + } + case CodeTables.GENERAL_SCOPE_CODE -> { response = ok(codesService.getAllGeneralScopeCodes()); - break; - case "projectTypeCodes": + } + case CodeTables.PROJECT_TYPE_CODE -> { response = ok(codesService.getAllProjectTypeCodes()); - break; - default: + } + default -> { response = internalServerError(); + } } + } catch (ServiceException e) { response = internalServerError(); log.error(" ### Error while fetching codes", e); @@ -88,17 +90,18 @@ public ResponseEntity getCodeById(@PathVariable("codeTable") String codeTable, @ try { switch(codeTable) { - case "forestAreaCodes": + case CodeTables.FOREST_AREA_CODE -> { resource = codesService.getForestAreaCodeById(id); - break; - case "generalScopeCodes": + } + case CodeTables.GENERAL_SCOPE_CODE -> { resource = codesService.getGeneralScopeCodeById(id); - break; - case "projectTypeCodes": + } + case CodeTables.PROJECT_TYPE_CODE -> { resource = codesService.getProjectTypeCodeById(id); - break; - default: - resource = null; + } + default -> { + resource = null; + } } response = resource == null ? notFound() : ok(resource); diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java index 7b5e4e3aa..6508cb801 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java @@ -3,10 +3,6 @@ import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; import org.springframework.stereotype.Component; @@ -46,7 +42,7 @@ public ForestAreaCodeModel toModel(ForestAreaCodeEntity entity) { resource.add(linkTo( methodOn(CodesController.class) - .getCodeById(CodeTables.FOREST_AREA.toString(), entity.getForestAreaCode())) + .getCodeById(CodeTables.FOREST_AREA_CODE, entity.getForestAreaCode())) .withSelfRel()); resource.setForestAreaCode(entity.getForestAreaCode()); @@ -68,7 +64,7 @@ public CollectionModel toCollectionModel(Iterable resources = super.toCollectionModel(entities); - resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.FOREST_AREA.toString())).withSelfRel()); + resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.FOREST_AREA_CODE)).withSelfRel()); return resources; } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java index 4afdaba76..f113d7cc5 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java @@ -46,7 +46,7 @@ public GeneralScopeCodeModel toModel(GeneralScopeCodeEntity entity) { resource.add(linkTo( methodOn(CodesController.class) - .getCodeById(CodeTables.GENERAL_SCOPE.toString(), entity.getGeneralScopeCode())) + .getCodeById(CodeTables.GENERAL_SCOPE_CODE, entity.getGeneralScopeCode())) .withSelfRel()); resource.setGeneralScopeCode(entity.getGeneralScopeCode()); @@ -68,7 +68,7 @@ public CollectionModel toCollectionModel(Iterable resources = super.toCollectionModel(entities); - resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.GENERAL_SCOPE.toString())).withSelfRel()); + resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.GENERAL_SCOPE_CODE)).withSelfRel()); return resources; } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java index ec5015679..e219d64a6 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java @@ -42,7 +42,7 @@ public ProjectTypeCodeModel toModel(ProjectTypeCodeEntity entity) { resource.add(linkTo( methodOn(CodesController.class) - .getCodeById(CodeTables.PROJECT_TYPE.toString(), entity.getProjectTypeCode())) + .getCodeById(CodeTables.PROJECT_TYPE_CODE, entity.getProjectTypeCode())) .withSelfRel()); resource.setProjectTypeCode(entity.getProjectTypeCode()); @@ -64,7 +64,7 @@ public CollectionModel toCollectionModel(Iterable resources = super.toCollectionModel(entities); - resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.PROJECT_TYPE.toString())).withSelfRel()); + resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.PROJECT_TYPE_CODE)).withSelfRel()); return resources; } From a04aec1d9fa9746b74e36c4f6ea15f367637a4f4 Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Thu, 21 Nov 2024 15:11:37 -0800 Subject: [PATCH 05/15] Add manyToOne links for Projects --- .../assemblers/ProjectResourceAssembler.java | 54 ++++++++++++++++--- .../nrs/wfprev/data/model/ProjectEntity.java | 33 +++++------- .../wfprev/data/resources/ProjectModel.java | 8 +-- 3 files changed, 66 insertions(+), 29 deletions(-) diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java index 0a6a201e9..8fe2b3097 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java @@ -7,9 +7,15 @@ import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; import org.springframework.stereotype.Component; +import ca.bc.gov.nrs.wfprev.data.model.ForestAreaCodeEntity; +import ca.bc.gov.nrs.wfprev.data.model.GeneralScopeCodeEntity; import ca.bc.gov.nrs.wfprev.data.model.ProjectEntity; +import ca.bc.gov.nrs.wfprev.data.model.ProjectTypeCodeEntity; import ca.bc.gov.nrs.wfprev.controllers.ProjectController; +import ca.bc.gov.nrs.wfprev.data.resources.ForestAreaCodeModel; +import ca.bc.gov.nrs.wfprev.data.resources.GeneralScopeCodeModel; import ca.bc.gov.nrs.wfprev.data.resources.ProjectModel; +import ca.bc.gov.nrs.wfprev.data.resources.ProjectTypeCodeModel; @Component public class ProjectResourceAssembler extends RepresentationModelAssemblerSupport { @@ -22,11 +28,11 @@ public ProjectEntity toEntity(ProjectModel resource) { ProjectEntity entity = new ProjectEntity(); entity.setProjectGuid(resource.getProjectGuid()); - entity.setProjectTypeCode(resource.getProjectTypeCode()); + entity.setProjectTypeCode(toProjectTypeCodeEntity(resource.getProjectTypeCode())); entity.setProjectNumber(resource.getProjectNumber()); entity.setSiteUnitName(resource.getSiteUnitName()); - entity.setForestAreaCode(resource.getForestAreaCode()); - entity.setGeneralScopeCode(resource.getGeneralScopeCode()); + entity.setForestAreaCode(toForestAreaCodeEntity(resource.getForestAreaCode())); + entity.setGeneralScopeCode(toGeneralScopeCodeEntity(resource.getGeneralScopeCode())); entity.setProgramAreaGuid(resource.getProgramAreaGuid()); entity.setForestRegionOrgUnitId(resource.getForestRegionOrgUnitId()); entity.setForestDistrictOrgUnitId(resource.getForestDistrictOrgUnitId()); @@ -68,11 +74,11 @@ public ProjectModel toModel(ProjectEntity entity) { .withSelfRel()); resource.setProjectGuid(entity.getProjectGuid()); - resource.setProjectTypeCode(entity.getProjectTypeCode()); + resource.setProjectTypeCode(toProjectTypeCodeModel(entity.getProjectTypeCode())); resource.setProjectNumber(entity.getProjectNumber()); resource.setSiteUnitName(entity.getSiteUnitName()); - resource.setForestAreaCode(entity.getForestAreaCode()); - resource.setGeneralScopeCode(entity.getGeneralScopeCode()); + resource.setForestAreaCode(toForestAreaCodeModel(entity.getForestAreaCode())); + resource.setGeneralScopeCode(toGeneralScopeCodeModel(entity.getGeneralScopeCode())); resource.setProgramAreaGuid(entity.getProgramAreaGuid()); resource.setForestRegionOrgUnitId(entity.getForestRegionOrgUnitId()); resource.setForestDistrictOrgUnitId(entity.getForestDistrictOrgUnitId()); @@ -113,4 +119,40 @@ public CollectionModel toCollectionModel(Iterable { private String projectGuid; - private String projectTypeCode; // CODE + private ProjectTypeCodeModel projectTypeCode; // CODE private Integer projectNumber; private String siteUnitName; - private String forestAreaCode; // CODE - private String generalScopeCode; // CODE - private String programAreaGuid; // FK + private ForestAreaCodeModel forestAreaCode; // CODE + private GeneralScopeCodeModel generalScopeCode; // CODE + private String programAreaGuid; // FK, not Modeled private Integer forestRegionOrgUnitId; private Integer forestDistrictOrgUnitId; private Integer fireCentreOrgUnitId; From aee0e97919c3669fb7abc433cbfae9f76404da37 Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Thu, 21 Nov 2024 15:25:51 -0800 Subject: [PATCH 06/15] Update Entity/Model folder naming for consistency --- .../controllers/ProgramAreaController.java | 2 +- .../controllers/ProjectBoundaryController.java | 2 +- .../wfprev/controllers/ProjectController.java | 2 +- .../ForestAreaCodeResourceAssembler.java | 4 ++-- .../GeneralScopeCodeResourceAssembler.java | 8 ++------ .../assemblers/ProgramAreaResourceAssembler.java | 8 +++----- .../ProjectBoundaryResourceAssembler.java | 4 ++-- .../assemblers/ProjectResourceAssembler.java | 16 ++++++++-------- .../ProjectTypeCodeResourceAssembler.java | 4 ++-- .../ForestAreaCodeEntity.java | 2 +- .../GeneralScopeCodeEntity.java | 2 +- .../{model => entities}/ProgramAreaEntity.java | 2 +- .../ProjectBoundaryEntity.java | 2 +- .../data/{model => entities}/ProjectEntity.java | 2 +- .../ProjectTypeCodeEntity.java | 2 +- .../ForestAreaCodeModel.java | 2 +- .../GeneralScopeCodeModel.java | 2 +- .../{resources => models}/ProgramAreaModel.java | 2 +- .../ProjectBoundaryModel.java | 2 +- .../data/{resources => models}/ProjectModel.java | 2 +- .../ProjectTypeCodeModel.java | 2 +- .../repositories/ForestAreaCodeRepository.java | 2 +- .../repositories/GeneralScopeCodeRepository.java | 2 +- .../data/repositories/ProgramAreaRepository.java | 2 +- .../repositories/ProjectBoundaryRepository.java | 2 +- .../data/repositories/ProjectRepository.java | 3 ++- .../repositories/ProjectTypeCodeRepository.java | 2 +- .../bc/gov/nrs/wfprev/services/CodesService.java | 12 ++++++------ .../nrs/wfprev/services/ProgramAreaService.java | 4 ++-- .../wfprev/services/ProjectBoundaryService.java | 4 ++-- .../gov/nrs/wfprev/services/ProjectService.java | 4 ++-- .../bc/gov/nrs/wfprev/ExampleControllerTest.java | 4 ++-- 32 files changed, 55 insertions(+), 60 deletions(-) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{model => entities}/ForestAreaCodeEntity.java (97%) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{model => entities}/GeneralScopeCodeEntity.java (97%) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{model => entities}/ProgramAreaEntity.java (97%) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{model => entities}/ProjectBoundaryEntity.java (98%) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{model => entities}/ProjectEntity.java (99%) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{model => entities}/ProjectTypeCodeEntity.java (97%) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{resources => models}/ForestAreaCodeModel.java (95%) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{resources => models}/GeneralScopeCodeModel.java (95%) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{resources => models}/ProgramAreaModel.java (94%) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{resources => models}/ProjectBoundaryModel.java (96%) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{resources => models}/ProjectModel.java (97%) rename server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/{resources => models}/ProjectTypeCodeModel.java (95%) diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java index ccad88ab3..ed3c18721 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java @@ -18,7 +18,7 @@ import ca.bc.gov.nrs.common.wfone.rest.resource.MessageListRsrc; import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; import ca.bc.gov.nrs.wfprev.common.controllers.CommonController; -import ca.bc.gov.nrs.wfprev.data.resources.ProgramAreaModel; +import ca.bc.gov.nrs.wfprev.data.models.ProgramAreaModel; import ca.bc.gov.nrs.wfprev.services.ProgramAreaService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java index c411a1b1d..76ea4e55a 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java @@ -18,7 +18,7 @@ import ca.bc.gov.nrs.common.wfone.rest.resource.MessageListRsrc; import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; import ca.bc.gov.nrs.wfprev.common.controllers.CommonController; -import ca.bc.gov.nrs.wfprev.data.resources.ProjectBoundaryModel; +import ca.bc.gov.nrs.wfprev.data.models.ProjectBoundaryModel; import ca.bc.gov.nrs.wfprev.services.ProjectBoundaryService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java index f5beefa76..001dce484 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java @@ -18,7 +18,7 @@ import ca.bc.gov.nrs.common.wfone.rest.resource.MessageListRsrc; import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; import ca.bc.gov.nrs.wfprev.common.controllers.CommonController; -import ca.bc.gov.nrs.wfprev.data.resources.ProjectModel; +import ca.bc.gov.nrs.wfprev.data.models.ProjectModel; import ca.bc.gov.nrs.wfprev.services.ProjectService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java index 6508cb801..74b24c1ee 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ForestAreaCodeResourceAssembler.java @@ -7,10 +7,10 @@ import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; import org.springframework.stereotype.Component; -import ca.bc.gov.nrs.wfprev.data.model.ForestAreaCodeEntity; import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; import ca.bc.gov.nrs.wfprev.controllers.CodesController; -import ca.bc.gov.nrs.wfprev.data.resources.ForestAreaCodeModel; +import ca.bc.gov.nrs.wfprev.data.entities.ForestAreaCodeEntity; +import ca.bc.gov.nrs.wfprev.data.models.ForestAreaCodeModel; @Component public class ForestAreaCodeResourceAssembler extends RepresentationModelAssemblerSupport { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java index f113d7cc5..9a26aa662 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/GeneralScopeCodeResourceAssembler.java @@ -3,18 +3,14 @@ import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; import org.springframework.stereotype.Component; -import ca.bc.gov.nrs.wfprev.data.model.GeneralScopeCodeEntity; import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; import ca.bc.gov.nrs.wfprev.controllers.CodesController; -import ca.bc.gov.nrs.wfprev.data.resources.GeneralScopeCodeModel; +import ca.bc.gov.nrs.wfprev.data.entities.GeneralScopeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.models.GeneralScopeCodeModel; @Component public class GeneralScopeCodeResourceAssembler extends RepresentationModelAssemblerSupport { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProgramAreaResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProgramAreaResourceAssembler.java index 2d33c0717..cdaa55fa8 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProgramAreaResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProgramAreaResourceAssembler.java @@ -6,11 +6,9 @@ import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; import org.springframework.stereotype.Component; -import ca.bc.gov.nrs.wfprev.data.model.ProgramAreaEntity; -import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; -import ca.bc.gov.nrs.wfprev.controllers.CodesController; import ca.bc.gov.nrs.wfprev.controllers.ProgramAreaController; -import ca.bc.gov.nrs.wfprev.data.resources.ProgramAreaModel; +import ca.bc.gov.nrs.wfprev.data.entities.ProgramAreaEntity; +import ca.bc.gov.nrs.wfprev.data.models.ProgramAreaModel; @Component public class ProgramAreaResourceAssembler extends RepresentationModelAssemblerSupport { @@ -58,7 +56,7 @@ public CollectionModel toCollectionModel(Iterable resources = super.toCollectionModel(entities); - resources.add(linkTo(methodOn(CodesController.class).getCodes(CodeTables.GENERAL_SCOPE.toString())).withSelfRel()); + resources.add(linkTo(methodOn(ProgramAreaController.class).getAllProgramAreas()).withSelfRel()); return resources; } diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectBoundaryResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectBoundaryResourceAssembler.java index e8bbda9e3..4c64bd130 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectBoundaryResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectBoundaryResourceAssembler.java @@ -7,9 +7,9 @@ import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; import org.springframework.stereotype.Component; -import ca.bc.gov.nrs.wfprev.data.model.ProjectBoundaryEntity; import ca.bc.gov.nrs.wfprev.controllers.ProjectBoundaryController; -import ca.bc.gov.nrs.wfprev.data.resources.ProjectBoundaryModel; +import ca.bc.gov.nrs.wfprev.data.entities.ProjectBoundaryEntity; +import ca.bc.gov.nrs.wfprev.data.models.ProjectBoundaryModel; @Component public class ProjectBoundaryResourceAssembler extends RepresentationModelAssemblerSupport { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java index 8fe2b3097..349012500 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectResourceAssembler.java @@ -7,15 +7,15 @@ import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; import org.springframework.stereotype.Component; -import ca.bc.gov.nrs.wfprev.data.model.ForestAreaCodeEntity; -import ca.bc.gov.nrs.wfprev.data.model.GeneralScopeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.model.ProjectEntity; -import ca.bc.gov.nrs.wfprev.data.model.ProjectTypeCodeEntity; import ca.bc.gov.nrs.wfprev.controllers.ProjectController; -import ca.bc.gov.nrs.wfprev.data.resources.ForestAreaCodeModel; -import ca.bc.gov.nrs.wfprev.data.resources.GeneralScopeCodeModel; -import ca.bc.gov.nrs.wfprev.data.resources.ProjectModel; -import ca.bc.gov.nrs.wfprev.data.resources.ProjectTypeCodeModel; +import ca.bc.gov.nrs.wfprev.data.entities.ForestAreaCodeEntity; +import ca.bc.gov.nrs.wfprev.data.entities.GeneralScopeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.entities.ProjectEntity; +import ca.bc.gov.nrs.wfprev.data.entities.ProjectTypeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.models.ForestAreaCodeModel; +import ca.bc.gov.nrs.wfprev.data.models.GeneralScopeCodeModel; +import ca.bc.gov.nrs.wfprev.data.models.ProjectModel; +import ca.bc.gov.nrs.wfprev.data.models.ProjectTypeCodeModel; @Component public class ProjectResourceAssembler extends RepresentationModelAssemblerSupport { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java index e219d64a6..bfcf99a3e 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/assemblers/ProjectTypeCodeResourceAssembler.java @@ -7,10 +7,10 @@ import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport; import org.springframework.stereotype.Component; -import ca.bc.gov.nrs.wfprev.data.model.ProjectTypeCodeEntity; import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; import ca.bc.gov.nrs.wfprev.controllers.CodesController; -import ca.bc.gov.nrs.wfprev.data.resources.ProjectTypeCodeModel; +import ca.bc.gov.nrs.wfprev.data.entities.ProjectTypeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.models.ProjectTypeCodeModel; @Component public class ProjectTypeCodeResourceAssembler extends RepresentationModelAssemblerSupport { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ForestAreaCodeEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ForestAreaCodeEntity.java similarity index 97% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ForestAreaCodeEntity.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ForestAreaCodeEntity.java index b575b0ee2..d26e39d3d 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ForestAreaCodeEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ForestAreaCodeEntity.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.model; +package ca.bc.gov.nrs.wfprev.data.entities; import java.io.Serializable; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/GeneralScopeCodeEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/GeneralScopeCodeEntity.java similarity index 97% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/GeneralScopeCodeEntity.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/GeneralScopeCodeEntity.java index c223b174d..af8f4fc26 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/GeneralScopeCodeEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/GeneralScopeCodeEntity.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.model; +package ca.bc.gov.nrs.wfprev.data.entities; import java.io.Serializable; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProgramAreaEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProgramAreaEntity.java similarity index 97% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProgramAreaEntity.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProgramAreaEntity.java index 36574c116..e61df5c9e 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProgramAreaEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProgramAreaEntity.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.model; +package ca.bc.gov.nrs.wfprev.data.entities; import java.io.Serializable; import java.util.Date; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectBoundaryEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectBoundaryEntity.java similarity index 98% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectBoundaryEntity.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectBoundaryEntity.java index 0a0d87c02..0cb262c63 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectBoundaryEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectBoundaryEntity.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.model; +package ca.bc.gov.nrs.wfprev.data.entities; import java.io.Serializable; import java.math.BigDecimal; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java similarity index 99% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectEntity.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java index 21105c85d..125de2453 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.model; +package ca.bc.gov.nrs.wfprev.data.entities; import java.io.Serializable; import java.math.BigDecimal; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectTypeCodeEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectTypeCodeEntity.java similarity index 97% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectTypeCodeEntity.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectTypeCodeEntity.java index b6c3f36ba..3fb86c029 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/model/ProjectTypeCodeEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectTypeCodeEntity.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.model; +package ca.bc.gov.nrs.wfprev.data.entities; import java.io.Serializable; import java.util.Date; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ForestAreaCodeModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ForestAreaCodeModel.java similarity index 95% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ForestAreaCodeModel.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ForestAreaCodeModel.java index 435a2dd81..2121c5a06 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ForestAreaCodeModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ForestAreaCodeModel.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.resources; +package ca.bc.gov.nrs.wfprev.data.models; import java.util.Date; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/GeneralScopeCodeModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/GeneralScopeCodeModel.java similarity index 95% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/GeneralScopeCodeModel.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/GeneralScopeCodeModel.java index c108d0768..74e7ffc80 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/GeneralScopeCodeModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/GeneralScopeCodeModel.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.resources; +package ca.bc.gov.nrs.wfprev.data.models; import java.util.Date; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProgramAreaModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProgramAreaModel.java similarity index 94% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProgramAreaModel.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProgramAreaModel.java index a2ce6bc44..0f7288eb6 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProgramAreaModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProgramAreaModel.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.resources; +package ca.bc.gov.nrs.wfprev.data.models; import org.springframework.hateoas.server.core.Relation; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectBoundaryModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectBoundaryModel.java similarity index 96% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectBoundaryModel.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectBoundaryModel.java index 694ba4c20..ead76e2d6 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectBoundaryModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectBoundaryModel.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.resources; +package ca.bc.gov.nrs.wfprev.data.models; import java.math.BigDecimal; import java.util.Date; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java similarity index 97% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectModel.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java index a69450a5b..7b1163895 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.resources; +package ca.bc.gov.nrs.wfprev.data.models; import java.math.BigDecimal; import java.util.Date; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectTypeCodeModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectTypeCodeModel.java similarity index 95% rename from server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectTypeCodeModel.java rename to server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectTypeCodeModel.java index 8f1f1b486..25fea7351 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/resources/ProjectTypeCodeModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectTypeCodeModel.java @@ -1,4 +1,4 @@ -package ca.bc.gov.nrs.wfprev.data.resources; +package ca.bc.gov.nrs.wfprev.data.models; import java.util.Date; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ForestAreaCodeRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ForestAreaCodeRepository.java index c4f3c1368..62021cdab 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ForestAreaCodeRepository.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ForestAreaCodeRepository.java @@ -3,7 +3,7 @@ import org.springframework.data.rest.core.annotation.RepositoryRestResource; import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; -import ca.bc.gov.nrs.wfprev.data.model.ForestAreaCodeEntity; +import ca.bc.gov.nrs.wfprev.data.entities.ForestAreaCodeEntity; @RepositoryRestResource(exported = false) public interface ForestAreaCodeRepository extends CommonRepository { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/GeneralScopeCodeRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/GeneralScopeCodeRepository.java index da808cc3a..2a365eacb 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/GeneralScopeCodeRepository.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/GeneralScopeCodeRepository.java @@ -1,8 +1,8 @@ package ca.bc.gov.nrs.wfprev.data.repositories; -import ca.bc.gov.nrs.wfprev.data.model.GeneralScopeCodeEntity; import org.springframework.data.rest.core.annotation.RepositoryRestResource; import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; +import ca.bc.gov.nrs.wfprev.data.entities.GeneralScopeCodeEntity; @RepositoryRestResource(exported = false) public interface GeneralScopeCodeRepository extends CommonRepository { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProgramAreaRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProgramAreaRepository.java index 0576e2696..1aadc4299 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProgramAreaRepository.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProgramAreaRepository.java @@ -1,8 +1,8 @@ package ca.bc.gov.nrs.wfprev.data.repositories; -import ca.bc.gov.nrs.wfprev.data.model.ProgramAreaEntity; import org.springframework.data.rest.core.annotation.RepositoryRestResource; import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; +import ca.bc.gov.nrs.wfprev.data.entities.ProgramAreaEntity; @RepositoryRestResource(exported = false) public interface ProgramAreaRepository extends CommonRepository { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectBoundaryRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectBoundaryRepository.java index f820e1c7c..5773800ff 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectBoundaryRepository.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectBoundaryRepository.java @@ -1,8 +1,8 @@ package ca.bc.gov.nrs.wfprev.data.repositories; -import ca.bc.gov.nrs.wfprev.data.model.ProjectBoundaryEntity; import org.springframework.data.rest.core.annotation.RepositoryRestResource; import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; +import ca.bc.gov.nrs.wfprev.data.entities.ProjectBoundaryEntity; @RepositoryRestResource(exported = false) public interface ProjectBoundaryRepository extends CommonRepository { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectRepository.java index fc882d8bd..16e54897a 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectRepository.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectRepository.java @@ -1,8 +1,9 @@ package ca.bc.gov.nrs.wfprev.data.repositories; import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; +import ca.bc.gov.nrs.wfprev.data.entities.ProjectEntity; + import org.springframework.data.rest.core.annotation.RepositoryRestResource; -import ca.bc.gov.nrs.wfprev.data.model.ProjectEntity; @RepositoryRestResource(exported = false) public interface ProjectRepository extends CommonRepository { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectTypeCodeRepository.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectTypeCodeRepository.java index 0f7c352dd..4b4887f3e 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectTypeCodeRepository.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/repositories/ProjectTypeCodeRepository.java @@ -3,7 +3,7 @@ import org.springframework.data.rest.core.annotation.RepositoryRestResource; import ca.bc.gov.nrs.wfprev.common.repository.CommonRepository; -import ca.bc.gov.nrs.wfprev.data.model.ProjectTypeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.entities.ProjectTypeCodeEntity; @RepositoryRestResource(exported = false) public interface ProjectTypeCodeRepository extends CommonRepository { diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java index b687fc833..a81541718 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/CodesService.java @@ -11,15 +11,15 @@ import ca.bc.gov.nrs.wfprev.data.assemblers.ForestAreaCodeResourceAssembler; import ca.bc.gov.nrs.wfprev.data.assemblers.GeneralScopeCodeResourceAssembler; import ca.bc.gov.nrs.wfprev.data.assemblers.ProjectTypeCodeResourceAssembler; -import ca.bc.gov.nrs.wfprev.data.model.ForestAreaCodeEntity; -import ca.bc.gov.nrs.wfprev.data.model.GeneralScopeCodeEntity; -import ca.bc.gov.nrs.wfprev.data.model.ProjectTypeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.entities.ForestAreaCodeEntity; +import ca.bc.gov.nrs.wfprev.data.entities.GeneralScopeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.entities.ProjectTypeCodeEntity; +import ca.bc.gov.nrs.wfprev.data.models.ForestAreaCodeModel; +import ca.bc.gov.nrs.wfprev.data.models.GeneralScopeCodeModel; +import ca.bc.gov.nrs.wfprev.data.models.ProjectTypeCodeModel; import ca.bc.gov.nrs.wfprev.data.repositories.ForestAreaCodeRepository; import ca.bc.gov.nrs.wfprev.data.repositories.GeneralScopeCodeRepository; import ca.bc.gov.nrs.wfprev.data.repositories.ProjectTypeCodeRepository; -import ca.bc.gov.nrs.wfprev.data.resources.ForestAreaCodeModel; -import ca.bc.gov.nrs.wfprev.data.resources.GeneralScopeCodeModel; -import ca.bc.gov.nrs.wfprev.data.resources.ProjectTypeCodeModel; import lombok.extern.slf4j.Slf4j; @Slf4j diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProgramAreaService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProgramAreaService.java index ca9d8b74f..43a2c44f0 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProgramAreaService.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProgramAreaService.java @@ -10,9 +10,9 @@ import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; import ca.bc.gov.nrs.wfprev.common.services.CommonService; import ca.bc.gov.nrs.wfprev.data.assemblers.ProgramAreaResourceAssembler; -import ca.bc.gov.nrs.wfprev.data.model.ProgramAreaEntity; +import ca.bc.gov.nrs.wfprev.data.entities.ProgramAreaEntity; +import ca.bc.gov.nrs.wfprev.data.models.ProgramAreaModel; import ca.bc.gov.nrs.wfprev.data.repositories.ProgramAreaRepository; -import ca.bc.gov.nrs.wfprev.data.resources.ProgramAreaModel; import jakarta.transaction.Transactional; import lombok.extern.slf4j.Slf4j; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectBoundaryService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectBoundaryService.java index 234a98519..ca726b243 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectBoundaryService.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectBoundaryService.java @@ -10,9 +10,9 @@ import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; import ca.bc.gov.nrs.wfprev.common.services.CommonService; import ca.bc.gov.nrs.wfprev.data.assemblers.ProjectBoundaryResourceAssembler; -import ca.bc.gov.nrs.wfprev.data.model.ProjectBoundaryEntity; +import ca.bc.gov.nrs.wfprev.data.entities.ProjectBoundaryEntity; +import ca.bc.gov.nrs.wfprev.data.models.ProjectBoundaryModel; import ca.bc.gov.nrs.wfprev.data.repositories.ProjectBoundaryRepository; -import ca.bc.gov.nrs.wfprev.data.resources.ProjectBoundaryModel; import jakarta.transaction.Transactional; import lombok.extern.slf4j.Slf4j; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java index 9c57c23c8..d08a6ae5a 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/services/ProjectService.java @@ -10,9 +10,9 @@ import ca.bc.gov.nrs.wfone.common.service.api.ServiceException; import ca.bc.gov.nrs.wfprev.common.services.CommonService; import ca.bc.gov.nrs.wfprev.data.assemblers.ProjectResourceAssembler; -import ca.bc.gov.nrs.wfprev.data.model.ProjectEntity; +import ca.bc.gov.nrs.wfprev.data.entities.ProjectEntity; +import ca.bc.gov.nrs.wfprev.data.models.ProjectModel; import ca.bc.gov.nrs.wfprev.data.repositories.ProjectRepository; -import ca.bc.gov.nrs.wfprev.data.resources.ProjectModel; import jakarta.transaction.Transactional; import lombok.extern.slf4j.Slf4j; diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ExampleControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ExampleControllerTest.java index 70a7d090f..1284638cf 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ExampleControllerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ExampleControllerTest.java @@ -19,8 +19,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import ca.bc.gov.nrs.wfprev.controllers.ExampleController; -import ca.bc.gov.nrs.wfprev.data.resources.ExampleCodeModel; -import ca.bc.gov.nrs.wfprev.data.resources.ExampleModel; +import ca.bc.gov.nrs.wfprev.data.models.ExampleCodeModel; +import ca.bc.gov.nrs.wfprev.data.models.ExampleModel; import ca.bc.gov.nrs.wfprev.services.ExampleService; @WebMvcTest(ExampleController.class) From cdd094e6725e4d06c7776346ee7533f51fef469d Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Thu, 21 Nov 2024 15:44:09 -0800 Subject: [PATCH 07/15] Add codes controller test --- .../gov/nrs/wfprev/CodesControllerTest.java | 160 ++++++++++++++++++ .../gov/nrs/wfprev/ExampleControllerTest.java | 109 ------------ 2 files changed, 160 insertions(+), 109 deletions(-) create mode 100644 server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/CodesControllerTest.java delete mode 100644 server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ExampleControllerTest.java diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/CodesControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/CodesControllerTest.java new file mode 100644 index 000000000..6fbfa0f4a --- /dev/null +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/CodesControllerTest.java @@ -0,0 +1,160 @@ +package ca.bc.gov.nrs.wfprev; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import static org.mockito.Mockito.when; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.hateoas.CollectionModel; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import ca.bc.gov.nrs.wfprev.common.enums.CodeTables; +import ca.bc.gov.nrs.wfprev.controllers.CodesController; +import ca.bc.gov.nrs.wfprev.data.models.ForestAreaCodeModel; +import ca.bc.gov.nrs.wfprev.data.models.GeneralScopeCodeModel; +import ca.bc.gov.nrs.wfprev.data.models.ProjectTypeCodeModel; +import ca.bc.gov.nrs.wfprev.services.CodesService; + +@WebMvcTest(CodesController.class) +@Import({SecurityConfig.class, TestcontainersConfiguration.class}) +class CodesControllerTest { + + @MockBean + private CodesService codesService; + + @Autowired + private MockMvc mockMvc; + + @Test + @WithMockUser + void testGetAllCodes() throws Exception { + testGetForestAreaCodes(); + testGetGeneralScopeCodes(); + testGetProjectTypeCodes(); + } + + void testGetForestAreaCodes() throws Exception { + String exampleId1 = UUID.randomUUID().toString(); + String exampleId2 = UUID.randomUUID().toString(); + + ForestAreaCodeModel fac1 = new ForestAreaCodeModel(); + fac1.setForestAreaCode(exampleId1); + + ForestAreaCodeModel fac2 = new ForestAreaCodeModel(); + fac2.setForestAreaCode(exampleId2); + + List facList = Arrays.asList(fac1, fac2); + CollectionModel facModel = CollectionModel.of(facList); + + when(codesService.getAllForestAreaCodes()).thenReturn(facModel); + + mockMvc.perform(get("/codes/" + CodeTables.FOREST_AREA_CODE) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + void testGetGeneralScopeCodes() throws Exception { + String exampleId1 = UUID.randomUUID().toString(); + String exampleId2 = UUID.randomUUID().toString(); + + GeneralScopeCodeModel fac1 = new GeneralScopeCodeModel(); + fac1.setGeneralScopeCode(exampleId1); + + GeneralScopeCodeModel fac2 = new GeneralScopeCodeModel(); + fac2.setGeneralScopeCode(exampleId2); + + List facList = Arrays.asList(fac1, fac2); + CollectionModel facModel = CollectionModel.of(facList); + + when(codesService.getAllGeneralScopeCodes()).thenReturn(facModel); + + mockMvc.perform(get("/codes/" + CodeTables.GENERAL_SCOPE_CODE) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + void testGetProjectTypeCodes() throws Exception { + String exampleId1 = UUID.randomUUID().toString(); + String exampleId2 = UUID.randomUUID().toString(); + + ProjectTypeCodeModel fac1 = new ProjectTypeCodeModel(); + fac1.setProjectTypeCode(exampleId1); + + ProjectTypeCodeModel fac2 = new ProjectTypeCodeModel(); + fac2.setProjectTypeCode(exampleId2); + + List facList = Arrays.asList(fac1, fac2); + CollectionModel facModel = CollectionModel.of(facList); + + when(codesService.getAllProjectTypeCodes()).thenReturn(facModel); + + mockMvc.perform(get("/codes/" + CodeTables.PROJECT_TYPE_CODE) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + @WithMockUser + void testGetCodesById() throws Exception { + String ptID = UUID.randomUUID().toString(); + ProjectTypeCodeModel projectTypeCode = new ProjectTypeCodeModel(); + projectTypeCode.setProjectTypeCode(ptID); + + when(codesService.getProjectTypeCodeById(ptID)).thenReturn(projectTypeCode); + + mockMvc.perform(get("/codes/{codeTable}/{id}", CodeTables.PROJECT_TYPE_CODE, ptID) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + String gsID = UUID.randomUUID().toString(); + GeneralScopeCodeModel generalScopeCode = new GeneralScopeCodeModel(); + generalScopeCode.setGeneralScopeCode(gsID); + + when(codesService.getGeneralScopeCodeById(gsID)).thenReturn(generalScopeCode); + + mockMvc.perform(get("/codes/{codeTable}/{id}", CodeTables.GENERAL_SCOPE_CODE, gsID) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + String faID = UUID.randomUUID().toString(); + ForestAreaCodeModel forestAreaCode = new ForestAreaCodeModel(); + forestAreaCode.setForestAreaCode(faID); + + when(codesService.getForestAreaCodeById(faID)).thenReturn(forestAreaCode); + + mockMvc.perform(get("/codes/{codeTable}/{id}", CodeTables.FOREST_AREA_CODE, faID) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + @WithMockUser + void testCodesNotFound() throws Exception { + ForestAreaCodeModel forestAreaCode = new ForestAreaCodeModel(); + GeneralScopeCodeModel generalScopeCode = new GeneralScopeCodeModel(); + ProjectTypeCodeModel projectTypeCode = new ProjectTypeCodeModel(); + + when(codesService.getForestAreaCodeById(null)).thenReturn(forestAreaCode); + when(codesService.getGeneralScopeCodeById(null)).thenReturn(generalScopeCode); + when(codesService.getProjectTypeCodeById(null)).thenReturn(projectTypeCode); + + mockMvc.perform(get("/codes/{codeTable}/{id}", CodeTables.FOREST_AREA_CODE, null) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + mockMvc.perform(get("/codes/{codeTable}/{id}", CodeTables.GENERAL_SCOPE_CODE, null) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + mockMvc.perform(get("/codes/{codeTable}/{id}", CodeTables.PROJECT_TYPE_CODE, null) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + } +} diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ExampleControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ExampleControllerTest.java deleted file mode 100644 index 1284638cf..000000000 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ExampleControllerTest.java +++ /dev/null @@ -1,109 +0,0 @@ -package ca.bc.gov.nrs.wfprev; - -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import org.junit.jupiter.api.Test; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; -import org.springframework.hateoas.CollectionModel; -import org.springframework.http.MediaType; -import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.test.web.servlet.MockMvc; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import ca.bc.gov.nrs.wfprev.controllers.ExampleController; -import ca.bc.gov.nrs.wfprev.data.models.ExampleCodeModel; -import ca.bc.gov.nrs.wfprev.data.models.ExampleModel; -import ca.bc.gov.nrs.wfprev.services.ExampleService; - -@WebMvcTest(ExampleController.class) -@Import({SecurityConfig.class, TestcontainersConfiguration.class}) -class ExampleControllerTest { - - @MockBean - private ExampleService exampleService; - - @Autowired - private MockMvc mockMvc; - - @Test - @WithMockUser - void testGetAllExamples() throws Exception { - String exampleId1 = UUID.randomUUID().toString(); - String exampleId2 = UUID.randomUUID().toString(); - - ExampleModel example1 = new ExampleModel(); - example1.setExampleGuid(exampleId1); - - ExampleModel example2 = new ExampleModel(); - example2.setExampleGuid(exampleId2); - - List exampleList = Arrays.asList(example1, example1); - CollectionModel collectionModel = CollectionModel.of(exampleList); - - when(exampleService.getAllExamples()).thenReturn(collectionModel); - - mockMvc.perform(get("/wfprev/examples") - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); - } - - @Test - @WithMockUser - void testGetExampleById() throws Exception { - String exampleId = UUID.randomUUID().toString(); - ExampleModel exampleModel = new ExampleModel(); - exampleModel.setExampleGuid(exampleId); - - when(exampleService.getExampleById(exampleId)).thenReturn(exampleModel); - - mockMvc.perform(get("/wfprev/examples/{id}", exampleId) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); - } - - @Test - @WithMockUser - void testGetExampleByIdNotFound() throws Exception { - String exampleId = null; - ExampleModel exampleModel = new ExampleModel(); - - when(exampleService.getExampleById(null)).thenReturn(exampleModel); - - mockMvc.perform(get("/wfprev/examples/{id}", exampleId) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isNotFound()); - } - - @Test - @WithMockUser - void getUserNotFoundCodeById() throws Exception { - String exampleCodeId = "INVALID_CODE"; - - when(exampleService.getExampleCodeById(eq(exampleCodeId))).thenReturn(null); - - mockMvc.perform(get("/wfprev/exampleCodes/{id}", exampleCodeId)) - .andExpect(status().isNotFound()); - } - - @Test - @WithMockUser - void getExampleCodeById() throws Exception { - String exampleCodeId = "VALID_CODE"; - ExampleCodeModel exampleCodeModel = new ExampleCodeModel(); - exampleCodeModel.setExampleCode(exampleCodeId); - - when(exampleService.getExampleCodeById(eq(exampleCodeId))).thenReturn(exampleCodeModel); - - mockMvc.perform(get("/wfprev/exampleCodes/{id}", exampleCodeId)) - .andExpect(status().isOk()); - - } -} From 2611135cbd792721ef293fb13f97637e22b83900 Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Thu, 21 Nov 2024 16:36:56 -0800 Subject: [PATCH 08/15] Project Controller test stub --- .../gov/nrs/wfprev/ProjectControllerTest.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java new file mode 100644 index 000000000..c1dc844f3 --- /dev/null +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java @@ -0,0 +1,68 @@ +package ca.bc.gov.nrs.wfprev; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import static org.mockito.Mockito.when; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.hateoas.CollectionModel; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import ca.bc.gov.nrs.wfprev.controllers.ProjectController; +import ca.bc.gov.nrs.wfprev.data.models.ProjectModel; +import ca.bc.gov.nrs.wfprev.services.ProjectService; + +@WebMvcTest(ProjectController.class) +@Import({SecurityConfig.class, TestcontainersConfiguration.class}) +class ProjectControllerTest { + @MockBean + private ProjectService projectService; + + @Autowired + private MockMvc mockMvc; + + @Test + @WithMockUser + void testGetProject() throws Exception { + String guid = UUID.randomUUID().toString(); + + ProjectModel project = new ProjectModel(); + project.setProjectGuid(guid); + + List projectList = Arrays.asList(project); + CollectionModel projectModel = CollectionModel.of(projectList); + + when(projectService.getAllProjects()).thenReturn(projectModel); + + mockMvc.perform(get("/projects") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + when(projectService.getProjectById(guid)).thenReturn(project); + + mockMvc.perform(get("/projects/{id}", guid) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + @WithMockUser + void testCreateProject() throws Exception { + ProjectModel project = new ProjectModel(); + when(projectService.createOrUpdateProject(project)).thenReturn(project); + + mockMvc.perform(post("/projects", project) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()); + } +} From 5b50ef2f16c30acdf17c0531a63ef12e62a1da70 Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Thu, 21 Nov 2024 17:09:05 -0800 Subject: [PATCH 09/15] Project test stub updates --- .../gov/nrs/wfprev/ProjectControllerTest.java | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java index c1dc844f3..edea5e1f6 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java @@ -16,6 +16,8 @@ import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import ca.bc.gov.nrs.wfprev.controllers.ProjectController; @@ -57,12 +59,37 @@ void testGetProject() throws Exception { @Test @WithMockUser - void testCreateProject() throws Exception { + void testCreateUpdateProject() throws Exception { ProjectModel project = new ProjectModel(); when(projectService.createOrUpdateProject(project)).thenReturn(project); mockMvc.perform(post("/projects", project) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()); + + + project.setClosestCommunityName("Test"); + when(projectService.createOrUpdateProject(project)).thenReturn(project); + + mockMvc.perform(put("/projects", project) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()); + } + + @Test + @WithMockUser + void testDeleteProject() throws Exception { + ProjectModel project = new ProjectModel(); + when(projectService.createOrUpdateProject(project)).thenReturn(project); + + mockMvc.perform(post("/projects", project) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()); + + when(projectService.deleteProject(project.getProjectGuid())).thenReturn(null); + + mockMvc.perform(delete("/projects/{id}", project.getProjectGuid()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); } } From 80c598c6dd85b4c7926d6b59d15f6e24f8ec0414 Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Fri, 22 Nov 2024 09:41:23 -0800 Subject: [PATCH 10/15] Program Area and Project Boundary test stubs --- .../nrs/wfprev/ProgramAreaControllerTest.java | 95 +++++++++++++++++++ .../wfprev/ProjectBoundaryControllerTest.java | 95 +++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java create mode 100644 server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java new file mode 100644 index 000000000..a3eee94c6 --- /dev/null +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java @@ -0,0 +1,95 @@ +package ca.bc.gov.nrs.wfprev; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import static org.mockito.Mockito.when; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.hateoas.CollectionModel; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import ca.bc.gov.nrs.wfprev.controllers.ProgramAreaController; +import ca.bc.gov.nrs.wfprev.data.models.ProgramAreaModel; +import ca.bc.gov.nrs.wfprev.services.ProgramAreaService; + +@WebMvcTest(ProgramAreaController.class) +@Import({SecurityConfig.class, TestcontainersConfiguration.class}) +class ProgramAreaControllerTest { + @MockBean + private ProgramAreaService programAreaService; + + @Autowired + private MockMvc mockMvc; + + @Test + @WithMockUser + void testGetProject() throws Exception { + String guid = UUID.randomUUID().toString(); + + ProgramAreaModel programArea = new ProgramAreaModel(); + programArea.setProgramAreaGuid(guid); + + List programAreaList = Arrays.asList(programArea); + CollectionModel programAreaModel = CollectionModel.of(programAreaList); + + when(programAreaService.getAllProgramAreas()).thenReturn(programAreaModel); + + mockMvc.perform(get("/programAreas") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + when(programAreaService.getProgramAreaById(guid)).thenReturn(programArea); + + mockMvc.perform(get("/programAreas/{id}", guid) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + @WithMockUser + void testCreateUpdateProject() throws Exception { + ProgramAreaModel programArea = new ProgramAreaModel(); + when(programAreaService.createOrUpdateProgramArea(programArea)).thenReturn(programArea); + + mockMvc.perform(post("/programAreas", programArea) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()); + + + programArea.setProgramAreaName("Test"); + when(programAreaService.createOrUpdateProgramArea(programArea)).thenReturn(programArea); + + mockMvc.perform(put("/programAreas", programArea) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()); + } + + @Test + @WithMockUser + void testDeleteProject() throws Exception { + ProgramAreaModel programArea = new ProgramAreaModel(); + when(programAreaService.createOrUpdateProgramArea(programArea)).thenReturn(programArea); + + mockMvc.perform(post("/programArea", programArea) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()); + + when(programAreaService.deleteProgramArea(programArea.getProgramAreaGuid())).thenReturn(null); + + mockMvc.perform(delete("/programArea/{id}", programArea.getProgramAreaGuid()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } +} diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java new file mode 100644 index 000000000..00b51df2e --- /dev/null +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java @@ -0,0 +1,95 @@ +package ca.bc.gov.nrs.wfprev; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import static org.mockito.Mockito.when; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.hateoas.CollectionModel; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import ca.bc.gov.nrs.wfprev.controllers.ProjectBoundaryController; +import ca.bc.gov.nrs.wfprev.data.models.ProjectBoundaryModel; +import ca.bc.gov.nrs.wfprev.services.ProjectBoundaryService; + +@WebMvcTest(ProjectBoundaryController.class) +@Import({SecurityConfig.class, TestcontainersConfiguration.class}) +class ProjectBoundaryControllerTest { + @MockBean + private ProjectBoundaryService projectBoundaryService; + + @Autowired + private MockMvc mockMvc; + + @Test + @WithMockUser + void testGetProject() throws Exception { + String guid = UUID.randomUUID().toString(); + + ProjectBoundaryModel project = new ProjectBoundaryModel(); + project.setProjectGuid(guid); + + List projectList = Arrays.asList(project); + CollectionModel projectModel = CollectionModel.of(projectList); + + when(projectBoundaryService.getAllProjectBoundaries()).thenReturn(projectModel); + + mockMvc.perform(get("/projectBoundaries") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + when(projectBoundaryService.getProjectBoundaryById(guid)).thenReturn(project); + + mockMvc.perform(get("/projectBoundaries/{id}", guid) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + @WithMockUser + void testCreateUpdateProject() throws Exception { + ProjectBoundaryModel project = new ProjectBoundaryModel(); + when(projectBoundaryService.createOrUpdateProjectBoundary(project)).thenReturn(project); + + mockMvc.perform(post("/projectBoundaries", project) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()); + + + project.setBoundaryComment("Test"); + when(projectBoundaryService.createOrUpdateProjectBoundary(project)).thenReturn(project); + + mockMvc.perform(put("/projectBoundaries", project) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()); + } + + @Test + @WithMockUser + void testDeleteProject() throws Exception { + ProjectBoundaryModel project = new ProjectBoundaryModel(); + when(projectBoundaryService.createOrUpdateProjectBoundary(project)).thenReturn(project); + + mockMvc.perform(post("/projectBoundaries", project) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()); + + when(projectBoundaryService.deleteProjectBoundary(project.getProjectGuid())).thenReturn(null); + + mockMvc.perform(delete("/projectBoundaries/{id}", project.getProjectGuid()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } +} From 3355606d4e3e9d5fa2d41f9e0a4f44f0a650ae52 Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Sat, 23 Nov 2024 13:19:07 -0800 Subject: [PATCH 11/15] Add updated geojson serializers/deserializers --- .../ca/bc/gov/nrs/wfprev/SecurityConfig.java | 4 +- .../GeoJsonJacksonDeserializer.java | 47 ++++++++ .../serializers/GeoJsonJacksonSerializer.java | 37 +++++++ .../controllers/ProgramAreaController.java | 4 +- .../ProjectBoundaryController.java | 5 +- .../wfprev/controllers/ProjectController.java | 4 +- .../data/entities/ForestAreaCodeEntity.java | 4 +- .../data/entities/GeneralScopeCodeEntity.java | 4 +- .../data/entities/ProjectBoundaryEntity.java | 7 +- .../data/entities/ProjectTypeCodeEntity.java | 4 +- .../data/models/ProjectBoundaryModel.java | 2 +- .../MockMvcRestExceptionConfiguration.java | 38 +++++++ .../nrs/wfprev/MockMvcVExceptionAdvice.java | 31 ++++++ .../nrs/wfprev/ProgramAreaControllerTest.java | 59 ++++++++--- .../wfprev/ProjectBoundaryControllerTest.java | 85 ++++++++++++--- .../gov/nrs/wfprev/ProjectControllerTest.java | 57 ++++++++-- .../bc/gov/nrs/wfprev/TestSpringSecurity.java | 100 ++++++++++++++++++ 17 files changed, 436 insertions(+), 56 deletions(-) create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/serializers/GeoJsonJacksonDeserializer.java create mode 100644 server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/serializers/GeoJsonJacksonSerializer.java create mode 100644 server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/MockMvcRestExceptionConfiguration.java create mode 100644 server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/MockMvcVExceptionAdvice.java create mode 100644 server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestSpringSecurity.java diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/SecurityConfig.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/SecurityConfig.java index 637222523..68dadceef 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/SecurityConfig.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/SecurityConfig.java @@ -44,7 +44,7 @@ AuthenticationEntryPoint authenticationEntryPoint() { BasicAuthenticationEntryPoint result; result = new BasicAuthenticationEntryPoint(); - result.setRealmName("wfim-incidents-api"); + result.setRealmName("wfprev-api"); return result; } @@ -60,7 +60,7 @@ public TokenService tokenServiceImpl() { @Bean public AuthenticationProvider authenticationProvider() { - return new WebadeOauth2AuthenticationProvider(tokenServiceImpl(), "WFIM.*"); + return new WebadeOauth2AuthenticationProvider(tokenServiceImpl(), "WFPREV.*"); } @Bean diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/serializers/GeoJsonJacksonDeserializer.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/serializers/GeoJsonJacksonDeserializer.java new file mode 100644 index 000000000..560f4074c --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/serializers/GeoJsonJacksonDeserializer.java @@ -0,0 +1,47 @@ +package ca.bc.gov.nrs.wfprev.common.serializers; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.geojson.GeoJsonReader; + +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; + +@Slf4j +public class GeoJsonJacksonDeserializer extends StdDeserializer { + + public GeoJsonJacksonDeserializer() { + super(Geometry.class); + } + + public Geometry deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException { + log.trace("deserialize " + result); + return result; + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/serializers/GeoJsonJacksonSerializer.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/serializers/GeoJsonJacksonSerializer.java new file mode 100644 index 000000000..6722347ee --- /dev/null +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/common/serializers/GeoJsonJacksonSerializer.java @@ -0,0 +1,37 @@ +package ca.bc.gov.nrs.wfprev.common.serializers; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.io.geojson.GeoJsonWriter; + +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.io.StringWriter; + +@Slf4j +public class GeoJsonJacksonSerializer extends StdSerializer { + + public GeoJsonJacksonSerializer() { + super(Geometry.class); + } + + public void serialize(Geometry geometry, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException { + log.trace("serialize"); + } +} diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java index ed3c18721..c1e488fc0 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProgramAreaController.java @@ -46,7 +46,7 @@ public ProgramAreaController(ProgramAreaService programAreaService) { this.programAreaService = programAreaService; } - @GetMapping("/") + @GetMapping @Operation(summary = "Fetch all Program Area Resources", description = "Fetch all Program Area Resources", security = @SecurityRequirement(name = "Webade-OAUTH2", @@ -93,7 +93,7 @@ public ResponseEntity getById(@PathVariable("id") String id) { return response; } - @PostMapping("/") + @PostMapping @Operation(summary = "Create a Program Area Resource", description = "Create a Program Area Resource", security = @SecurityRequirement(name = "Webade-OAUTH2", diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java index 76ea4e55a..45126514b 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectBoundaryController.java @@ -4,6 +4,7 @@ import java.util.UUID; import org.springframework.hateoas.CollectionModel; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -45,7 +46,7 @@ public ProjectBoundaryController(ProjectBoundaryService projectBoundaryService) this.projectBoundaryService = projectBoundaryService; } - @GetMapping("/") + @GetMapping @Operation(summary = "Fetch all Project Boundary Resources", description = "Fetch all Project Boundary Resources", security = @SecurityRequirement(name = "Webade-OAUTH2", @@ -92,7 +93,7 @@ public ResponseEntity getById(@PathVariable("id") String i return response; } - @PostMapping("/") + @PostMapping(consumes = "application/json") @Operation(summary = "Create a project boundary Resource", description = "Create a project boundary Resource", security = @SecurityRequirement(name = "Webade-OAUTH2", diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java index 001dce484..a8b5e6b19 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/controllers/ProjectController.java @@ -45,7 +45,7 @@ public ProjectController(ProjectService projectService) { this.projectService = projectService; } - @GetMapping("/") + @GetMapping @Operation(summary = "Fetch all Project Resources", description = "Fetch all Project Resources", security = @SecurityRequirement(name = "Webade-OAUTH2", @@ -92,7 +92,7 @@ public ResponseEntity getById(@PathVariable("id") String id) { return response; } - @PostMapping("/") + @PostMapping @Operation(summary = "Create a Project Resource", description = "Create a Project Resource", security = @SecurityRequirement(name = "Webade-OAUTH2", diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ForestAreaCodeEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ForestAreaCodeEntity.java index d26e39d3d..758df72bf 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ForestAreaCodeEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ForestAreaCodeEntity.java @@ -46,11 +46,11 @@ public class ForestAreaCodeEntity implements Serializable { private Integer displayOrder; @NotNull - @Column(name = "effective_date", length = 200) + @Column(name = "effective_date") private Date effectiveDate; @NotNull - @Column(name = "expiry_date", length = 200) + @Column(name = "expiry_date") private Date expiryDate; @Column(name = "revision_count", columnDefinition="Decimal(10) default '0'") diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/GeneralScopeCodeEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/GeneralScopeCodeEntity.java index af8f4fc26..efd4b11a5 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/GeneralScopeCodeEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/GeneralScopeCodeEntity.java @@ -46,11 +46,11 @@ public class GeneralScopeCodeEntity implements Serializable { private Integer displayOrder; @NotNull - @Column(name = "effective_date", length = 200) + @Column(name = "effective_date") private Date effectiveDate; @NotNull - @Column(name = "expiry_date", length = 200) + @Column(name = "expiry_date") private Date expiryDate; @Column(name = "revision_count", columnDefinition="Decimal(10) default '0'") diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectBoundaryEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectBoundaryEntity.java index 0cb262c63..83650ed4e 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectBoundaryEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectBoundaryEntity.java @@ -14,10 +14,9 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.Point; -import ca.bc.gov.nrs.common.wfone.rest.resource.transformers.GeoJsonJacksonDeserializer; -import ca.bc.gov.nrs.common.wfone.rest.resource.transformers.GeoJsonJacksonSerializer; +import ca.bc.gov.nrs.wfprev.common.serializers.GeoJsonJacksonDeserializer; +import ca.bc.gov.nrs.wfprev.common.serializers.GeoJsonJacksonSerializer; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -83,7 +82,7 @@ public class ProjectBoundaryEntity implements Serializable { @JsonSerialize(using=GeoJsonJacksonSerializer.class) @JsonDeserialize(using=GeoJsonJacksonDeserializer.class) @Column(name="location_geometry", columnDefinition = "geometry(Point,4326)") - public Point locationGeometry; + public Geometry locationGeometry; @NotNull @JsonSerialize(using=GeoJsonJacksonSerializer.class) diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectTypeCodeEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectTypeCodeEntity.java index 3fb86c029..bafeb4aaa 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectTypeCodeEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectTypeCodeEntity.java @@ -45,11 +45,11 @@ public class ProjectTypeCodeEntity implements Serializable { private Integer displayOrder; @NotNull - @Column(name = "effective_date", length = 200) + @Column(name = "effective_date") private Date effectiveDate; @NotNull - @Column(name = "expiry_date", length = 200) + @Column(name = "expiry_date") private Date expiryDate; @Column(name = "revision_count", columnDefinition="Decimal(10) default '0'") diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectBoundaryModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectBoundaryModel.java index ead76e2d6..c5ddd155c 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectBoundaryModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectBoundaryModel.java @@ -37,6 +37,6 @@ public class ProjectBoundaryModel extends CommonModel { private String collectorName; private BigDecimal boundarySizeHa; private String boundaryComment; - private Point locationGeometry; + private Geometry locationGeometry; private Geometry boundaryGeometry; } diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/MockMvcRestExceptionConfiguration.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/MockMvcRestExceptionConfiguration.java new file mode 100644 index 000000000..1acbc65be --- /dev/null +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/MockMvcRestExceptionConfiguration.java @@ -0,0 +1,38 @@ +package ca.bc.gov.nrs.wfprev; + +import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +@TestConfiguration +public class MockMvcRestExceptionConfiguration implements WebMvcConfigurer { + private final BasicErrorController errorController; + + public MockMvcRestExceptionConfiguration (final BasicErrorController basicErrorController) { + this.errorController = basicErrorController; + } + + @Override + public void addInterceptors (final InterceptorRegistry registry) { + registry.addInterceptor( + new HandlerInterceptor() { + @Override + public void afterCompletion (final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception ex) throws Exception { + final int status = response.getStatus(); + + if (status >= 400) { + request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, status); + new ObjectMapper().writeValue(response.getOutputStream(), MockMvcRestExceptionConfiguration.this.errorController.error(request).getBody()); + } + } + }); + } +} \ No newline at end of file diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/MockMvcVExceptionAdvice.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/MockMvcVExceptionAdvice.java new file mode 100644 index 000000000..414f028a0 --- /dev/null +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/MockMvcVExceptionAdvice.java @@ -0,0 +1,31 @@ +package ca.bc.gov.nrs.wfprev; + +import org.springframework.core.annotation.AnnotationUtils; +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.servlet.ModelAndView; +import jakarta.servlet.http.HttpServletRequest; + +@ControllerAdvice +public class MockMvcVExceptionAdvice { + + public static final String DEFAULT_ERROR_VIEW = "error"; + + @ExceptionHandler(value = Exception.class) + public ModelAndView + defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception { + // If the exception is annotated with @ResponseStatus rethrow it and let + // the framework handle it - like the OrderNotFoundException example + // at the start of this post. + // AnnotationUtils is a Spring Framework utility class. + if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) throw e; + + // Otherwise setup and send the user to a default error-view. + ModelAndView mav = new ModelAndView(); + mav.addObject("exception", e); + mav.addObject("url", req.getRequestURL()); + mav.setViewName(DEFAULT_ERROR_VIEW); + return mav; + } +} \ No newline at end of file diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java index a3eee94c6..cd7deb70c 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.mockito.Mockito.when; import org.springframework.beans.factory.annotation.Autowired; @@ -14,6 +15,10 @@ import org.springframework.http.MediaType; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; + +import com.nimbusds.jose.shaded.gson.Gson; +import com.nimbusds.jose.shaded.gson.GsonBuilder; + import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; @@ -25,17 +30,26 @@ import ca.bc.gov.nrs.wfprev.services.ProgramAreaService; @WebMvcTest(ProgramAreaController.class) -@Import({SecurityConfig.class, TestcontainersConfiguration.class}) +@Import({TestSpringSecurity.class, TestcontainersConfiguration.class}) class ProgramAreaControllerTest { @MockBean private ProgramAreaService programAreaService; @Autowired private MockMvc mockMvc; + + private Gson gson; + + @BeforeEach + void setup() { + GsonBuilder builder = new GsonBuilder(); + builder.serializeNulls().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").serializeSpecialFloatingPointValues(); + gson = builder.create(); + } @Test @WithMockUser - void testGetProject() throws Exception { + void testGetProgramArea() throws Exception { String guid = UUID.randomUUID().toString(); ProgramAreaModel programArea = new ProgramAreaModel(); @@ -46,7 +60,7 @@ void testGetProject() throws Exception { when(programAreaService.getAllProgramAreas()).thenReturn(programAreaModel); - mockMvc.perform(get("/programAreas") + mockMvc.perform(get("/programAreas/") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); @@ -59,37 +73,52 @@ void testGetProject() throws Exception { @Test @WithMockUser - void testCreateUpdateProject() throws Exception { + void testCreateUpdateProgramArea() throws Exception { ProgramAreaModel programArea = new ProgramAreaModel(); + programArea.setProgramAreaName("Test"); when(programAreaService.createOrUpdateProgramArea(programArea)).thenReturn(programArea); - mockMvc.perform(post("/programAreas", programArea) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isCreated()); + String json = gson.toJson(programArea); + mockMvc.perform(post("/programAreas") + .content(json) + .contentType(MediaType.APPLICATION_JSON) + .accept("application/json") + .header("Authorization", "Bearer admin-token")) + .andExpect(status().isCreated()); - programArea.setProgramAreaName("Test"); + + programArea.setProgramAreaName("Test Change"); when(programAreaService.createOrUpdateProgramArea(programArea)).thenReturn(programArea); - mockMvc.perform(put("/programAreas", programArea) - .contentType(MediaType.APPLICATION_JSON)) + json = gson.toJson(programArea); + + mockMvc.perform(put("/programAreas/") + .content(json) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer admin-token")) .andExpect(status().isCreated()); } @Test @WithMockUser - void testDeleteProject() throws Exception { + void testDeleteProgramArea() throws Exception { ProgramAreaModel programArea = new ProgramAreaModel(); when(programAreaService.createOrUpdateProgramArea(programArea)).thenReturn(programArea); - mockMvc.perform(post("/programArea", programArea) - .contentType(MediaType.APPLICATION_JSON)) + String json = gson.toJson(programArea); + + mockMvc.perform(post("/programAreas/") + .content(json) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer admin-token")) .andExpect(status().isCreated()); when(programAreaService.deleteProgramArea(programArea.getProgramAreaGuid())).thenReturn(null); - mockMvc.perform(delete("/programArea/{id}", programArea.getProgramAreaGuid()) - .contentType(MediaType.APPLICATION_JSON)) + mockMvc.perform(delete("/programAreas/{id}", programArea.getProgramAreaGuid()) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer admin-token")) .andExpect(status().isOk()); } } diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java index 00b51df2e..671324cde 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java @@ -1,10 +1,14 @@ package ca.bc.gov.nrs.wfprev; +import java.math.BigDecimal; import java.util.Arrays; +import java.util.Date; import java.util.List; import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; + import static org.mockito.Mockito.when; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -14,28 +18,49 @@ import org.springframework.http.MediaType; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; + +import com.fasterxml.jackson.core.Version; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.nimbusds.jose.shaded.gson.Gson; +import com.nimbusds.jose.shaded.gson.GsonBuilder; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; + import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import ca.bc.gov.nrs.wfprev.common.serializers.GeoJsonJacksonDeserializer; +import ca.bc.gov.nrs.wfprev.common.serializers.GeoJsonJacksonSerializer; import ca.bc.gov.nrs.wfprev.controllers.ProjectBoundaryController; import ca.bc.gov.nrs.wfprev.data.models.ProjectBoundaryModel; import ca.bc.gov.nrs.wfprev.services.ProjectBoundaryService; @WebMvcTest(ProjectBoundaryController.class) -@Import({SecurityConfig.class, TestcontainersConfiguration.class}) +@Import({TestSpringSecurity.class, TestcontainersConfiguration.class, MockMvcRestExceptionConfiguration.class}) class ProjectBoundaryControllerTest { @MockBean private ProjectBoundaryService projectBoundaryService; @Autowired private MockMvc mockMvc; + + private Gson gson; + @BeforeEach + void setup() { + GsonBuilder builder = new GsonBuilder(); + builder.serializeNulls().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").serializeSpecialFloatingPointValues(); + gson = builder.create(); + } + @Test @WithMockUser - void testGetProject() throws Exception { + void testGetProjectBoundary() throws Exception { String guid = UUID.randomUUID().toString(); ProjectBoundaryModel project = new ProjectBoundaryModel(); @@ -46,7 +71,7 @@ void testGetProject() throws Exception { when(projectBoundaryService.getAllProjectBoundaries()).thenReturn(projectModel); - mockMvc.perform(get("/projectBoundaries") + mockMvc.perform(get("/projectBoundaries/") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); @@ -58,38 +83,72 @@ void testGetProject() throws Exception { } @Test - @WithMockUser - void testCreateUpdateProject() throws Exception { + void testCreateUpdateProjectBoundary() throws Exception { ProjectBoundaryModel project = new ProjectBoundaryModel(); + + project.setBoundaryComment("test"); + project.setCollectionMethod("test"); + project.setSystemStartTimestamp(new Date()); + project.setSystemEndTimestamp(new Date()); + project.setProjectBoundaryGuid(UUID.randomUUID().toString()); + project.setCollectionDate(new Date()); + project.setBoundarySizeHa(BigDecimal.ONE); + project.setLocationGeometry((Geometry) new GeometryFactory().createPoint(new Coordinate(1, 1))); + + Coordinate[] coords = new Coordinate[] {new Coordinate(1, 1), new Coordinate(2, 1), new Coordinate(2, 2), new Coordinate(1, 2), new Coordinate(1, 1)}; + project.setBoundaryGeometry(new GeometryFactory().createPolygon(coords)); + when(projectBoundaryService.createOrUpdateProjectBoundary(project)).thenReturn(project); - mockMvc.perform(post("/projectBoundaries", project) - .contentType(MediaType.APPLICATION_JSON)) + // use the jackson mapper for handling Geometry types, Gson converters aren't + // implemented yet + ObjectMapper mapper = new ObjectMapper(); + SimpleModule simpleModule = new SimpleModule(); + simpleModule.addSerializer(new GeoJsonJacksonSerializer()); + simpleModule.addDeserializer(Geometry.class, new GeoJsonJacksonDeserializer()); + mapper.registerModule(simpleModule); + + String json = mapper.writeValueAsString(project); + + mockMvc.perform(post("/projectBoundaries") + .content(json) + .contentType(MediaType.APPLICATION_JSON) + .accept("application/json") + .header("Authorization", "Bearer admin-token")) .andExpect(status().isCreated()); project.setBoundaryComment("Test"); when(projectBoundaryService.createOrUpdateProjectBoundary(project)).thenReturn(project); - mockMvc.perform(put("/projectBoundaries", project) - .contentType(MediaType.APPLICATION_JSON)) + json = gson.toJson(project); + + mockMvc.perform(put("/projectBoundaries/{id}") + .content(json) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer admin-token")) .andExpect(status().isCreated()); } @Test @WithMockUser - void testDeleteProject() throws Exception { + void testDeleteProjectBoundary() throws Exception { ProjectBoundaryModel project = new ProjectBoundaryModel(); when(projectBoundaryService.createOrUpdateProjectBoundary(project)).thenReturn(project); - mockMvc.perform(post("/projectBoundaries", project) - .contentType(MediaType.APPLICATION_JSON)) + String json = gson.toJson(project); + + mockMvc.perform(post("/projectBoundaries/") + .content(json) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer admin-token")) .andExpect(status().isCreated()); when(projectBoundaryService.deleteProjectBoundary(project.getProjectGuid())).thenReturn(null); mockMvc.perform(delete("/projectBoundaries/{id}", project.getProjectGuid()) - .contentType(MediaType.APPLICATION_JSON)) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer admin-token")) .andExpect(status().isOk()); } } diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java index edea5e1f6..310e3de72 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java @@ -1,9 +1,11 @@ package ca.bc.gov.nrs.wfprev; import java.util.Arrays; +import java.util.Date; import java.util.List; import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.mockito.Mockito.when; import org.springframework.beans.factory.annotation.Autowired; @@ -14,6 +16,9 @@ import org.springframework.http.MediaType; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; +import com.nimbusds.jose.shaded.gson.Gson; +import com.nimbusds.jose.shaded.gson.GsonBuilder; + import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; @@ -22,10 +27,11 @@ import ca.bc.gov.nrs.wfprev.controllers.ProjectController; import ca.bc.gov.nrs.wfprev.data.models.ProjectModel; +import ca.bc.gov.nrs.wfprev.data.models.ProjectTypeCodeModel; import ca.bc.gov.nrs.wfprev.services.ProjectService; @WebMvcTest(ProjectController.class) -@Import({SecurityConfig.class, TestcontainersConfiguration.class}) +@Import({TestSpringSecurity.class, TestcontainersConfiguration.class}) class ProjectControllerTest { @MockBean private ProjectService projectService; @@ -33,6 +39,15 @@ class ProjectControllerTest { @Autowired private MockMvc mockMvc; + private Gson gson; + + @BeforeEach + void setup() { + GsonBuilder builder = new GsonBuilder(); + builder.serializeNulls().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").serializeSpecialFloatingPointValues(); + gson = builder.create(); + } + @Test @WithMockUser void testGetProject() throws Exception { @@ -61,18 +76,36 @@ void testGetProject() throws Exception { @WithMockUser void testCreateUpdateProject() throws Exception { ProjectModel project = new ProjectModel(); + project.setProjectTypeCode(new ProjectTypeCodeModel()); + project.setProjectNumber(1); + project.setSiteUnitName("Test"); + project.setProgramAreaGuid(UUID.randomUUID().toString()); + project.setProjectName("Test"); + project.setIsMultiFiscalYearProj(false); + project.setLatitude(40.99); + project.setLongitude(-115.23); + project.setLastProgressUpdateTimestamp(new Date()); + when(projectService.createOrUpdateProject(project)).thenReturn(project); - mockMvc.perform(post("/projects", project) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isCreated()); + String json = gson.toJson(project); + mockMvc.perform(post("/projects") + .contentType(MediaType.APPLICATION_JSON) + .content(json) + .accept("application/json") + .header("Authorization", "Bearer admin-token")) + .andExpect(status().isCreated()); project.setClosestCommunityName("Test"); when(projectService.createOrUpdateProject(project)).thenReturn(project); - mockMvc.perform(put("/projects", project) - .contentType(MediaType.APPLICATION_JSON)) + json = gson.toJson(project); + + mockMvc.perform(put("/projects/{id}") + .content(json) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer admin-token")) .andExpect(status().isCreated()); } @@ -82,14 +115,20 @@ void testDeleteProject() throws Exception { ProjectModel project = new ProjectModel(); when(projectService.createOrUpdateProject(project)).thenReturn(project); - mockMvc.perform(post("/projects", project) - .contentType(MediaType.APPLICATION_JSON)) + String json = gson.toJson(project); + + mockMvc.perform(post("/projects") + .content(json) + .contentType(MediaType.APPLICATION_JSON) + .accept("application/json") + .header("Authorization", "Bearer admin-token")) .andExpect(status().isCreated()); when(projectService.deleteProject(project.getProjectGuid())).thenReturn(null); mockMvc.perform(delete("/projects/{id}", project.getProjectGuid()) - .contentType(MediaType.APPLICATION_JSON)) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer admin-token")) .andExpect(status().isOk()); } } diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestSpringSecurity.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestSpringSecurity.java new file mode 100644 index 000000000..c34958e84 --- /dev/null +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestSpringSecurity.java @@ -0,0 +1,100 @@ +package ca.bc.gov.nrs.wfprev; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Properties; + +import org.mockito.Mockito; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationManagerResolver; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.core.OAuth2AccessToken.TokenType; +import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; + +import ca.bc.gov.nrs.wfone.common.webade.oauth2.authentication.WebAdeOAuth2Authentication; +import jakarta.servlet.http.HttpServletRequest; + +@TestConfiguration +public class TestSpringSecurity { + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .csrf(AbstractHttpConfigurer::disable) + .authorizeHttpRequests(auth -> auth + .requestMatchers("/actuator/health").permitAll() + .anyRequest().authenticated() + ) + .oauth2ResourceServer(oauth2 -> oauth2 + .authenticationManagerResolver(authenticationManagerResolver()) + ) + .httpBasic() + .and() + .exceptionHandling(exceptionHandling -> exceptionHandling + .authenticationEntryPoint(authenticationEntryPoint())); + + return http.build(); + } + + @Bean + AuthenticationEntryPoint authenticationEntryPoint() { + BasicAuthenticationEntryPoint result; + + result = new BasicAuthenticationEntryPoint(); + result.setRealmName("wfprev-api"); + + return result; + } + + @Bean + public AuthenticationManagerResolver authenticationManagerResolver() { + return new AuthenticationManagerResolver() { + @Override + public AuthenticationManager resolve(HttpServletRequest httpServletRequest) { + return new AuthenticationManager() { + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + // Add different Authentications based on roles here + // can be filtered via the fake token passed in + OAuth2AuthenticatedPrincipal principal = Mockito.mock(OAuth2AuthenticatedPrincipal.class); + Collection authorities = new ArrayList<>(); + OAuth2AccessToken token = new OAuth2AccessToken(TokenType.BEARER, "admin-token", Instant.now(), Instant.MAX); + Authentication basicUser = new WebAdeOAuth2Authentication(principal, token, authorities,"WFPREV", "test", "test", "GOV", "test'", "test", "test", (long) 0, null, null, null, "businessNumber", "businessGuid"); + + return basicUser; + } + }; + } + }; + } + + @Bean + @Primary + public InMemoryUserDetailsManager authUserService() { + UserDetails admin = User.withUsername("Admin").password("admin").roles("WFPREV", "READ", "WRITE", "ADMIN").build(); + UserDetails write = User.withUsername("Write").password("write").roles("WFPREV","READ", "WRITE").build(); + UserDetails read = User.withUsername("Read").password("read").roles("WFPREV","READ").build(); + + return new InMemoryUserDetailsManager(Arrays.asList( + read, write, admin + )); + } +} From d44952f4ee822b906f030c3122855b7332f07179 Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Sat, 23 Nov 2024 13:23:51 -0800 Subject: [PATCH 12/15] Remove unused slashes/mappings --- .../ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java | 6 +++--- .../ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java index cd7deb70c..4f6015a40 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProgramAreaControllerTest.java @@ -60,7 +60,7 @@ void testGetProgramArea() throws Exception { when(programAreaService.getAllProgramAreas()).thenReturn(programAreaModel); - mockMvc.perform(get("/programAreas/") + mockMvc.perform(get("/programAreas") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); @@ -93,7 +93,7 @@ void testCreateUpdateProgramArea() throws Exception { json = gson.toJson(programArea); - mockMvc.perform(put("/programAreas/") + mockMvc.perform(put("/programAreas/{id}") .content(json) .contentType(MediaType.APPLICATION_JSON) .header("Authorization", "Bearer admin-token")) @@ -108,7 +108,7 @@ void testDeleteProgramArea() throws Exception { String json = gson.toJson(programArea); - mockMvc.perform(post("/programAreas/") + mockMvc.perform(post("/programAreas") .content(json) .contentType(MediaType.APPLICATION_JSON) .header("Authorization", "Bearer admin-token")) diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java index 671324cde..cd01e6022 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java @@ -71,7 +71,7 @@ void testGetProjectBoundary() throws Exception { when(projectBoundaryService.getAllProjectBoundaries()).thenReturn(projectModel); - mockMvc.perform(get("/projectBoundaries/") + mockMvc.perform(get("/projectBoundaries") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); @@ -138,7 +138,7 @@ void testDeleteProjectBoundary() throws Exception { String json = gson.toJson(project); - mockMvc.perform(post("/projectBoundaries/") + mockMvc.perform(post("/projectBoundaries") .content(json) .contentType(MediaType.APPLICATION_JSON) .header("Authorization", "Bearer admin-token")) From a14085dcd3ec784f32e8ff99430821e5f561e87f Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Mon, 25 Nov 2024 09:16:22 -0800 Subject: [PATCH 13/15] Object mapper for spatial serialization --- .../bc/gov/nrs/wfprev/WfprevApiApplication.java | 17 +++++++++++++++++ .../wfprev/ProjectBoundaryControllerTest.java | 1 - .../nrs/wfprev/TestcontainersConfiguration.java | 2 -- .../test/java/resources/application.properties | 3 +++ 4 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 server/wfprev-api/src/test/java/resources/application.properties diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/WfprevApiApplication.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/WfprevApiApplication.java index 51e616479..3e6ec273c 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/WfprevApiApplication.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/WfprevApiApplication.java @@ -9,6 +9,13 @@ import org.springframework.core.Ordered; import org.springframework.web.filter.ForwardedHeaderFilter; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.vividsolutions.jts.geom.Geometry; + +import ca.bc.gov.nrs.wfprev.common.serializers.GeoJsonJacksonDeserializer; +import ca.bc.gov.nrs.wfprev.common.serializers.GeoJsonJacksonSerializer; import jakarta.servlet.DispatcherType; @SpringBootApplication @@ -45,4 +52,14 @@ public FilterRegistrationBean forwardedHeaderFilter() { registration.setOrder(Ordered.HIGHEST_PRECEDENCE); return registration; } + + @Bean + public ObjectMapper registerObjectMapper(){ + ObjectMapper mapper = new ObjectMapper(); + SimpleModule simpleModule = new SimpleModule(); + simpleModule.addSerializer(new GeoJsonJacksonSerializer()); + simpleModule.addDeserializer(Geometry.class, new GeoJsonJacksonDeserializer()); + mapper.registerModule(simpleModule); + return mapper; + } } diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java index cd01e6022..c06bc4c45 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerTest.java @@ -19,7 +19,6 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; -import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.nimbusds.jose.shaded.gson.Gson; diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestcontainersConfiguration.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestcontainersConfiguration.java index c72cbf9d5..5f4b8f51e 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestcontainersConfiguration.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestcontainersConfiguration.java @@ -12,7 +12,6 @@ @TestConfiguration(proxyBeanMethods = false) class TestcontainersConfiguration { - @Bean @ServiceConnection PostgreSQLContainer postgresContainer() { @@ -31,5 +30,4 @@ PostgreSQLContainer postgresContainer() { return container; } - } diff --git a/server/wfprev-api/src/test/java/resources/application.properties b/server/wfprev-api/src/test/java/resources/application.properties new file mode 100644 index 000000000..81b65e514 --- /dev/null +++ b/server/wfprev-api/src/test/java/resources/application.properties @@ -0,0 +1,3 @@ +spring.liquibase.change-log=classpath:db/main-changelog.xml +spring.liquibase.drop-first=true +spring.liquibase.contexts=test \ No newline at end of file From 205a85ba7567eae15710485f9d142983b8dcda07 Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Mon, 25 Nov 2024 16:20:17 -0800 Subject: [PATCH 14/15] Add liquibase unit test example --- .../wfprev/data/entities/ProjectEntity.java | 4 +- .../nrs/wfprev/data/models/ProjectModel.java | 4 +- ...rojectBoundaryControllerLiquibaseTest.java | 172 ++++++++++++++++++ .../gov/nrs/wfprev/ProjectControllerTest.java | 5 +- .../wfprev/TestcontainersConfiguration.java | 15 +- .../java/resources/application.properties | 3 - .../resources/application-test.properties | 6 + 7 files changed, 198 insertions(+), 11 deletions(-) create mode 100644 server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerLiquibaseTest.java delete mode 100644 server/wfprev-api/src/test/java/resources/application.properties create mode 100644 server/wfprev-api/src/test/resources/application-test.properties diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java index 125de2453..dc7b51345 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/entities/ProjectEntity.java @@ -134,11 +134,11 @@ public class ProjectEntity implements Serializable { @Column(name = "latitude", precision = 9, scale = 6) @Latitude - private Double latitude; + private BigDecimal latitude; @Column(name = "longitude", precision = 9, scale = 6) @Longitude - private Double longitude; + private BigDecimal longitude; @Column(name="last_progress_update_timestamp") private Date lastProgressUpdateTimestamp; diff --git a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java index 7b1163895..f325b3f76 100644 --- a/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java +++ b/server/wfprev-api/src/main/java/ca/bc/gov/nrs/wfprev/data/models/ProjectModel.java @@ -50,7 +50,7 @@ public class ProjectModel extends CommonModel { private BigDecimal totalProjectSizeHa; private BigDecimal totalCostPerHectareAmount; private Boolean isMultiFiscalYearProj; - private Double latitude; - private Double longitude; + private BigDecimal latitude; + private BigDecimal longitude; private Date lastProgressUpdateTimestamp; } diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerLiquibaseTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerLiquibaseTest.java new file mode 100644 index 000000000..1e298c85f --- /dev/null +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectBoundaryControllerLiquibaseTest.java @@ -0,0 +1,172 @@ +package ca.bc.gov.nrs.wfprev; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.mockito.Mockito.when; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.hateoas.CollectionModel; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.servlet.MockMvc; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.nimbusds.jose.shaded.gson.Gson; +import com.nimbusds.jose.shaded.gson.GsonBuilder; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import ca.bc.gov.nrs.wfprev.common.serializers.GeoJsonJacksonDeserializer; +import ca.bc.gov.nrs.wfprev.common.serializers.GeoJsonJacksonSerializer; +import ca.bc.gov.nrs.wfprev.data.models.ProjectBoundaryModel; +import ca.bc.gov.nrs.wfprev.services.ProjectBoundaryService; + +/** + * Identical test to the Project Boundary Controller test, + * However this one will instantiate and execute the Liquibase scripts + * so instead of just mocks, we could use the container and write to the DB + * directly. + * + * Note that this will mean that the "DB" folder will need to be on the classpath + * for liquibase to find it, either copy to resources, or link through target on build + * Currently DB must be on classpath, but there is an open ticket to change to relative + * https://github.com/liquibase/liquibase/issues/2687 + */ + +@SpringBootTest +@AutoConfigureMockMvc +@Import({TestcontainersConfiguration.class, MockMvcRestExceptionConfiguration.class}) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@TestPropertySource(value = { + "classpath:application-test.properties" +}) +class ProjectBoundaryControllerLiquibaseTest { + @MockBean + private ProjectBoundaryService projectBoundaryService; + + @Autowired + private MockMvc mockMvc; + + private Gson gson; + + @BeforeEach + void setup() { + GsonBuilder builder = new GsonBuilder(); + builder.serializeNulls().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").serializeSpecialFloatingPointValues(); + gson = builder.create(); + } + + @Test + @WithMockUser + void testGetProjectBoundary() throws Exception { + String guid = UUID.randomUUID().toString(); + + ProjectBoundaryModel project = new ProjectBoundaryModel(); + project.setProjectGuid(guid); + + List projectList = Arrays.asList(project); + CollectionModel projectModel = CollectionModel.of(projectList); + + when(projectBoundaryService.getAllProjectBoundaries()).thenReturn(projectModel); + + mockMvc.perform(get("/projectBoundaries") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + when(projectBoundaryService.getProjectBoundaryById(guid)).thenReturn(project); + + mockMvc.perform(get("/projectBoundaries/{id}", guid) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + void testCreateUpdateProjectBoundary() throws Exception { + ProjectBoundaryModel project = new ProjectBoundaryModel(); + + project.setBoundaryComment("test"); + project.setCollectionMethod("test"); + project.setSystemStartTimestamp(new Date()); + project.setSystemEndTimestamp(new Date()); + project.setProjectBoundaryGuid(UUID.randomUUID().toString()); + project.setCollectionDate(new Date()); + project.setBoundarySizeHa(BigDecimal.ONE); + project.setLocationGeometry((Geometry) new GeometryFactory().createPoint(new Coordinate(1, 1))); + + Coordinate[] coords = new Coordinate[] {new Coordinate(1, 1), new Coordinate(2, 1), new Coordinate(2, 2), new Coordinate(1, 2), new Coordinate(1, 1)}; + project.setBoundaryGeometry(new GeometryFactory().createPolygon(coords)); + + when(projectBoundaryService.createOrUpdateProjectBoundary(project)).thenReturn(project); + + // use the jackson mapper for handling Geometry types, Gson converters aren't + // implemented yet + ObjectMapper mapper = new ObjectMapper(); + SimpleModule simpleModule = new SimpleModule(); + simpleModule.addSerializer(new GeoJsonJacksonSerializer()); + simpleModule.addDeserializer(Geometry.class, new GeoJsonJacksonDeserializer()); + mapper.registerModule(simpleModule); + + String json = mapper.writeValueAsString(project); + + mockMvc.perform(post("/projectBoundaries") + .content(json) + .contentType(MediaType.APPLICATION_JSON) + .accept("application/json") + .header("Authorization", "Bearer admin-token")) + .andExpect(status().isCreated()); + + + project.setBoundaryComment("Test"); + when(projectBoundaryService.createOrUpdateProjectBoundary(project)).thenReturn(project); + + json = gson.toJson(project); + + mockMvc.perform(put("/projectBoundaries/{id}") + .content(json) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer admin-token")) + .andExpect(status().isCreated()); + } + + @Test + @WithMockUser + void testDeleteProjectBoundary() throws Exception { + ProjectBoundaryModel project = new ProjectBoundaryModel(); + when(projectBoundaryService.createOrUpdateProjectBoundary(project)).thenReturn(project); + + String json = gson.toJson(project); + + mockMvc.perform(post("/projectBoundaries") + .content(json) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer admin-token")) + .andExpect(status().isCreated()); + + when(projectBoundaryService.deleteProjectBoundary(project.getProjectGuid())).thenReturn(null); + + mockMvc.perform(delete("/projectBoundaries/{id}", project.getProjectGuid()) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer admin-token")) + .andExpect(status().isOk()); + } +} diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java index 310e3de72..05add4df1 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/ProjectControllerTest.java @@ -1,5 +1,6 @@ package ca.bc.gov.nrs.wfprev; +import java.math.BigDecimal; import java.util.Arrays; import java.util.Date; import java.util.List; @@ -82,8 +83,8 @@ void testCreateUpdateProject() throws Exception { project.setProgramAreaGuid(UUID.randomUUID().toString()); project.setProjectName("Test"); project.setIsMultiFiscalYearProj(false); - project.setLatitude(40.99); - project.setLongitude(-115.23); + project.setLatitude(new BigDecimal(40.99)); + project.setLongitude(new BigDecimal(-115.23)); project.setLastProgressUpdateTimestamp(new Date()); when(projectService.createOrUpdateProject(project)).thenReturn(project); diff --git a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestcontainersConfiguration.java b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestcontainersConfiguration.java index 5f4b8f51e..d1d49eed2 100644 --- a/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestcontainersConfiguration.java +++ b/server/wfprev-api/src/test/java/ca/bc/gov/nrs/wfprev/TestcontainersConfiguration.java @@ -6,6 +6,8 @@ import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.context.annotation.Bean; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; import org.testcontainers.utility.DockerImageName; @@ -14,9 +16,10 @@ class TestcontainersConfiguration { @Bean @ServiceConnection - PostgreSQLContainer postgresContainer() { + static PostgreSQLContainer postgresContainer() { DockerImageName image = DockerImageName.parse("postgis/postgis:16-3.4").asCompatibleSubstituteFor("postgres"); PostgreSQLContainer container = new PostgreSQLContainer<>(image) + .withDatabaseName("wfprev") .withUsername("wfprev") .withPassword("password") .withExposedPorts(5432); @@ -30,4 +33,12 @@ PostgreSQLContainer postgresContainer() { return container; } -} + + @DynamicPropertySource + static void postgresqlProperties(DynamicPropertyRegistry registry) { + registry.add("spring.datasource.url", postgresContainer()::getJdbcUrl); + registry.add("spring.datasource.username", postgresContainer()::getUsername); + registry.add("spring.datasource.password", postgresContainer()::getPassword); + registry.add("spring.datasource.password", postgresContainer()::getPassword); + } +} \ No newline at end of file diff --git a/server/wfprev-api/src/test/java/resources/application.properties b/server/wfprev-api/src/test/java/resources/application.properties deleted file mode 100644 index 81b65e514..000000000 --- a/server/wfprev-api/src/test/java/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -spring.liquibase.change-log=classpath:db/main-changelog.xml -spring.liquibase.drop-first=true -spring.liquibase.contexts=test \ No newline at end of file diff --git a/server/wfprev-api/src/test/resources/application-test.properties b/server/wfprev-api/src/test/resources/application-test.properties new file mode 100644 index 000000000..bf5ffb49d --- /dev/null +++ b/server/wfprev-api/src/test/resources/application-test.properties @@ -0,0 +1,6 @@ +spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver +spring.datasource.url=jdbc:tc:postgresql://wfprev +spring.jpa.hibernate.ddl-auto=none +spring.liquibase.contexts=test +spring.liquibase.enabled=true +spring.liquibase.change-log=classpath:/db/main-changelog.json \ No newline at end of file From a7b894d09d356da64c6f55237ffa8963f23391cd Mon Sep 17 00:00:00 2001 From: Dylan Hemsworth Date: Mon, 25 Nov 2024 16:25:20 -0800 Subject: [PATCH 15/15] Add liquibase core test dependency --- server/wfprev-api/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/wfprev-api/pom.xml b/server/wfprev-api/pom.xml index 480c60f57..e36e3def4 100644 --- a/server/wfprev-api/pom.xml +++ b/server/wfprev-api/pom.xml @@ -121,6 +121,11 @@ postgresql test + + org.liquibase + liquibase-core + test +