diff --git a/.github/workflows/pr-open.yml b/.github/workflows/pr-open.yml index a0d5f23d5b..210442e8fa 100644 --- a/.github/workflows/pr-open.yml +++ b/.github/workflows/pr-open.yml @@ -98,16 +98,14 @@ jobs: packages: write strategy: matrix: - package: [backend, database, frontend,legacy] - include: - - package: backend - triggers: ('backend/') + package: [database, frontend, common] + include: - package: database triggers: ('database/') + - package: common + triggers: ('common/') - package: frontend - triggers: ('frontend/') - - package: legacy - triggers: ('legacy/') + triggers: ('frontend/') steps: - uses: actions/checkout@v3 @@ -119,10 +117,88 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} triggers: ${{ matrix.triggers }} + build-backend: + name: Backend Image Build + env: + COMPONENT: backend + ZONE: ${{ github.event.number }} + NAME: ghcr.io/${{ github.repository }}/backend:${{ github.event.number }} + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - uses: graalvm/setup-graalvm@v1 + with: + version: '22.3.0' + java-version: '17' + components: 'native-image' + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Build App + run: | + cd backend + chmod +x ./mvnw + ./mvnw -Pnative clean spring-boot:build-image \ + -Dspring-boot.build-image.imageName="${{ env.NAME }}" \ + -Doci.revision=${{ github.event.number }} -q + + - name: Log in to the Container registry + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Pushing + run: docker push ${{ env.NAME }} + build-legacy: + name: Legacy Image Build + env: + COMPONENT: legacy + ZONE: ${{ github.event.number }} + NAME: ghcr.io/${{ github.repository }}/legacy:${{ github.event.number }} + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - uses: graalvm/setup-graalvm@v1 + with: + version: '22.3.0' + java-version: '17' + components: 'native-image' + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Build App + run: | + cd legacy + chmod +x ./mvnw + ./mvnw -Pnative clean spring-boot:build-image \ + -Dspring-boot.build-image.imageName="${{ env.NAME }}" \ + -Doci.revision=${{ github.event.number }} -q + + - name: Log in to the Container registry + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Pushing + run: docker push ${{ env.NAME }} + deploy-init: name: Deploy Init needs: - builds + - build-backend environment: dev runs-on: ubuntu-22.04 steps: @@ -235,6 +311,7 @@ jobs: -p ORACLEDB_HOST=${{ secrets.ORACLEDB_HOST }} -p ORACLEDB_SERVICENAME=${{ secrets.ORACLEDB_SERVICENAME }} -p FOREST_API_URL=https://${{ github.event.repository.name }}-${{ github.event.number }}-backend.apps.silver.devops.gov.bc.ca + -p ORACLEDB_SECRET=${{ secrets.ORACLEDB_SECRET }} deploy-frontend: name: Deploy Frontend diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 34cb7e171f..37ef5a56b6 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -36,6 +36,40 @@ jobs: -Dsonar.organization=bcgov-sonarcloud -Dsonar.projectKey=forest-client-backend sonar_project_token: ${{ secrets.SONAR_TOKEN_BACKEND }} + - name: Archive CycloneDX + continue-on-error: true + uses: actions/upload-artifact@v3 + with: + name: cyclone-backend + path: target/bom.json + retention-days: 5 + + - name: Use Checkstyle report + continue-on-error: true + uses: jwgmeligmeyling/checkstyle-github-action@master + with: + path: 'backend/**/checkstyle-result.xml' + + - name: Publish Test Report + uses: mikepenz/action-junit-report@v3 + continue-on-error: true + if: success() || failure() # always run even if the previous step fails + with: + report_paths: 'backend/target/**/TEST-*.xml' + commit: ${{ github.event.pull_request.head.sha }} + summary: Pull Request Tests Backend + detailed_summary: true + job_name: Backend Tests + + - name: Add coverage to PR + id: jacoco + continue-on-error: true + uses: madrapps/jacoco-report@v1.3 + with: + paths: backend/target/coverage-reports/merged-test-report/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 75 + min-coverage-changed-files: 75 tests-legacy: name: Legacy Unit Tests @@ -54,6 +88,40 @@ jobs: -Dsonar.organization=bcgov-sonarcloud -Dsonar.projectKey=forest-client-legacy sonar_project_token: ${{ secrets.SONAR_TOKEN_LEGACY }} + - name: Archive CycloneDX + continue-on-error: true + uses: actions/upload-artifact@v3 + with: + name: cyclone-legacy + path: target/bom.json + retention-days: 5 + + - name: Use Checkstyle report + continue-on-error: true + uses: jwgmeligmeyling/checkstyle-github-action@master + with: + path: 'legacy/**/checkstyle-result.xml' + + - name: Publish Test Report + uses: mikepenz/action-junit-report@v3 + continue-on-error: true + if: success() || failure() # always run even if the previous step fails + with: + report_paths: 'legacy/target/**/TEST-*.xml' + commit: ${{ github.event.pull_request.head.sha }} + summary: Pull Request Tests Legacy + detailed_summary: true + job_name: Legacy Tests + + - name: Add coverage to PR + id: jacoco + continue-on-error: true + uses: madrapps/jacoco-report@v1.3 + with: + paths: legacy/target/coverage-reports/merged-test-report/jacoco.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 75 + min-coverage-changed-files: 75 tests-frontend: name: Frontend Unit Tests diff --git a/.gitignore b/.gitignore index bb823fad24..ca198481b1 100644 --- a/.gitignore +++ b/.gitignore @@ -118,6 +118,9 @@ snyk.sarif # Dist **/dist/** +# IntelliJ +.idea/** +**/*.iml ### Eclipse ### backend/.metadata diff --git a/backend/pom.xml b/backend/pom.xml index 2fc3934f4d..474089b3ce 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -63,6 +63,7 @@ 5.9.1 1.9.1 + ${project.version} @@ -193,6 +194,10 @@ + + org.graalvm.buildtools + native-maven-plugin + org.springframework.boot spring-boot-maven-plugin @@ -203,6 +208,27 @@ lombok + + + gcr.io/paketo-buildpacks/graalvm + gcr.io/paketo-buildpacks/java-native-image + gcr.io/paketo-buildpacks/image-labels + + + 19.0.2 + https://github.com/bcgov/nr-forest-client + ${project.version} + ${project.description} + Apache License, Version 2.0 + ${oci.revision} + ${project.name} + ${timestamp} + true + + + + false + diff --git a/backend/src/main/java/ca/bc/gov/app/configuration/RouteConfiguration.java b/backend/src/main/java/ca/bc/gov/app/configuration/RouteConfiguration.java deleted file mode 100644 index f5e2124276..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/configuration/RouteConfiguration.java +++ /dev/null @@ -1,95 +0,0 @@ -package ca.bc.gov.app.configuration; - -import static org.springframework.web.reactive.function.server.RequestPredicates.path; -import static org.springframework.web.reactive.function.server.RouterFunctions.nest; - -import ca.bc.gov.app.routes.BaseRouter; -import io.swagger.v3.oas.models.examples.Example; -import io.swagger.v3.oas.models.media.StringSchema; -import io.swagger.v3.oas.models.parameters.Parameter; -import io.swagger.v3.oas.models.tags.Tag; -import java.util.List; -import java.util.Map; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.customizers.OpenApiCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.MediaType; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerResponse; - -/** - *

Base Router Class

- * This configuration class is responsible for configuring the routing for webflux. - * It also configures the OpenAPI part of the code with some default data. - */ -@Configuration -@Slf4j -public class RouteConfiguration { - - @Bean - public RouterFunction routes(List routes) { - return - routes - .stream() - .map(route -> nest( - path(String.format("/api%s", route.basePath())), - route.routerRoute()) - ) - .reduce(RouterFunction::and) - .orElseThrow(); - - } - - @Bean - public OpenApiCustomizer tagCustomizer(List routes) { - return openAPI -> { - routes.forEach(route -> - openAPI - .addTagsItem( - new Tag() - .name(route.routeTagName()) - .description(route.routeTagDescription()) - ) - ); - - openAPI - .getPaths() - .values() - .forEach(pathItem -> - pathItem - .addParametersItem( - new Parameter() - .schema(new StringSchema()) - .required(true) - .examples( - Map.of( - MediaType.APPLICATION_JSON_VALUE, - new Example().value(MediaType.APPLICATION_JSON_VALUE), - MediaType.TEXT_EVENT_STREAM_VALUE, - new Example().value(MediaType.TEXT_EVENT_STREAM_VALUE) - ) - ) - .in("header") - .name("Content-Type") - ) - .addParametersItem( - new Parameter() - .schema(new StringSchema()) - .required(true) - .examples( - Map.of( - MediaType.APPLICATION_JSON_VALUE, - new Example().value(MediaType.APPLICATION_JSON_VALUE), - MediaType.TEXT_EVENT_STREAM_VALUE, - new Example().value(MediaType.TEXT_EVENT_STREAM_VALUE) - ) - ) - .in("header") - .name("accept") - ) - ); - }; - } - -} diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/AbstractHandler.java b/backend/src/main/java/ca/bc/gov/app/controller/AbstractController.java similarity index 86% rename from backend/src/main/java/ca/bc/gov/app/handlers/AbstractHandler.java rename to backend/src/main/java/ca/bc/gov/app/controller/AbstractController.java index b09dc0aea6..83f350c36e 100644 --- a/backend/src/main/java/ca/bc/gov/app/handlers/AbstractHandler.java +++ b/backend/src/main/java/ca/bc/gov/app/controller/AbstractController.java @@ -1,4 +1,4 @@ -package ca.bc.gov.app.handlers; +package ca.bc.gov.app.controller; import ca.bc.gov.app.exception.InvalidRequestObjectException; import java.util.function.Function; @@ -8,12 +8,11 @@ import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.Errors; -import org.springframework.validation.FieldError; import org.springframework.validation.Validator; @RequiredArgsConstructor @Slf4j -public class AbstractHandler { +public class AbstractController { protected final Class contentClass; private final V validator; @@ -32,7 +31,6 @@ private static Function getErrorMessages() { errors .getAllErrors() .stream() - .map(FieldError.class::cast) .map(DefaultMessageSourceResolvable::getCode) .reduce(StringUtils.EMPTY, (message1, message2) -> String.join(",", message1, message2)); diff --git a/backend/src/main/java/ca/bc/gov/app/controller/ClientController.java b/backend/src/main/java/ca/bc/gov/app/controller/ClientController.java deleted file mode 100644 index e918339077..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/controller/ClientController.java +++ /dev/null @@ -1,38 +0,0 @@ -package ca.bc.gov.app.controller; - -import ca.bc.gov.app.dto.client.ClientDetailsDto; -import ca.bc.gov.app.service.client.ClientService; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.MediaType; -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 reactor.core.publisher.Mono; - -@RestController -@Slf4j -@Tag( - name = "FSA Clients", - description = "The FSA Client endpoint, responsible for handling client data" -) -@RequestMapping(value = "/api/clients", produces = MediaType.APPLICATION_JSON_VALUE) -@RequiredArgsConstructor -public class ClientController { - - private final ClientService service; - - @GetMapping("/{clientNumber}") - public Mono getClientDetails( - @Parameter( - description = "The client number to look for", - example = "00000002" - ) - @PathVariable String clientNumber - ) { - return service.getClientDetails(clientNumber); - } -} diff --git a/legacy/src/main/java/ca/bc/gov/app/handlers/GlobalErrorHandler.java b/backend/src/main/java/ca/bc/gov/app/controller/GlobalErrorController.java similarity index 95% rename from legacy/src/main/java/ca/bc/gov/app/handlers/GlobalErrorHandler.java rename to backend/src/main/java/ca/bc/gov/app/controller/GlobalErrorController.java index 02019d37db..db7ceff1d8 100644 --- a/legacy/src/main/java/ca/bc/gov/app/handlers/GlobalErrorHandler.java +++ b/backend/src/main/java/ca/bc/gov/app/controller/GlobalErrorController.java @@ -1,4 +1,4 @@ -package ca.bc.gov.app.handlers; +package ca.bc.gov.app.controller; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.BooleanUtils; @@ -29,9 +29,9 @@ @Slf4j @Component @Order(-2) -public class GlobalErrorHandler extends AbstractErrorWebExceptionHandler { +public class GlobalErrorController extends AbstractErrorWebExceptionHandler { - public GlobalErrorHandler( + public GlobalErrorController( ErrorAttributes errorAttributes, WebProperties webProperties, ApplicationContext applicationContext, diff --git a/backend/src/main/java/ca/bc/gov/app/controller/ches/ChesController.java b/backend/src/main/java/ca/bc/gov/app/controller/ches/ChesController.java new file mode 100644 index 0000000000..e22eccf3ea --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/controller/ches/ChesController.java @@ -0,0 +1,95 @@ +package ca.bc.gov.app.controller.ches; + +import ca.bc.gov.app.controller.AbstractController; +import ca.bc.gov.app.dto.ches.ChesRequest; +import ca.bc.gov.app.exception.InvalidRequestObjectException; +import ca.bc.gov.app.service.ches.ChesCommonServicesService; +import ca.bc.gov.app.validator.ches.ChesRequestValidator; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +@RestController +@Slf4j +@Tag( + name = "Ches API", + description = "A route for common services consumption" +) +@RequestMapping(value = "/api/mail", produces = MediaType.APPLICATION_JSON_VALUE) +public class ChesController extends AbstractController { + + private final ChesCommonServicesService service; + + public ChesController(ChesCommonServicesService service, ChesRequestValidator validator) { + super(ChesRequest.class, validator); + this.service = service; + } + + @PostMapping + @Operation( + summary = "Send an contactEmail to one or more contactEmail addresses", + responses = { + @ApiResponse( + responseCode = "201", + description = "Mail was sent", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = String.class), + examples = {@ExampleObject(value = "Created")} + ), + headers = { + @Header( + name = "Location", + schema = @Schema( + implementation = String.class, + example = "/api/mail/00000000-0000-0000-0000-000000000000" + ) + ) + } + ), + @ApiResponse( + responseCode = "400", + description = "Something went wrong, a required parameter wasn't being sent", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = String.class), + examples = {@ExampleObject(value = "Destination contactEmail is required")} + ) + ) + } + ) + public Mono sendMail( + @RequestBody ChesRequest request, + ServerHttpResponse serverResponse) { + return Mono.just(request) + .switchIfEmpty( + Mono.error(new InvalidRequestObjectException("no request body was provided")) + ) + .doOnNext(this::validate) + .doOnNext( + requestBody -> log.info("Requesting an contactEmail to be sent {}", requestBody)) + .flatMap(service::sendEmail) + .doOnNext(companyId -> { + serverResponse + .setStatusCode(HttpStatus.CREATED); + serverResponse + .getHeaders() + .add("Location", String.format("/api/mail/%s", companyId)); + } + ) + .then(); + } +} diff --git a/backend/src/main/java/ca/bc/gov/app/controller/client/ClientController.java b/backend/src/main/java/ca/bc/gov/app/controller/client/ClientController.java new file mode 100644 index 0000000000..9a320ab43f --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/controller/client/ClientController.java @@ -0,0 +1,178 @@ +package ca.bc.gov.app.controller.client; + +import ca.bc.gov.app.dto.client.ClientDetailsDto; +import ca.bc.gov.app.dto.client.ClientNameCodeDto; +import ca.bc.gov.app.service.client.ClientService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +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.tags.Tag; +import java.time.LocalDate; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RestController +@Slf4j +@Tag( + name = "FSA Clients", + description = "The FSA Client endpoint, responsible for handling client data" +) +@RequestMapping(value = "/api/clients", produces = MediaType.APPLICATION_JSON_VALUE) +@RequiredArgsConstructor +public class ClientController { + + private final ClientService clientService; + + @GetMapping("/{clientNumber}") + public Mono getClientDetails( + @Parameter( + description = "The client number to look for", + example = "00000002" + ) + @PathVariable String clientNumber + ) { + return clientService.getClientDetails(clientNumber); + } + + @GetMapping("/activeCountryCodes") + @Operation( + summary = "List countries", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK - List a page of countries with name and code", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + array = @ArraySchema( + schema = @Schema( + name = "NameCode", + implementation = ClientNameCodeDto.class + ) + ) + ) + ) + } + ) + public Flux listCountries( + @Parameter(description = "The one index page number, defaults to 0", example = "0") + @RequestParam(value = "page", required = false, defaultValue = "0") + Integer page, + + @Parameter(description = "The amount of data to be returned per page, defaults to 10", + example = "10") + @RequestParam(value = "size", required = false, defaultValue = "10") + Integer size, + ServerHttpResponse serverResponse) { + return clientService + .listCountries(page, size); + } + + @GetMapping("/activeCountryCodes/{countryCode}") + @Operation( + summary = "List provinces", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK - List a page of provinces with name and code", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + array = @ArraySchema( + schema = @Schema( + name = "NameCode", + implementation = ClientNameCodeDto.class + ) + ) + ) + ) + } + ) + public Flux listProvinces( + @Parameter( + description = """ + The code of the country. + The code can be obtained through /api/client/country endpoint""", + example = "CA" + ) + @PathVariable String countryCode, + + @Parameter(description = "The one index page number, defaults to 0", example = "0") + @RequestParam(value = "page", required = false, defaultValue = "0") + Integer page, + + @Parameter(description = "The amount of data to be returned per page, defaults to 10", + example = "10") + @RequestParam(value = "size", required = false, defaultValue = "10") + Integer size) { + return clientService + .listProvinces(countryCode, page, size); + } + + @GetMapping("/activeClientTypeCodes") + @Operation( + summary = "List active clients with their type codes", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK - List a page of active clients with name and code", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + array = @ArraySchema( + schema = @Schema( + name = "NameCode", + implementation = ClientNameCodeDto.class + ) + ) + ) + ) + } + ) + public Flux findActiveClientTypeCodes() { + return clientService + .findActiveClientTypeCodes(LocalDate.now()); + } + + @GetMapping("/activeContactTypeCodes") + @Operation( + summary = "List contact type codes", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK - List a page of contact type codes", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + array = @ArraySchema( + schema = @Schema( + name = "NameCode", + implementation = ClientNameCodeDto.class + ) + ) + ) + ) + } + ) + public Flux listClientContactTypeCodes( + @Parameter(description = "The one index page number, defaults to 0", example = "0") + @RequestParam(value = "page", required = false, defaultValue = "0") + Integer page, + + @Parameter(description = "The amount of data to be returned per page, defaults to 10", + example = "10") + @RequestParam(value = "size", required = false, defaultValue = "10") + Integer size + ) { + return clientService + .listClientContactTypeCodes(page, size); + } +} diff --git a/backend/src/main/java/ca/bc/gov/app/controller/client/ClientSubmissionController.java b/backend/src/main/java/ca/bc/gov/app/controller/client/ClientSubmissionController.java new file mode 100644 index 0000000000..82d477f2aa --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/controller/client/ClientSubmissionController.java @@ -0,0 +1,87 @@ +package ca.bc.gov.app.controller.client; + +import ca.bc.gov.app.dto.client.ClientSubmissionDto; +import ca.bc.gov.app.exception.InvalidRequestObjectException; +import ca.bc.gov.app.service.client.ClientService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +@RestController +@Slf4j +@RequestMapping(value = "/api/clients", produces = MediaType.APPLICATION_JSON_VALUE) +@RequiredArgsConstructor +public class ClientSubmissionController { + + private final ClientService clientService; + + @PostMapping("/submissions") + @Operation( + summary = "Submit client data", + responses = { + @ApiResponse( + responseCode = "201", + description = "New client submission posted", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = String.class), + examples = {@ExampleObject(value = "Created")} + ), + headers = { + @Header( + name = "Location", + schema = @Schema( + implementation = String.class, + example = "/api/clients/submissions/000123" + ) + ), + @Header( + name = "x-sub-id", + description = "ID of the submission that was created", + schema = @Schema( + implementation = String.class, + example = "000123" + ) + ) + } + ) + } + ) + public Mono submit( + @RequestBody ClientSubmissionDto request, + ServerHttpResponse serverResponse) { + return Mono.just(request) + .switchIfEmpty( + Mono.error(new InvalidRequestObjectException("no request body was provided")) + ) + .flatMap(clientService::submit) + .doOnNext(submissionId -> { + serverResponse + .setStatusCode(HttpStatus.CREATED); + + HttpHeaders headers = serverResponse.getHeaders(); + headers + .add( + "Location", + String.format("/api/clients/submissions/%d", submissionId)); + headers.add( + "x-sub-id", String.valueOf(submissionId)); + } + ) + .then(); + } +} diff --git a/backend/src/main/java/ca/bc/gov/app/controller/openmaps/OpenMapsController.java b/backend/src/main/java/ca/bc/gov/app/controller/openmaps/OpenMapsController.java new file mode 100644 index 0000000000..991f42082c --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/controller/openmaps/OpenMapsController.java @@ -0,0 +1,68 @@ +package ca.bc.gov.app.controller.openmaps; + +import ca.bc.gov.app.dto.openmaps.PropertyDto; +import ca.bc.gov.app.service.openmaps.OpenMapsService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +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 reactor.core.publisher.Mono; + +@RestController +@Slf4j +@Tag( + name = "OpenMaps API", + description = "Exposes OpenMaps consumption for First nation data extraction" +) +@RequestMapping(value = "/api/maps", produces = MediaType.APPLICATION_JSON_VALUE) +@RequiredArgsConstructor +public class OpenMapsController { + + private final OpenMapsService openMapsService; + + @GetMapping(value = "/firstNation/{id}") + @Operation( + summary = "Get First Nation data by ID", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK - Data was found based on the provided id", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema( + name = "FirstNationResponse", + implementation = PropertyDto.class + ) + ) + ), + @ApiResponse( + responseCode = "400", + description = "No first nation found with provided federal id", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = String.class), + examples = {@ExampleObject(value = "No first nation found with federal id 99999")} + ) + ) + } + ) + public Mono findFirstNation( + @Parameter( + description = "The first nation federal ID to lookup", + example = "656" + ) + @PathVariable String id) { + return openMapsService + .getFirstNation(id); + } +} diff --git a/backend/src/main/java/ca/bc/gov/app/controller/orgbook/OrgBookNameController.java b/backend/src/main/java/ca/bc/gov/app/controller/orgbook/OrgBookNameController.java new file mode 100644 index 0000000000..4ab28a3bc5 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/controller/orgbook/OrgBookNameController.java @@ -0,0 +1,90 @@ +package ca.bc.gov.app.controller.orgbook; + +import ca.bc.gov.app.dto.client.ClientNameCodeDto; +import ca.bc.gov.app.dto.orgbook.OrgBookTopicListResponse; +import ca.bc.gov.app.service.orgbook.OrgBookApiService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +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.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +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 reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RestController +@Slf4j +@Tag( + name = "OrgBook API", + description = "A route for BC OrgBook data access and consumption" +) +@RequestMapping(value = "/api/orgbook", produces = MediaType.APPLICATION_JSON_VALUE) +@RequiredArgsConstructor +public class OrgBookNameController { + + private final OrgBookApiService service; + + @GetMapping(value = "/name/{name}") + @Operation( + summary = "Search the OrgBook based on the name", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK - Data was found based on the provided name", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + array = @ArraySchema( + schema = @Schema( + name = "NameCode", + implementation = ClientNameCodeDto.class + ) + ) + ) + ) + } + ) + public Flux findByClientName( + @Parameter( + description = "The name to lookup", + example = "Power Corp" + ) + @PathVariable String name) { + return service + .findByClientName(name); + } + + @GetMapping(value = "/incorporation/{incorporationId}") + @Operation( + summary = "Search the OrgBook based on the incorporation id", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK - Data was found based on the provided incorporation", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema( + name = "TopicListResponse", + implementation = OrgBookTopicListResponse.class + ) + ) + ) + } + ) + public Mono findByIncorporationNumber( + @Parameter( + description = "The incorporation ID to lookup", + example = "BC0772006" + ) + @PathVariable String incorporationId) { + return service + .findByIncorporationNumber(incorporationId); + } +} diff --git a/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailAttachment.java b/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailAttachment.java index 6527bf9b67..b9c895f50e 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailAttachment.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailAttachment.java @@ -22,11 +22,12 @@ public record ChesMailAttachment( @JsonPropertyDescription("If set and content is string, then encodes the content to a " + "Buffer using the specified encoding. Example values: 'base64', 'hex', 'binary' etc. " - + "Useful if you want to use binary attachments in a JSON formatted email object.") + + "Useful if you want to use binary attachments in a JSON formatted contactEmail object.") ChesMailEncoding encoding, - @JsonPropertyDescription("Filename to be reported as the name of the attached file. " - + "Use of unicode is allowed.") + @JsonPropertyDescription( + "Filename to be reported as the name of the attached file. " + + "Use of unicode is allowed.") String filename ) { } diff --git a/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailRequest.java b/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailRequest.java index 56c057f6b3..583205fc18 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailRequest.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailRequest.java @@ -29,12 +29,12 @@ public record ChesMailRequest( @Valid List attachments, - @JsonPropertyDescription("An array of recipients email addresses " + @JsonPropertyDescription("An array of recipients contactEmail addresses " + "that will appear on the BCC: field") @Valid List bcc, - @JsonPropertyDescription("The email body type (html = content with html, text = plaintext)") + @JsonPropertyDescription("The contactEmail body type (html = content with html, text = plaintext)") @NotNull ChesMailBodyType bodyType, @@ -42,7 +42,7 @@ public record ChesMailRequest( @NotNull String body, - @JsonPropertyDescription("An array of recipients email addresses " + @JsonPropertyDescription("An array of recipients contactEmail addresses " + "that will appear on the CC: field") @Valid List cc, @@ -56,8 +56,8 @@ public record ChesMailRequest( + "(defaults to 'utf-8', other values are 'hex' and 'base64')") ChesMailEncoding encoding, - @JsonPropertyDescription("The email address of the sender. " - + "All email addresses can be plain 'sender@server.com' or " + @JsonPropertyDescription("The contactEmail address of the sender. " + + "All contactEmail addresses can be plain 'sender@server.com' or " + "formatted '\"Sender Name\" '") @NotNull String from, @@ -66,14 +66,14 @@ public record ChesMailRequest( + "'high', 'normal' (default) or 'low'.") ChesMailPriority priority, - @JsonPropertyDescription("The email subject") + @JsonPropertyDescription("The contactEmail subject") @NotNull String subject, @JsonPropertyDescription("A unique string which is associated with the message") String tag, - @JsonPropertyDescription("An array of recipients email addresses " + @JsonPropertyDescription("An array of recipients contactEmail addresses " + "that will appear on the To: field") @Valid @NotNull diff --git a/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailResponseMessage.java b/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailResponseMessage.java index e659f69ffb..33c46480aa 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailResponseMessage.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesMailResponseMessage.java @@ -22,7 +22,7 @@ public record ChesMailResponseMessage( @JsonPropertyDescription("A unique string which is associated with the message") String tag, - @JsonPropertyDescription("An array of recipient email addresses that this message will go to") + @JsonPropertyDescription("An array of recipient contactEmail addresses that this message will go to") @Valid @NotNull List to diff --git a/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesRequest.java b/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesRequest.java index 3ef5a8d521..70d2a98780 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesRequest.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/ches/ChesRequest.java @@ -13,7 +13,7 @@ public record ChesRequest( @Min(1) @Email @Schema(name = "emailTo", - description = "An array of recipients email addresses", + description = "An array of recipients contactEmail addresses", example = "foo@bar.com") List emailTo, @NotNull diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientAddressDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientAddressDto.java index d79d3e2ee0..40916daf99 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientAddressDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientAddressDto.java @@ -8,8 +8,8 @@ public record ClientAddressDto( String province, String city, String postalCode, - String businessPhone, + int index, - List clientContactDtoList + List contacts ) { } diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientInformationDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientBusinessInformationDto.java similarity index 77% rename from backend/src/main/java/ca/bc/gov/app/dto/client/ClientInformationDto.java rename to backend/src/main/java/ca/bc/gov/app/dto/client/ClientBusinessInformationDto.java index 84c2cb9ac4..0e990b1590 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientInformationDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientBusinessInformationDto.java @@ -1,6 +1,6 @@ package ca.bc.gov.app.dto.client; -public record ClientInformationDto( +public record ClientBusinessInformationDto( String firstName, String lastName, String birthdate, diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientBusinessTypeDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientBusinessTypeDto.java index f6154d0a8d..2df37a40c8 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientBusinessTypeDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientBusinessTypeDto.java @@ -1,4 +1,4 @@ package ca.bc.gov.app.dto.client; -public record ClientBusinessTypeDto(String clientType){ +public record ClientBusinessTypeDto(ClientTypeDto clientType) { } diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLocationDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLocationDto.java index 4de4f62fcc..9a046a1266 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLocationDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientLocationDto.java @@ -2,5 +2,5 @@ import java.util.List; -public record ClientLocationDto(List clientAddressDto) { +public record ClientLocationDto(List addresses) { } diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientSubmissionDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientSubmissionDto.java index 77f5c11bdb..1f9fa37be9 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientSubmissionDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientSubmissionDto.java @@ -1,8 +1,9 @@ package ca.bc.gov.app.dto.client; public record ClientSubmissionDto( - ClientBusinessTypeDto clientBusinessTypeDto, - ClientInformationDto clientInformationDto, - ClientLocationDto clientLocationDto + ClientBusinessTypeDto businessType, + ClientBusinessInformationDto businessInformation, + ClientLocationDto location, + ClientSubmitterInformationDto submitterInformation ) { } diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientSubmitterInformationDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientSubmitterInformationDto.java new file mode 100644 index 0000000000..f4201aec2a --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientSubmitterInformationDto.java @@ -0,0 +1,9 @@ +package ca.bc.gov.app.dto.client; + +public record ClientSubmitterInformationDto( + String submitterFirstName, + String submitterLastName, + String submitterPhoneNumber, + String submitterEmail +) { +} diff --git a/backend/src/main/java/ca/bc/gov/app/dto/client/ClientTypeDto.java b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientTypeDto.java new file mode 100644 index 0000000000..c5135c6308 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/dto/client/ClientTypeDto.java @@ -0,0 +1,4 @@ +package ca.bc.gov.app.dto.client; + +public record ClientTypeDto(String value, String text) { +} diff --git a/backend/src/main/java/ca/bc/gov/app/dto/orgbook/OrgBookNameDto.java b/backend/src/main/java/ca/bc/gov/app/dto/orgbook/OrgBookNameDto.java index 3756f6ac94..a055ba9c2d 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/orgbook/OrgBookNameDto.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/orgbook/OrgBookNameDto.java @@ -12,6 +12,6 @@ public record OrgBookNameDto( String subType, @JsonProperty("topic_source_id") String topicSourceId, - Listnames + List names ) { } diff --git a/backend/src/main/java/ca/bc/gov/app/dto/orgbook/OrgBookResultListResponse.java b/backend/src/main/java/ca/bc/gov/app/dto/orgbook/OrgBookResultListResponse.java index fd773abffe..e278479a23 100644 --- a/backend/src/main/java/ca/bc/gov/app/dto/orgbook/OrgBookResultListResponse.java +++ b/backend/src/main/java/ca/bc/gov/app/dto/orgbook/OrgBookResultListResponse.java @@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -@Schema(name = "NameListResponse", description = "A list of name results") +@Schema(name = "NameListResponse", description = "A list of contactFirstName results") @JsonIgnoreProperties(ignoreUnknown = true) public record OrgBookResultListResponse( @Schema(description = "The total amount of entries on all pages", example = "75") diff --git a/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionEntity.java b/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionEntity.java index 172909a671..2b96549bc3 100644 --- a/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionEntity.java +++ b/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionEntity.java @@ -4,7 +4,6 @@ import ca.bc.gov.app.models.client.SubmissionStatusEnum; import java.time.LocalDateTime; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -35,7 +34,5 @@ public class SubmissionEntity extends BaseEntity { private SubmissionStatusEnum submissionStatus; @Column("submission_date") - @Builder.Default - private LocalDateTime submissionDate = LocalDateTime.now(); - + private LocalDateTime submissionDate; } diff --git a/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionLocationContactEntity.java b/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionLocationContactEntity.java index bf8c89d725..417b1ad8be 100644 --- a/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionLocationContactEntity.java +++ b/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionLocationContactEntity.java @@ -24,15 +24,15 @@ public class SubmissionLocationContactEntity { @Column("submission_location_id") private Integer submissionLocationId; + @Column("contact_type_code") + private String contactTypeCode; + @Column("first_name") private String firstName; - + @Column("last_name") private String lastName; - @Column("contact_type_code") - private String contactTypeCode; - @Column("business_phone_number") private String businessPhoneNumber; diff --git a/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionLocationEntity.java b/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionLocationEntity.java index ac9bb65808..b831d5008a 100644 --- a/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionLocationEntity.java +++ b/backend/src/main/java/ca/bc/gov/app/entity/client/SubmissionLocationEntity.java @@ -39,9 +39,6 @@ public class SubmissionLocationEntity { @Column("postal_code") private String postalCode; - @Column("email_address") - private String emailAddress; - @Column("main_address_ind") private String mainAddressInd; } diff --git a/backend/src/main/java/ca/bc/gov/app/entity/client/SubmitterEntity.java b/backend/src/main/java/ca/bc/gov/app/entity/client/SubmitterEntity.java new file mode 100644 index 0000000000..87ebe4bf80 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/entity/client/SubmitterEntity.java @@ -0,0 +1,38 @@ +package ca.bc.gov.app.entity.client; + +import ca.bc.gov.app.ApplicationConstant; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.With; +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +@Table(name = "submission_submitter", schema = ApplicationConstant.POSTGRES_ATTRIBUTE_SCHEMA) +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@With +public class SubmitterEntity { + @Id + @Column("submission_submitter_id") + private Integer submissionSubmitterId; + + @Column("submission_id") + private Integer submissionId; + + @Column("first_name") + private String firstName; + + @Column("last_name") + private String lastName; + + @Column("phone_number") + private String phoneNumber; + + @Column("email_address") + private String emailAddress; +} diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/BaseHandler.java b/backend/src/main/java/ca/bc/gov/app/handlers/BaseHandler.java deleted file mode 100644 index 70a3634bfe..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/handlers/BaseHandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package ca.bc.gov.app.handlers; - -import java.util.function.Consumer; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -public interface BaseHandler { - Mono handle(ServerRequest serverRequest); - - Consumer documentation(String tag); - -} diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/ches/ChesHandler.java b/backend/src/main/java/ca/bc/gov/app/handlers/ches/ChesHandler.java deleted file mode 100644 index 5c8c3cf4de..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/handlers/ches/ChesHandler.java +++ /dev/null @@ -1,109 +0,0 @@ -package ca.bc.gov.app.handlers.ches; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.header.Builder.headerBuilder; -import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.ches.ChesRequest; -import ca.bc.gov.app.exception.InvalidRequestObjectException; -import ca.bc.gov.app.handlers.AbstractHandler; -import ca.bc.gov.app.handlers.BaseHandler; -import ca.bc.gov.app.service.ches.ChesCommonServicesService; -import ca.bc.gov.app.util.HandlerUtil; -import ca.bc.gov.app.validator.ches.ChesRequestValidator; -import java.net.URI; -import java.util.function.Consumer; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@Slf4j -public class ChesHandler extends AbstractHandler implements - BaseHandler { - - private final ChesCommonServicesService service; - - public ChesHandler(ChesCommonServicesService service, ChesRequestValidator validator) { - super(ChesRequest.class, validator); - this.service = service; - } - - @Override - public Mono handle(ServerRequest request) { - return - request - .bodyToMono(ChesRequest.class) - .switchIfEmpty( - Mono.error(new InvalidRequestObjectException("no request body was provided")) - ) - .doOnNext(this::validate) - .doOnNext(requestBody -> log.info("Requesting an email to be sent {}", requestBody)) - .flatMap(service::sendEmail) - .flatMap( - companyId -> - ServerResponse - .created( - URI - .create(String.format("/api/mail/%s", companyId)) - ) - .contentType( - request - .headers() - .contentType() - .orElse(MediaType.APPLICATION_JSON) - ) - .build() - ) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - - } - - - @Override - public Consumer documentation(String tag) { - return ops -> ops - .tag(tag) - .description("Send an email to one or more email addresses") - .beanClass(ChesHandler.class) - .beanMethod("handle") - .operationId("handle") - .requestBody(requestBodyBuilder().implementation(ChesRequest.class)) - .response( - responseBuilder() - .responseCode("201") - .description("Mail was sent") - .content(contentBuilder()) - .header( - headerBuilder() - .name("Location") - .schema( - schemaBuilder() - .implementation(String.class) - .example("/api/mail/00000000-0000-0000-0000-000000000000") - ) - ) - ) - .response( - responseBuilder() - .responseCode("400") - .description("Something went wrong, a required parameter wasn't being sent") - .content( - contentBuilder() - .schema( - schemaBuilder() - .implementation(String.class) - .example("Destination email is required") - ) - ) - ); - } -} diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientCountryCodeHandler.java b/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientCountryCodeHandler.java deleted file mode 100644 index f78415fe8d..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientCountryCodeHandler.java +++ /dev/null @@ -1,105 +0,0 @@ -package ca.bc.gov.app.handlers.client; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.arrayschema.Builder.arraySchemaBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder; -import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.client.ClientNameCodeDto; -import ca.bc.gov.app.handlers.BaseHandler; -import ca.bc.gov.app.service.client.ClientService; -import ca.bc.gov.app.util.HandlerUtil; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@Slf4j -@RequiredArgsConstructor -public class ClientCountryCodeHandler implements BaseHandler { - - private final ClientService clientService; - - @Override - public Mono handle(ServerRequest serverRequest) { - return - ServerResponse - .ok() - .contentType(serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON)) - .body( - clientService - .listCountries( - serverRequest - .queryParam("page") - .map(Integer::parseInt) - .orElse(0), - serverRequest - .queryParam("size") - .map(Integer::parseInt) - .orElse(5) - ), - ClientNameCodeDto.class - ) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops - .tag(tag) - .description("List countries") - .beanClass(ClientCountryCodeHandler.class) - .beanMethod("handle") - .operationId("handle") - .requestBody(requestBodyBuilder()) - .parameter( - parameterBuilder() - .in(ParameterIn.QUERY) - .name("page") - .description(""" - 0 index page number, for example: - 0 for the first page, 4 for the fifth page. - Defaults to 0 (first page)""") - .allowEmptyValue(true) - .schema(schemaBuilder().implementation(String.class)) - .example("4") - ) - .parameter( - parameterBuilder() - .in(ParameterIn.QUERY) - .name("size") - .description("Amount of entries per page,default to 5") - .allowEmptyValue(true) - .schema(schemaBuilder().implementation(String.class)) - .example("5") - ) - .response( - responseBuilder() - .responseCode("200") - .description("OK - List a page of countries with name and code") - .content( - contentBuilder() - .array( - arraySchemaBuilder() - .schema( - schemaBuilder() - .name("NameCode") - .implementation(ClientNameCodeDto.class) - ) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ); - } -} diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientProvinceCodeHandler.java b/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientProvinceCodeHandler.java deleted file mode 100644 index 85f921dc93..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientProvinceCodeHandler.java +++ /dev/null @@ -1,118 +0,0 @@ -package ca.bc.gov.app.handlers.client; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.arrayschema.Builder.arraySchemaBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder; -import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.client.ClientNameCodeDto; -import ca.bc.gov.app.handlers.BaseHandler; -import ca.bc.gov.app.service.client.ClientService; -import ca.bc.gov.app.util.HandlerUtil; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@Slf4j -@RequiredArgsConstructor -public class ClientProvinceCodeHandler implements BaseHandler { - - private final ClientService clientService; - - @Override - public Mono handle(ServerRequest serverRequest) { - return - ServerResponse - .ok() - .contentType(serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON)) - .body( - clientService - .listProvinces( - serverRequest - .pathVariable("countryCode"), - serverRequest - .queryParam("page") - .map(Integer::parseInt) - .orElse(0), - serverRequest - .queryParam("size") - .map(Integer::parseInt) - .orElse(5) - ), - ClientNameCodeDto.class - ) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops - .tag(tag) - .description("List countries") - .beanClass(ClientProvinceCodeHandler.class) - .beanMethod("handle") - .operationId("handle") - .requestBody(requestBodyBuilder()) - .parameter( - parameterBuilder() - .in(ParameterIn.PATH) - .name("countryCode") - .description(""" - The code of the country. - The code can be obtained through /api/client/country endpoint""") - .allowEmptyValue(true) - .schema(schemaBuilder().implementation(String.class)) - .example("CA") - ) - .parameter( - parameterBuilder() - .in(ParameterIn.QUERY) - .name("page") - .description(""" - 0 index page number, for example: - 0 for the first page, 4 for the fifth page. - Defaults to 0 (first page)""") - .allowEmptyValue(true) - .schema(schemaBuilder().implementation(String.class)) - .example("4") - ) - .parameter( - parameterBuilder() - .in(ParameterIn.QUERY) - .name("size") - .description("Amount of entries per page,default to 5") - .allowEmptyValue(true) - .schema(schemaBuilder().implementation(String.class)) - .example("5") - ) - .response( - responseBuilder() - .responseCode("200") - .description("OK - List a page of provinces with name and code") - .content( - contentBuilder() - .array( - arraySchemaBuilder() - .schema( - schemaBuilder() - .name("NameCode") - .implementation(ClientNameCodeDto.class) - ) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ); - } -} \ No newline at end of file diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientSubmissionHandler.java b/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientSubmissionHandler.java deleted file mode 100644 index cee7a39af0..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientSubmissionHandler.java +++ /dev/null @@ -1,86 +0,0 @@ -package ca.bc.gov.app.handlers.client; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.header.Builder.headerBuilder; -import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.client.ClientSubmissionDto; -import ca.bc.gov.app.handlers.BaseHandler; -import ca.bc.gov.app.service.client.ClientService; -import ca.bc.gov.app.util.HandlerUtil; -import java.net.URI; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@Slf4j -@RequiredArgsConstructor -public class ClientSubmissionHandler implements BaseHandler { - - private final ClientService clientService; - - @Override - public Mono handle(ServerRequest serverRequest) { - return - serverRequest - .bodyToMono(ClientSubmissionDto.class) - .flatMap(clientService::submit) - .flatMap(submissionId -> - ServerResponse - .created( - URI.create(String.format("/api/clients/submissions/%d", submissionId)) - ) - .header("x-sub-id", String.valueOf(submissionId)) - .build() - ) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops - .tag(tag) - .description("Submit client data") - .beanClass(ClientSubmissionHandler.class) - .beanMethod("handle") - .operationId("handle") - .requestBody( - requestBodyBuilder() - .implementation(ClientSubmissionDto.class)) - .response( - responseBuilder() - .responseCode("201") - .description("New client submission posted") - .content(contentBuilder()) - .header( - headerBuilder() - .name("Location") - .schema( - schemaBuilder() - .implementation(String.class) - .example("/api/clients/submissions/0") - ) - ) - .header( - headerBuilder() - .name("x-sub-id") - .description("ID of the submission that was created") - .schema( - schemaBuilder() - .implementation(String.class) - .example("0") - ) - ) - ); - } -} diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientTypeCodeHandler.java b/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientTypeCodeHandler.java deleted file mode 100644 index a9a867b768..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/handlers/client/ClientTypeCodeHandler.java +++ /dev/null @@ -1,74 +0,0 @@ -package ca.bc.gov.app.handlers.client; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.arrayschema.Builder.arraySchemaBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.client.ClientNameCodeDto; -import ca.bc.gov.app.handlers.BaseHandler; -import ca.bc.gov.app.service.client.ClientService; -import ca.bc.gov.app.util.HandlerUtil; -import java.time.LocalDate; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@Slf4j -@RequiredArgsConstructor -public class ClientTypeCodeHandler implements BaseHandler { - - private final ClientService clientService; - - @Override - public Mono handle(ServerRequest serverRequest) { - return - ServerResponse - .ok() - .contentType(serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON)) - .body( - clientService - .findActiveClientTypeCodes(LocalDate.now()), - ClientNameCodeDto.class - ) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops - .tag(tag) - .description("List active clients with their type codes") - .beanClass(ClientTypeCodeHandler.class) - .beanMethod("handle") - .operationId("handle") - .requestBody(requestBodyBuilder()) - .response( - responseBuilder() - .responseCode("200") - .description("OK - Data was found based on the provided incorporation") - .content( - contentBuilder() - .array( - arraySchemaBuilder() - .schema( - schemaBuilder() - .name("NameCode") - .implementation(ClientNameCodeDto.class) - ) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ); - } -} diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/client/ContactTypeCodeHandler.java b/backend/src/main/java/ca/bc/gov/app/handlers/client/ContactTypeCodeHandler.java deleted file mode 100644 index 4f23e87ca9..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/handlers/client/ContactTypeCodeHandler.java +++ /dev/null @@ -1,105 +0,0 @@ -package ca.bc.gov.app.handlers.client; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.arrayschema.Builder.arraySchemaBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder; -import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.client.ClientNameCodeDto; -import ca.bc.gov.app.handlers.BaseHandler; -import ca.bc.gov.app.service.client.ClientService; -import ca.bc.gov.app.util.HandlerUtil; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@Slf4j -@RequiredArgsConstructor -public class ContactTypeCodeHandler implements BaseHandler { - - private final ClientService clientService; - - - @Override - public Mono handle(ServerRequest serverRequest) { - return - ServerResponse - .ok() - .body( - clientService - .listClientContactTypeCodes( - serverRequest - .queryParam("page") - .map(Integer::parseInt) - .orElse(0), - serverRequest - .queryParam("size") - .map(Integer::parseInt) - .orElse(5) - ), - ContactTypeCodeHandler.class - ) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops - .tag(tag) - .description("List contact type codes") - .beanClass(ContactTypeCodeHandler.class) - .beanMethod("handle") - .operationId("handle") - .requestBody(requestBodyBuilder()) - .parameter( - parameterBuilder() - .in(ParameterIn.QUERY) - .name("page") - .description(""" - 0 index page number, for example: - 0 for the first page, 4 for the fifth page. - Defaults to 0 (first page)""") - .allowEmptyValue(true) - .schema(schemaBuilder().implementation(String.class)) - .example("4") - ) - .parameter( - parameterBuilder() - .in(ParameterIn.QUERY) - .name("size") - .description("Amount of entries per page,default to 5") - .allowEmptyValue(true) - .schema(schemaBuilder().implementation(String.class)) - .example("5") - ) - .response( - responseBuilder() - .responseCode("200") - .description("OK - List a page of contact type codes") - .content( - contentBuilder() - .array( - arraySchemaBuilder() - .schema( - schemaBuilder() - .name("NameCode") - .implementation(ClientNameCodeDto.class) - ) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ); - } -} diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/openmaps/OpenMapsHandler.java b/backend/src/main/java/ca/bc/gov/app/handlers/openmaps/OpenMapsHandler.java deleted file mode 100644 index ca8ba3c427..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/handlers/openmaps/OpenMapsHandler.java +++ /dev/null @@ -1,97 +0,0 @@ -package ca.bc.gov.app.handlers.openmaps; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.exampleobject.Builder.exampleOjectBuilder; -import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder; -import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.openmaps.PropertyDto; -import ca.bc.gov.app.handlers.BaseHandler; -import ca.bc.gov.app.service.openmaps.OpenMapsService; -import ca.bc.gov.app.util.HandlerUtil; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@Slf4j -@RequiredArgsConstructor -public class OpenMapsHandler implements BaseHandler { - - private final OpenMapsService openMapsService; - - @Override - public Mono handle(ServerRequest serverRequest) { - return - ServerResponse - .ok() - .contentType(serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON)) - .body( - openMapsService - .getFirstNation(serverRequest.pathVariable("id")), - PropertyDto.class - ) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops - .tag(tag) - .description("Get First Nation data by ID") - .beanClass(OpenMapsHandler.class) - .beanMethod("handle") - .operationId("handle") - .requestBody(requestBodyBuilder()) - .parameter( - parameterBuilder() - .description("The first nation federal ID to lookup") - .allowEmptyValue(false) - .example("656") - .schema(schemaBuilder().implementation(String.class)) - .in(ParameterIn.PATH) - .name("id") - ) - .response( - responseBuilder() - .responseCode("200") - .description("OK - Data was found based on the provided id") - .content( - contentBuilder() - .schema( - schemaBuilder() - .name("FirstNationResponse") - .implementation(PropertyDto.class) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ) - .response( - responseBuilder() - .responseCode("400") - .description("No first nation found with provided federal id ") - .content( - contentBuilder() - .schema( - schemaBuilder() - .implementation(String.class) - - ) - .example(exampleOjectBuilder() - .value("No first nation found with federal id 99999")) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ); - } -} diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/orgbook/OrgBookIncorporationHandler.java b/backend/src/main/java/ca/bc/gov/app/handlers/orgbook/OrgBookIncorporationHandler.java deleted file mode 100644 index eba9776a23..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/handlers/orgbook/OrgBookIncorporationHandler.java +++ /dev/null @@ -1,81 +0,0 @@ -package ca.bc.gov.app.handlers.orgbook; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder; -import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.orgbook.OrgBookTopicListResponse; -import ca.bc.gov.app.handlers.BaseHandler; -import ca.bc.gov.app.service.orgbook.OrgBookApiService; -import ca.bc.gov.app.util.HandlerUtil; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@Slf4j -@RequiredArgsConstructor -public class OrgBookIncorporationHandler implements BaseHandler { - - private final OrgBookApiService service; - - @Override - public Mono handle(ServerRequest serverRequest) { - return - ServerResponse - .ok() - .contentType(serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON)) - .body( - service - .findByIncorporationNumber(serverRequest.pathVariable("incorporationId")), - OrgBookTopicListResponse.class - ) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops - .tag(tag) - .description("Search the OrgBook based on the incorporation id") - .beanClass(OrgBookIncorporationHandler.class) - .beanMethod("handle") - .operationId("handle") - .requestBody(requestBodyBuilder()) - .parameter( - parameterBuilder() - .description("The incorporation ID to lookup") - .allowEmptyValue(false) - .example("BC0772006") - .schema(schemaBuilder().implementation(String.class)) - .in(ParameterIn.PATH) - .name("incorporationId") - ) - .response( - responseBuilder() - .responseCode("200") - .description("OK - Data was found based on the provided incorporation") - .content( - contentBuilder() - .schema( - schemaBuilder() - .name("TopicListResponse") - .implementation(OrgBookTopicListResponse.class) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - - ); - } -} diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/orgbook/OrgBookNameHandler.java b/backend/src/main/java/ca/bc/gov/app/handlers/orgbook/OrgBookNameHandler.java deleted file mode 100644 index 9d8d227328..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/handlers/orgbook/OrgBookNameHandler.java +++ /dev/null @@ -1,82 +0,0 @@ -package ca.bc.gov.app.handlers.orgbook; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.arrayschema.Builder.arraySchemaBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.client.ClientNameCodeDto; -import ca.bc.gov.app.handlers.BaseHandler; -import ca.bc.gov.app.service.orgbook.OrgBookApiService; -import ca.bc.gov.app.util.HandlerUtil; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@Slf4j -@RequiredArgsConstructor -public class OrgBookNameHandler implements BaseHandler { - - private final OrgBookApiService service; - - @Override - public Mono handle(ServerRequest serverRequest) { - return - ServerResponse - .ok() - .contentType(serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON)) - .body( - service - .findByClientName(serverRequest.pathVariable("name")), - ClientNameCodeDto.class - ) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return - ops -> ops - .tag(tag) - .description("Search the OrgBook based on the name") - .beanClass(OrgBookIncorporationHandler.class) - .beanMethod("handle") - .operationId("handle") - .parameter( - parameterBuilder() - .in(ParameterIn.PATH) - .name("name") - .schema(schemaBuilder().implementation(String.class)) - .description("The name to lookup") - .example("Power Corp") - ) - .response( - responseBuilder() - .responseCode("200") - .description("Found") - .content( - contentBuilder() - .array( - arraySchemaBuilder() - .schema( - schemaBuilder() - .name("NameCode") - .implementation(ClientNameCodeDto.class) - ) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ); - } -} diff --git a/backend/src/main/java/ca/bc/gov/app/repository/client/SubmitterRepository.java b/backend/src/main/java/ca/bc/gov/app/repository/client/SubmitterRepository.java new file mode 100644 index 0000000000..7394e847f1 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/repository/client/SubmitterRepository.java @@ -0,0 +1,9 @@ +package ca.bc.gov.app.repository.client; + +import ca.bc.gov.app.entity.client.SubmitterEntity; +import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface SubmitterRepository extends ReactiveCrudRepository { +} diff --git a/backend/src/main/java/ca/bc/gov/app/routes/BaseRouter.java b/backend/src/main/java/ca/bc/gov/app/routes/BaseRouter.java deleted file mode 100644 index f6393699e4..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/routes/BaseRouter.java +++ /dev/null @@ -1,15 +0,0 @@ -package ca.bc.gov.app.routes; - -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerResponse; - -public interface BaseRouter { - String basePath(); - - RouterFunction routerRoute(); - - String routeTagName(); - - String routeTagDescription(); - -} diff --git a/backend/src/main/java/ca/bc/gov/app/routes/ches/ChesRouter.java b/backend/src/main/java/ca/bc/gov/app/routes/ches/ChesRouter.java deleted file mode 100644 index 1259a6ccde..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/routes/ches/ChesRouter.java +++ /dev/null @@ -1,50 +0,0 @@ -package ca.bc.gov.app.routes.ches; - -import static org.springdoc.webflux.core.fn.SpringdocRouteBuilder.route; -import static org.springframework.web.reactive.function.server.RequestPredicates.accept; - -import ca.bc.gov.app.handlers.ches.ChesHandler; -import ca.bc.gov.app.routes.BaseRouter; -import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.StringUtils; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -@RequiredArgsConstructor -public class ChesRouter implements BaseRouter { - - private final ChesHandler handler; - - @Override - public String basePath() { - return "/mail"; - } - - @Override - public String routeTagName() { - return "Ches"; - } - - @Override - public String routeTagDescription() { - return "A route for common services consumption"; - } - - @Override - public RouterFunction routerRoute() { - return - route() - .POST( - StringUtils.EMPTY, - accept(MediaType.APPLICATION_JSON), - handler::handle, - handler.documentation(routeTagName()) - ) - .build(); - } - - -} diff --git a/backend/src/main/java/ca/bc/gov/app/routes/client/ClientRouter.java b/backend/src/main/java/ca/bc/gov/app/routes/client/ClientRouter.java deleted file mode 100644 index c5db1e95d1..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/routes/client/ClientRouter.java +++ /dev/null @@ -1,78 +0,0 @@ -package ca.bc.gov.app.routes.client; - -import static org.springdoc.webflux.core.fn.SpringdocRouteBuilder.route; -import static org.springframework.web.reactive.function.server.RequestPredicates.accept; - -import ca.bc.gov.app.handlers.client.ClientCountryCodeHandler; -import ca.bc.gov.app.handlers.client.ClientProvinceCodeHandler; -import ca.bc.gov.app.handlers.client.ClientSubmissionHandler; -import ca.bc.gov.app.handlers.client.ClientTypeCodeHandler; -import ca.bc.gov.app.handlers.client.ContactTypeCodeHandler; -import ca.bc.gov.app.routes.BaseRouter; -import lombok.RequiredArgsConstructor; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -@RequiredArgsConstructor -public class ClientRouter implements BaseRouter { - - private final ClientProvinceCodeHandler provinceCodeHandler; - private final ClientTypeCodeHandler clientHandler; - private final ClientCountryCodeHandler countryCodeHandler; - private final ContactTypeCodeHandler contactTypeCodeHandler; - private final ClientSubmissionHandler clientSubmissionHandler; - - @Override - public String basePath() { - return "/clients"; - } - - @Override - public String routeTagName() { - return "FSA Clients"; - } - - @Override - public String routeTagDescription() { - return "The FSA Client endpoint, responsible for handling client data"; - } - - @Override - public RouterFunction routerRoute() { - return route() - .GET( - "/activeClientTypeCodes", - accept(MediaType.ALL), - clientHandler::handle, - clientHandler.documentation(routeTagName()) - ) - .GET( - "/activeCountryCodes", - accept(MediaType.ALL), - countryCodeHandler::handle, - countryCodeHandler.documentation(routeTagName()) - ) - .GET( - "/activeCountryCodes/{countryCode}", - accept(MediaType.ALL), - provinceCodeHandler::handle, - provinceCodeHandler.documentation(routeTagName()) - ) - .GET( - "/activeContactTypeCodes", - accept(MediaType.ALL), - contactTypeCodeHandler::handle, - contactTypeCodeHandler.documentation(routeTagName()) - ) - .POST( - "/submissions", - accept(MediaType.ALL), - clientSubmissionHandler::handle, - clientSubmissionHandler.documentation(routeTagName()) - ) - .build(); - } -} diff --git a/backend/src/main/java/ca/bc/gov/app/routes/openmaps/OpenMapsRouter.java b/backend/src/main/java/ca/bc/gov/app/routes/openmaps/OpenMapsRouter.java deleted file mode 100644 index 6bc1423e17..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/routes/openmaps/OpenMapsRouter.java +++ /dev/null @@ -1,47 +0,0 @@ -package ca.bc.gov.app.routes.openmaps; - -import static org.springdoc.webflux.core.fn.SpringdocRouteBuilder.route; -import static org.springframework.web.reactive.function.server.RequestPredicates.accept; - -import ca.bc.gov.app.handlers.openmaps.OpenMapsHandler; -import ca.bc.gov.app.routes.BaseRouter; -import lombok.RequiredArgsConstructor; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -@RequiredArgsConstructor -public class OpenMapsRouter implements BaseRouter { - - private final OpenMapsHandler openMapsHandler; - - @Override - public String basePath() { - return "/maps"; - } - - @Override - public String routeTagName() { - return "OpenMaps"; - } - - @Override - public String routeTagDescription() { - return "Exposes OpanMaps consumption for First nation data extraction"; - } - - @Override - public RouterFunction routerRoute() { - return route() - .GET( - "/firstNation/{id}", - accept(MediaType.ALL), - openMapsHandler::handle, - openMapsHandler.documentation(routeTagName()) - ) - .build(); - } - -} diff --git a/backend/src/main/java/ca/bc/gov/app/routes/orgbook/OrgBookRouter.java b/backend/src/main/java/ca/bc/gov/app/routes/orgbook/OrgBookRouter.java deleted file mode 100644 index 2a9ec3c7c0..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/routes/orgbook/OrgBookRouter.java +++ /dev/null @@ -1,57 +0,0 @@ -package ca.bc.gov.app.routes.orgbook; - -import static org.springdoc.webflux.core.fn.SpringdocRouteBuilder.route; -import static org.springframework.web.reactive.function.server.RequestPredicates.accept; - -import ca.bc.gov.app.handlers.orgbook.OrgBookIncorporationHandler; -import ca.bc.gov.app.handlers.orgbook.OrgBookNameHandler; -import ca.bc.gov.app.routes.BaseRouter; -import lombok.RequiredArgsConstructor; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -@RequiredArgsConstructor -public class OrgBookRouter implements BaseRouter { - - private final OrgBookIncorporationHandler handler; - private final OrgBookNameHandler nameHandler; - - @Override - public String basePath() { - return "/orgbook"; - } - - @Override - public String routeTagName() { - return "OrgBook"; - } - - @Override - public String routeTagDescription() { - return "A route for BC OrgBook data access and consumption"; - } - - @Override - public RouterFunction routerRoute() { - return - route() - .GET( - "/incorporation/{incorporationId}", - accept(MediaType.ALL), - handler::handle, - handler.documentation(routeTagName()) - ) - - .GET( - "/name/{name}", - accept(MediaType.ALL), - nameHandler::handle, - nameHandler.documentation(routeTagName()) - ) - .build(); - } - -} diff --git a/backend/src/main/java/ca/bc/gov/app/service/ches/ChesCommonServicesService.java b/backend/src/main/java/ca/bc/gov/app/service/ches/ChesCommonServicesService.java index e92a5d138d..206f2c17c7 100644 --- a/backend/src/main/java/ca/bc/gov/app/service/ches/ChesCommonServicesService.java +++ b/backend/src/main/java/ca/bc/gov/app/service/ches/ChesCommonServicesService.java @@ -86,7 +86,7 @@ public Mono sendEmail(ChesRequest requestContent) { .bodyToMono(ChesMailResponse.class) .map(response -> response.txId().toString()) - .doOnError(error -> log.error("Failed to send email", error)); + .doOnError(error -> log.error("Failed to send contactEmail", error)); } @@ -145,7 +145,7 @@ private String getToken() { .accessToken(request, OAuth.HttpMethod.POST, OAuthJSONAccessTokenResponse.class) .getAccessToken(); } catch (Exception e) { - log.error("Failed to get email authentication token", e); + log.error("Failed to get contactEmail authentication token", e); throw new CannotExtractTokenException(); } diff --git a/backend/src/main/java/ca/bc/gov/app/service/client/ClientService.java b/backend/src/main/java/ca/bc/gov/app/service/client/ClientService.java index 7f0d388811..e70f044090 100644 --- a/backend/src/main/java/ca/bc/gov/app/service/client/ClientService.java +++ b/backend/src/main/java/ca/bc/gov/app/service/client/ClientService.java @@ -3,7 +3,9 @@ import static ca.bc.gov.app.util.ClientMapper.mapToSubmissionDetailEntity; import static ca.bc.gov.app.util.ClientMapper.mapToSubmissionLocationContactEntity; import static ca.bc.gov.app.util.ClientMapper.mapToSubmissionLocationEntity; +import static ca.bc.gov.app.util.ClientMapper.mapToSubmitterEntity; +import ca.bc.gov.app.repository.client.SubmitterRepository; import ca.bc.gov.app.dto.bcregistry.BcRegistryAddressDto; import ca.bc.gov.app.dto.bcregistry.BcRegistryBusinessAdressesDto; import ca.bc.gov.app.dto.bcregistry.BcRegistryBusinessDto; @@ -42,6 +44,7 @@ import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; + @Service @RequiredArgsConstructor public class ClientService { @@ -50,6 +53,8 @@ public class ClientService { private final ProvinceCodeRepository provinceCodeRepository; private final ContactTypeCodeRepository contactTypeCodeRepository; private final SubmissionRepository submissionRepository; + + private final SubmitterRepository submitterRepository; private final SubmissionDetailRepository submissionDetailRepository; private final SubmissionLocationRepository submissionLocationRepository; private final SubmissionLocationContactRepository submissionLocationContactRepository; @@ -65,8 +70,6 @@ public class ClientService { * @param targetDate The date to be used as reference. * @return A list of {@link ClientNameCodeDto} */ - - public Flux findActiveClientTypeCodes(LocalDate targetDate) { return @@ -131,25 +134,28 @@ public Mono submit(ClientSubmissionDto clientSubmissionDto) { SubmissionEntity submissionEntity = SubmissionEntity .builder() - .createdBy(UUID.randomUUID().toString()) //TODO: receive user id - .submissionDate(LocalDateTime.now()) .submitterUserId(UUID.randomUUID().toString()) //TODO: set the correct user .submissionStatus(SubmissionStatusEnum.S) .submissionDate(LocalDateTime.now()) + .createdBy(UUID.randomUUID().toString()) //TODO: receive user id .build(); return submissionRepository.save(submissionEntity) .map(submission -> - mapToSubmissionDetailEntity( + mapToSubmitterEntity( submission.getSubmissionId(), + clientSubmissionDto.submitterInformation())) + .flatMap(submitterRepository::save) + .map(submitter -> + mapToSubmissionDetailEntity( + submitter.getSubmissionId(), clientSubmissionDto) ) .flatMap(submissionDetailRepository::save) .flatMap(submissionDetail -> submitLocations( - clientSubmissionDto.clientLocationDto(), - submissionDetail.getSubmissionId() - ) + clientSubmissionDto.location(), + submissionDetail.getSubmissionId()) .thenReturn(submissionDetail.getSubmissionId()) ); } @@ -237,28 +243,25 @@ private Function> expa private Mono submitLocations(ClientLocationDto clientLocationDto, Integer submissionId) { return Flux.fromIterable(clientLocationDto - .clientAddressDto()) + .addresses()) .flatMap(addressDto -> submissionLocationRepository .save(mapToSubmissionLocationEntity(submissionId, addressDto)) .flatMap(location -> - submitLocationContacts(addressDto, location.getSubmissionLocationId()) - ) - ) + submitLocationContacts(addressDto, location.getSubmissionLocationId()))) .then(); } private Mono submitLocationContacts(ClientAddressDto addressDto, Integer submissionLocationId) { return Flux - .fromIterable(addressDto.clientContactDtoList()) + .fromIterable(addressDto.contacts()) .flatMap(contactDto -> submissionLocationContactRepository.save( mapToSubmissionLocationContactEntity( submissionLocationId, - contactDto) - ) - ) + contactDto))) .then(); } + } diff --git a/backend/src/main/java/ca/bc/gov/app/util/ClientMapper.java b/backend/src/main/java/ca/bc/gov/app/util/ClientMapper.java index af056b278d..b5d2a8c768 100644 --- a/backend/src/main/java/ca/bc/gov/app/util/ClientMapper.java +++ b/backend/src/main/java/ca/bc/gov/app/util/ClientMapper.java @@ -1,12 +1,14 @@ package ca.bc.gov.app.util; import ca.bc.gov.app.dto.client.ClientAddressDto; +import ca.bc.gov.app.dto.client.ClientBusinessInformationDto; import ca.bc.gov.app.dto.client.ClientContactDto; -import ca.bc.gov.app.dto.client.ClientInformationDto; import ca.bc.gov.app.dto.client.ClientSubmissionDto; +import ca.bc.gov.app.dto.client.ClientSubmitterInformationDto; import ca.bc.gov.app.entity.client.SubmissionDetailEntity; import ca.bc.gov.app.entity.client.SubmissionLocationContactEntity; import ca.bc.gov.app.entity.client.SubmissionLocationEntity; +import ca.bc.gov.app.entity.client.SubmitterEntity; import java.time.LocalDate; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -14,21 +16,33 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public class ClientMapper { + public static SubmitterEntity mapToSubmitterEntity( + Integer submissionId, + ClientSubmitterInformationDto clientSubmitter) { + return new SubmitterEntity() + .withSubmissionId(submissionId) + .withFirstName(clientSubmitter.submitterFirstName()) + .withLastName(clientSubmitter.submitterLastName()) + .withPhoneNumber(clientSubmitter.submitterPhoneNumber()) + .withEmailAddress(clientSubmitter.submitterEmail()); + } + public static SubmissionDetailEntity mapToSubmissionDetailEntity( Integer submissionId, ClientSubmissionDto clientSubmissionDto) { - ClientInformationDto clientInformationDto = clientSubmissionDto.clientInformationDto(); + ClientBusinessInformationDto + clientBusinessInformationDto = clientSubmissionDto.businessInformation(); return new SubmissionDetailEntity() .withSubmissionId(submissionId) - .withIncorporationNumber(clientInformationDto.incorporationNumber()) - .withOrganizationName(clientInformationDto.businessName()) - .withFirstName(clientInformationDto.firstName()) - .withLastName(clientInformationDto.lastName()) - .withClientTypeCode(clientSubmissionDto.clientBusinessTypeDto().clientType()) - .withDateOfBirth(LocalDate.parse(clientInformationDto.birthdate())) - .withDoingBusinessAsName(clientInformationDto.doingBusinessAsName()); + .withIncorporationNumber(clientBusinessInformationDto.incorporationNumber()) + .withOrganizationName(clientBusinessInformationDto.businessName()) + .withFirstName(clientBusinessInformationDto.firstName()) + .withLastName(clientBusinessInformationDto.lastName()) + .withClientTypeCode(clientSubmissionDto.businessType().clientType().value()) + .withDateOfBirth(LocalDate.parse(clientBusinessInformationDto.birthdate())) + .withDoingBusinessAsName(clientBusinessInformationDto.doingBusinessAsName()); } public static SubmissionLocationEntity mapToSubmissionLocationEntity( @@ -49,9 +63,10 @@ public static SubmissionLocationContactEntity mapToSubmissionLocationContactEnti ) { return new SubmissionLocationContactEntity() .withSubmissionLocationId(submissionLocationId) + .withContactTypeCode(clientContactDto.contactType()) + .withContactTypeCode(clientContactDto.contactType()) .withFirstName(clientContactDto.firstName()) .withLastName(clientContactDto.lastName()) - .withContactTypeCode(clientContactDto.contactType()) .withBusinessPhoneNumber(clientContactDto.businessPhone()) .withEmailAddress(clientContactDto.email()); } diff --git a/backend/src/main/java/ca/bc/gov/app/util/HandlerUtil.java b/backend/src/main/java/ca/bc/gov/app/util/HandlerUtil.java deleted file mode 100644 index b6d69e54ad..0000000000 --- a/backend/src/main/java/ca/bc/gov/app/util/HandlerUtil.java +++ /dev/null @@ -1,37 +0,0 @@ -package ca.bc.gov.app.util; - -import java.util.Optional; -import java.util.function.Consumer; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.web.reactive.function.BodyInserters; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class HandlerUtil { - - - public static Consumer handleStatusResponse() { - return t -> ServerResponse.status(t.getStatusCode()) - .body( - BodyInserters - .fromPublisher( - Mono - .justOrEmpty( - Optional - .ofNullable(t.getReason()) - ), - String.class - ) - ); - } - - public static Consumer handleError() { - return throwable -> - ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(BodyInserters.fromValue(throwable.getMessage())); - } -} diff --git a/backend/src/test/java/ca/bc/gov/app/endpoints/client/ClientHandlerIntegrationTest.java b/backend/src/test/java/ca/bc/gov/app/endpoints/client/ClientControllerIntegrationTest.java similarity index 83% rename from backend/src/test/java/ca/bc/gov/app/endpoints/client/ClientHandlerIntegrationTest.java rename to backend/src/test/java/ca/bc/gov/app/endpoints/client/ClientControllerIntegrationTest.java index 422020e93c..383ee47f11 100644 --- a/backend/src/test/java/ca/bc/gov/app/endpoints/client/ClientHandlerIntegrationTest.java +++ b/backend/src/test/java/ca/bc/gov/app/endpoints/client/ClientControllerIntegrationTest.java @@ -7,18 +7,11 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import ca.bc.gov.app.TestConstants; -import ca.bc.gov.app.dto.client.ClientAddressDto; -import ca.bc.gov.app.dto.client.ClientBusinessTypeDto; -import ca.bc.gov.app.dto.client.ClientContactDto; -import ca.bc.gov.app.dto.client.ClientInformationDto; -import ca.bc.gov.app.dto.client.ClientLocationDto; -import ca.bc.gov.app.dto.client.ClientSubmissionDto; import ca.bc.gov.app.extensions.AbstractTestContainerIntegrationTest; import ca.bc.gov.app.extensions.WiremockLogNotifier; import com.github.tomakehurst.wiremock.junit5.WireMockExtension; import java.net.URI; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Stream; @@ -34,11 +27,10 @@ import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.web.util.UriBuilder; -import reactor.core.publisher.Mono; @Slf4j @DisplayName("Integrated Test | FSA Client Controller") -class ClientHandlerIntegrationTest extends AbstractTestContainerIntegrationTest { +class ClientControllerIntegrationTest extends AbstractTestContainerIntegrationTest { @Autowired protected WebTestClient client; @@ -173,46 +165,6 @@ void shouldListContactTypes(Integer page, Integer size, String code, String desc .jsonPath("$[0].name").isEqualTo(description); } - @Test - @DisplayName("Submit client data") - void shouldSubmitClientData() { - ClientSubmissionDto clientSubmissionDto = - new ClientSubmissionDto( - new ClientBusinessTypeDto("A"), - new ClientInformationDto( - "James", "Bond", "2007-07-07", - "12345", "MI6", "Espionage"), - new ClientLocationDto( - List.of( - new ClientAddressDto( - "3570 S Las Vegas Blvd", - "US", - "NV", - "Las Vegas", - "89109", - "007", - 0, - List.of( - new ClientContactDto( - "LP", - "James", - "Doe", - "007", - "bond_james_bond@007.com", - 0)) - ))) - ); - client - .post() - .uri("/api/clients/submissions") - .body(Mono.just(clientSubmissionDto), ClientSubmissionDto.class) - .exchange() - .expectStatus().isCreated() - .expectHeader().location("/api/clients/submissions/1") - .expectHeader().valueEquals("x-sub-id", 1) - .expectBody().isEmpty(); - } - @ParameterizedTest @MethodSource("clientDetailing") @DisplayName("Client details") @@ -324,7 +276,7 @@ private static Stream countryCode() { Arguments.of(null, null, "CA", "Canada"), Arguments.of(0, 1, "CA", "Canada"), Arguments.of(1, 1, "US", "United States of America"), - Arguments.of(7, null, "BN", "Brunei Darussalam"), + Arguments.of(7, null, "EE", "Estonia"), Arguments.of(3, 10, "BA", "Bosnia and Herzegovina"), Arguments.of(33, 1, "BR", "Brazil"), Arguments.of(49, 1, "CO", "Colombia") diff --git a/backend/src/test/java/ca/bc/gov/app/endpoints/client/ClientSubmissionControllerIntegrationTest.java b/backend/src/test/java/ca/bc/gov/app/endpoints/client/ClientSubmissionControllerIntegrationTest.java new file mode 100644 index 0000000000..fbc871b7e0 --- /dev/null +++ b/backend/src/test/java/ca/bc/gov/app/endpoints/client/ClientSubmissionControllerIntegrationTest.java @@ -0,0 +1,61 @@ +package ca.bc.gov.app.endpoints.client; + +import ca.bc.gov.app.dto.client.ClientAddressDto; +import ca.bc.gov.app.dto.client.ClientBusinessInformationDto; +import ca.bc.gov.app.dto.client.ClientBusinessTypeDto; +import ca.bc.gov.app.dto.client.ClientContactDto; +import ca.bc.gov.app.dto.client.ClientLocationDto; +import ca.bc.gov.app.dto.client.ClientSubmissionDto; +import ca.bc.gov.app.dto.client.ClientSubmitterInformationDto; +import ca.bc.gov.app.dto.client.ClientTypeDto; +import ca.bc.gov.app.extensions.AbstractTestContainerIntegrationTest; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.web.reactive.server.WebTestClient; +import reactor.core.publisher.Mono; + +@Slf4j +@DisplayName("Integrated Test | FSA Client Submission Controller") +public class ClientSubmissionControllerIntegrationTest + extends AbstractTestContainerIntegrationTest { + + @Autowired + protected WebTestClient client; + + @Test + @DisplayName("Submit client data") + void shouldSubmitClientData() { + ClientSubmissionDto clientSubmissionDto = + new ClientSubmissionDto( + new ClientBusinessTypeDto(new ClientTypeDto("A", "Association")), + new ClientBusinessInformationDto( + "Auric", "", "1964-07-07", + "1234", "test", "Auric Enterprises"), + new ClientLocationDto( + List.of( + new ClientAddressDto( + "3570 S Las Vegas Blvd", "US", "NV", + "Las Vegas", "89109", 0, + List.of( + new ClientContactDto( + "LP", "James", "007", + "987654321", "bond_james_bond@007.com", + 0))))), + new ClientSubmitterInformationDto( + "James", "Bond", "1234567890", + "james_bond@MI6.com") + ); + client + .post() + .uri("/api/clients/submissions") + .body(Mono.just(clientSubmissionDto), ClientSubmissionDto.class) + .exchange() + .expectStatus().isCreated() + .expectHeader().location("/api/clients/submissions/1") + .expectHeader().valueEquals("x-sub-id", "1") + .expectBody().isEmpty(); + } +} diff --git a/common/Dockerfile b/common/Dockerfile new file mode 100644 index 0000000000..ec8bde6ad6 --- /dev/null +++ b/common/Dockerfile @@ -0,0 +1,24 @@ +FROM eclipse-temurin:17-jdk-alpine + +WORKDIR /app + +ENV LANG en_CA.UTF-8 +ENV LANGUAGE en_CA.UTF-8 +ENV LC_ALL en_CA.UTF-8 +ENV JAVA_OPS -Xms512m -Xmx512m + +COPY startup.sh . +COPY InstallCert.java . + +RUN chmod g+w /app && \ + chmod g+x startup.sh && \ + chmod g+w ${JAVA_HOME}/lib/security/cacerts + +EXPOSE 3001 + +HEALTHCHECK --interval=35s --timeout=4s CMD wget --spider -S http://127.0.0.1:3001/health || exit 1 + +# Non-privileged user +USER app + +ENTRYPOINT ["sh", "startup.sh"] \ No newline at end of file diff --git a/legacy/InstallCert.java b/common/InstallCert.java similarity index 92% rename from legacy/InstallCert.java rename to common/InstallCert.java index 93e5e2bc72..b38da026cf 100644 --- a/legacy/InstallCert.java +++ b/common/InstallCert.java @@ -125,6 +125,7 @@ public static void main(String[] args) throws Exception { TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); + X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0]; SavingTrustManager tm = new SavingTrustManager(defaultTrustManager); context.init(null, new TrustManager[] {tm}, null); @@ -180,10 +181,9 @@ public static void main(String[] args) throws Exception { System.out.println(); } - int k; + int k = 0; if (isQuiet) { System.out.println("Adding first certificate to trusted keystore"); - k = 0; } else { System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]"); String line = reader.readLine().trim(); @@ -195,18 +195,28 @@ public static void main(String[] args) throws Exception { } } - X509Certificate cert = chain[k]; - String alias = host + "-" + (k + 1); - ks.setCertificateEntry(alias, cert); + if (isQuiet) { + for (int c = 0; c < chain.length; c++){ + X509Certificate cert = chain[c]; + System.out.println(String.valueOf(cert.getSubjectDN())); + String alias = String.valueOf(cert.getSubjectDN()).replace("CN=",""); + ks.setCertificateEntry(alias, cert); + + System.out.println(); + System.out.println(cert); + System.out.println(); + System.out.println("Added certificate to keystore 'jssecacerts' using alias '" + alias + "'"); + } + }else{ + X509Certificate cert = chain[k]; + String alias = host + "-" + (k + 1); + ks.setCertificateEntry(alias, cert); + } OutputStream out = new FileOutputStream("jssecacerts"); ks.store(out, passphrase); out.close(); - System.out.println(); - System.out.println(cert); - System.out.println(); - System.out.println("Added certificate to keystore 'jssecacerts' using alias '" + alias + "'"); } private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); diff --git a/common/startup.sh b/common/startup.sh new file mode 100644 index 0000000000..45ad4e9e1d --- /dev/null +++ b/common/startup.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +mkdir -p /cert/certs +rm -rf /cert/certs/* + +echo "I will try to get the ${ORACLEDB_HOST}-1 cert" +echo "Connecting to ${ORACLEDB_HOST}:${ORACLEDB_PORT}" +java --source 17 InstallCert.java --quiet "${ORACLEDB_HOST}:${ORACLEDB_PORT}" + +cp jssecacerts /cert/jssecacerts \ No newline at end of file diff --git a/legacy/Dockerfile b/legacy/Dockerfile deleted file mode 100644 index e41e213496..0000000000 --- a/legacy/Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ -FROM openjdk:17.0.2@sha256:528707081fdb9562eb819128a9f85ae7fe000e2fbaeaf9f87662e7b3f38cb7d8 as build -WORKDIR /app -COPY . ./ -RUN chmod +x ./mvnw -RUN ./mvnw clean package -DskipTests -Dtests.skip=true -Dskip.unit.tests=true - -FROM eclipse-temurin:17.0.6_10-jdk-alpine@sha256:b99f9457ad5cabdfa02935d1048082dd79d318685cfa0ca79a8f623c052c406a -LABEL maintainer="Paulo Gomes da Cruz Junior " - -WORKDIR /app - -ENV LANG en_CA.UTF-8 -ENV LANGUAGE en_CA.UTF-8 -ENV LC_ALL en_CA.UTF-8 -ENV JAVA_OPS -Xms512m -Xmx512m - -COPY --from=build /app/target/nr-forest-client-legacy.jar /app/service.jar -COPY startup.sh . -COPY InstallCert.java . - -RUN chmod g+w /app && \ - chmod g+x startup.sh && \ - chmod g+w ${JAVA_HOME}/lib/security/cacerts - -EXPOSE 9000 - -HEALTHCHECK --interval=35s --timeout=4s CMD wget --spider -S http://127.0.0.1:9000/health || exit 1 - -# Non-privileged user -USER app - -ENTRYPOINT ["sh", "startup.sh"] \ No newline at end of file diff --git a/legacy/config/application.yml b/legacy/config/application.yml index e2124b816c..78aa482225 100644 --- a/legacy/config/application.yml +++ b/legacy/config/application.yml @@ -1,3 +1,3 @@ spring: r2dbc: - url: r2dbc:oracle://${ca.bc.gov.nrs.oracle.host}/${ca.bc.gov.nrs.oracle.database} \ No newline at end of file + url: r2dbc:oracle://${ca.bc.gov.nrs.oracle.host}:${ca.bc.gov.nrs.oracle.port}/${ca.bc.gov.nrs.oracle.database} \ No newline at end of file diff --git a/legacy/openshift.deploy.yml b/legacy/openshift.deploy.yml index 94386b72ef..118531ff10 100644 --- a/legacy/openshift.deploy.yml +++ b/legacy/openshift.deploy.yml @@ -41,7 +41,12 @@ parameters: required: true - name: ORACLEDB_SERVICENAME description: Oracle database service name - required: true + required: true + - name: ORACLEDB_KEYSTORE + description: Oracle database keystore file + - name: ORACLEDB_SECRET + description: Oracle database keystore secret/password + required: true - name: CPU_REQUEST value: 75m - name: CPU_LIMIT @@ -64,6 +69,7 @@ objects: oracle-database: "${ORACLEDB_DATABASE}" oracle-host: "${ORACLEDB_HOST}" oracle-service: "${ORACLEDB_SERVICENAME}" + oracle-secret: "${ORACLEDB_SECRET}" - apiVersion: v1 kind: ImageStream metadata: @@ -108,6 +114,24 @@ objects: app: ${NAME}-${ZONE} deploymentconfig: ${NAME}-${ZONE}-${COMPONENT} spec: + volumes: + - name: certs + emptyDir: { } + initContainers: + - name: ${NAME}-init + image: ${REGISTRY}/bcgov/${NAME}/common:${ZONE} + imagePullPolicy: Always + env: + - name: ORACLEDB_HOST + valueFrom: + secretKeyRef: + name: ${NAME}-${ZONE}-${COMPONENT} + key: oracle-host + - name: ORACLEDB_PORT + value: "1543" + volumeMounts: + - mountPath: /cert + name: certs containers: - image: ${NAME}-${ZONE}-${COMPONENT}:${IMAGE_TAG} imagePullPolicy: Always @@ -148,6 +172,13 @@ objects: key: oracle-service - name: ORACLEDB_PORT value: "1543" + - name: ORACLEDB_SECRET + valueFrom: + secretKeyRef: + name: ${NAME}-${ZONE}-${COMPONENT} + key: oracle-secret + - name: ORACLEDB_KEYSTORE + value: /cert/jssecacerts ports: - containerPort: 9000 protocol: TCP @@ -162,12 +193,25 @@ objects: successThreshold: 1 failureThreshold: 30 httpGet: - path: / + path: /health + port: 9000 + scheme: HTTP + initialDelaySeconds: 3 + periodSeconds: 30 + timeoutSeconds: 5 + livenessProbe: + successThreshold: 1 + failureThreshold: 12 + httpGet: + path: /health port: 9000 scheme: HTTP - initialDelaySeconds: 60 + initialDelaySeconds: 3 periodSeconds: 30 timeoutSeconds: 5 + volumeMounts: + - mountPath: /cert + name: certs - apiVersion: v1 kind: Service metadata: diff --git a/legacy/pom.xml b/legacy/pom.xml index 5a7b439bcb..db2db273f3 100644 --- a/legacy/pom.xml +++ b/legacy/pom.xml @@ -66,6 +66,7 @@ 1.9.1 2022.0.1 + ${project.version} @@ -188,6 +189,11 @@ + + org.graalvm.buildtools + native-maven-plugin + + org.springframework.boot spring-boot-maven-plugin @@ -198,6 +204,27 @@ lombok + + + gcr.io/paketo-buildpacks/graalvm + gcr.io/paketo-buildpacks/java-native-image + gcr.io/paketo-buildpacks/image-labels + + + 19.0.2 + https://github.com/bcgov/nr-forest-client + ${project.version} + ${project.description} + Apache License, Version 2.0 + ${oci.revision} + ${project.name} + ${timestamp} + true + + + + false + diff --git a/legacy/src/main/java/ca/bc/gov/app/LegacyApplication.java b/legacy/src/main/java/ca/bc/gov/app/LegacyApplication.java index 747a171942..31e73eeb28 100644 --- a/legacy/src/main/java/ca/bc/gov/app/LegacyApplication.java +++ b/legacy/src/main/java/ca/bc/gov/app/LegacyApplication.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.servers.Server; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -10,7 +11,10 @@ title = "${info.app.name}", version = "${info.app.version}", description = "${info.app.description}" -) +), + servers = { + @Server(url = "/", description = "Default Server URL") + } ) public class LegacyApplication { diff --git a/legacy/src/main/java/ca/bc/gov/app/configuration/RouteConfiguration.java b/legacy/src/main/java/ca/bc/gov/app/configuration/RouteConfiguration.java deleted file mode 100644 index 2ec079f57f..0000000000 --- a/legacy/src/main/java/ca/bc/gov/app/configuration/RouteConfiguration.java +++ /dev/null @@ -1,92 +0,0 @@ -package ca.bc.gov.app.configuration; - -import static org.springframework.web.reactive.function.server.RequestPredicates.path; -import static org.springframework.web.reactive.function.server.RouterFunctions.nest; - -import ca.bc.gov.app.routes.BaseRouter; -import io.swagger.v3.oas.models.examples.Example; -import io.swagger.v3.oas.models.media.StringSchema; -import io.swagger.v3.oas.models.parameters.Parameter; -import io.swagger.v3.oas.models.tags.Tag; -import java.util.List; -import java.util.Map; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.customizers.OpenApiCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.MediaType; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Configuration -@Slf4j -public class RouteConfiguration { - - @Bean - public RouterFunction routes(List routes) { - return - routes - .stream() - .map(route -> nest( - path(String.format("/api%s", route.basePath())), - route.routerRoute() - ) - ) - .reduce(RouterFunction::and) - .orElseThrow(); - - } - - @Bean - public OpenApiCustomizer tagCustomizer(List routes) { - return openAPI -> { - routes.forEach(route -> - openAPI - .addTagsItem( - new Tag() - .name(route.routeTagName()) - .description(route.routeTagDescription()) - ) - ); - - openAPI - .getPaths() - .values() - .forEach(pathItem -> - pathItem - .addParametersItem( - new Parameter() - .schema(new StringSchema()) - .required(true) - .examples( - Map.of( - "json", - new Example().value(MediaType.APPLICATION_JSON_VALUE), - "eventstream", - new Example().value(MediaType.TEXT_EVENT_STREAM_VALUE) - ) - ) - .in("header") - .name("Content-Type") - ) - .addParametersItem( - new Parameter() - .schema(new StringSchema()) - .required(true) - .examples( - Map.of( - "json", - new Example().value(MediaType.APPLICATION_JSON_VALUE), - "eventstream", - new Example().value(MediaType.TEXT_EVENT_STREAM_VALUE) - ) - ) - .in("header") - .name("accept") - ) - ); - }; - } - - -} diff --git a/legacy/src/main/java/ca/bc/gov/app/controller/ClientSearchController.java b/legacy/src/main/java/ca/bc/gov/app/controller/ClientSearchController.java new file mode 100644 index 0000000000..36e91ed31d --- /dev/null +++ b/legacy/src/main/java/ca/bc/gov/app/controller/ClientSearchController.java @@ -0,0 +1,131 @@ +package ca.bc.gov.app.controller; + +import ca.bc.gov.app.dto.ForestClientDto; +import ca.bc.gov.app.service.ClientSearchService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; + +@RestController +@Slf4j +@Tag( + name = "Search Client", + description = "Search clients based on some criterias" +) +@RequestMapping(value = "/api/search", produces = MediaType.APPLICATION_JSON_VALUE) +@RequiredArgsConstructor +public class ClientSearchController { + + private final ClientSearchService service; + + @GetMapping("/incorporationOrName") + @Operation( + summary = "List forest client entries by incorporation number or name", + responses = { + @ApiResponse( + responseCode = "200", + description = "Returns a client based on it's number", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + array = @ArraySchema( + schema = @Schema( + name = "ForestClient", + implementation = ForestClientDto.class + ) + ) + ) + ), + @ApiResponse( + responseCode = "412", + description = "Missing value for parameter incorporationNumber or companyName", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = String.class), + examples = { + @ExampleObject( + value = + "Missing value for parameter incorporationNumber or companyName") + } + ) + ) + } + ) + public Flux findByIncorporationOrName( + @Parameter(description = "The incorporation ID to lookup", example = "BC0772006") + @RequestParam(required = false) String incorporationNumber, + + @Parameter(description = "The name to lookup", example = "Power Corp") + @RequestParam(required = false) String companyName + ) { + return service + .findByIncorporationOrName(incorporationNumber, companyName); + } + + @GetMapping("/nameAndBirth") + @Operation( + summary = "List forest client entries by first name, last name and date of birth", + responses = { + @ApiResponse( + responseCode = "200", + description = "Returns a client based on it's number", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + array = @ArraySchema( + schema = @Schema( + name = "ForestClient", + implementation = ForestClientDto.class + ) + ) + ) + ) + } + ) + public Flux findByNameAndBirth( + @Parameter( + description = "First name to lookup. For companies, you can pass an empty value", + example = "Jhon", + required = false + ) + @RequestParam(required = false,defaultValue = "") String firstName, + + @Parameter( + description = "Last name to lookup. For companies, this will be the company name", + example = "Doh", + required = false + ) + @RequestParam(required = false) String lastName, + + @Parameter( + description = """ + Date of birth to lookup in an ISO Local Date format, + such as YYYY-MM-dd.
+ For companies, you can pass an empty value""", + example = "1955-05-09", + required = false + ) + @RequestParam(required = false,defaultValue = "") String birthdate + ) { + return service + .findByNameAndBirth( + Optional.ofNullable(firstName), + Optional.ofNullable(lastName), + Optional.ofNullable(birthdate) + ); + } + + +} diff --git a/legacy/src/main/java/ca/bc/gov/app/controller/ForestClientController.java b/legacy/src/main/java/ca/bc/gov/app/controller/ForestClientController.java new file mode 100644 index 0000000000..0547917c97 --- /dev/null +++ b/legacy/src/main/java/ca/bc/gov/app/controller/ForestClientController.java @@ -0,0 +1,103 @@ +package ca.bc.gov.app.controller; + +import ca.bc.gov.app.dto.ClientPublicViewDto; +import ca.bc.gov.app.dto.FirstNationBandVidationDto; +import ca.bc.gov.app.dto.ForestClientDto; +import ca.bc.gov.app.service.ForestClientService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; + +@RestController +@Slf4j +@Tag( + name = "Forest Client", + description = "Aggregation and other reports for forest clients" +) +@RequestMapping(value = "/api/client", produces = MediaType.APPLICATION_JSON_VALUE) +@RequiredArgsConstructor +public class ForestClientController { + + private final ForestClientService service; + + @GetMapping("/bands") + @Operation( + summary = "List First nation band validation information", + responses = { + @ApiResponse( + responseCode = "200", + description = "Returns a client based on it's number", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + array = @ArraySchema( + schema = @Schema( + name = "FirstNationBand", + implementation = FirstNationBandVidationDto.class + ) + ) + ) + ) + } + ) + public Flux getFirstNationBandInfo() { + return service.getFirstNationBandInfo(); + } + + + @GetMapping("/business") + @Operation( + summary = "List all clients we are doing business with", + responses = { + @ApiResponse( + responseCode = "200", + description = "Returns a client based on it's number", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + array = @ArraySchema( + schema = @Schema( + name = "ClientInformation", + implementation = ClientPublicViewDto.class + ) + ) + ) + ) + } + ) + public Flux getClientDoingBusiness() { + return service.getClientDoingBusiness(); + } + + @GetMapping("/unregistered") + @Operation( + summary = "List all clients that are unregistered", + responses = { + @ApiResponse( + responseCode = "200", + description = "Returns a client based on it's number", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + array = @ArraySchema( + schema = @Schema( + name = "ClientInformation", + implementation = ClientPublicViewDto.class + ) + ) + ) + ) + } + ) + public Flux getUnregisteredCompanies() { + return service.getUnregisteredCompanies(); + } +} diff --git a/backend/src/main/java/ca/bc/gov/app/handlers/GlobalErrorHandler.java b/legacy/src/main/java/ca/bc/gov/app/controller/GlobalErrorController.java similarity index 95% rename from backend/src/main/java/ca/bc/gov/app/handlers/GlobalErrorHandler.java rename to legacy/src/main/java/ca/bc/gov/app/controller/GlobalErrorController.java index 02019d37db..db7ceff1d8 100644 --- a/backend/src/main/java/ca/bc/gov/app/handlers/GlobalErrorHandler.java +++ b/legacy/src/main/java/ca/bc/gov/app/controller/GlobalErrorController.java @@ -1,4 +1,4 @@ -package ca.bc.gov.app.handlers; +package ca.bc.gov.app.controller; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.BooleanUtils; @@ -29,9 +29,9 @@ @Slf4j @Component @Order(-2) -public class GlobalErrorHandler extends AbstractErrorWebExceptionHandler { +public class GlobalErrorController extends AbstractErrorWebExceptionHandler { - public GlobalErrorHandler( + public GlobalErrorController( ErrorAttributes errorAttributes, WebProperties webProperties, ApplicationContext applicationContext, diff --git a/legacy/src/main/java/ca/bc/gov/app/handlers/BaseHandler.java b/legacy/src/main/java/ca/bc/gov/app/handlers/BaseHandler.java deleted file mode 100644 index 5e53a53525..0000000000 --- a/legacy/src/main/java/ca/bc/gov/app/handlers/BaseHandler.java +++ /dev/null @@ -1,13 +0,0 @@ -package ca.bc.gov.app.handlers; - -import java.util.function.Consumer; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -public interface BaseHandler { - Mono handle(ServerRequest serverRequest); - Consumer documentation(String tag); - -} diff --git a/legacy/src/main/java/ca/bc/gov/app/handlers/ClientSearchIncorporationHandler.java b/legacy/src/main/java/ca/bc/gov/app/handlers/ClientSearchIncorporationHandler.java deleted file mode 100644 index ae0733a43d..0000000000 --- a/legacy/src/main/java/ca/bc/gov/app/handlers/ClientSearchIncorporationHandler.java +++ /dev/null @@ -1,109 +0,0 @@ -package ca.bc.gov.app.handlers; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.arrayschema.Builder.arraySchemaBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.ForestClientDto; -import ca.bc.gov.app.service.ClientSearchService; -import ca.bc.gov.app.util.HandlerUtil; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@RequiredArgsConstructor -@Slf4j -public class ClientSearchIncorporationHandler implements BaseHandler { - private final ClientSearchService service; - - @Override - public Mono handle(ServerRequest serverRequest) { - return - ServerResponse - .ok() - .contentType(serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON)) - .body( - service - .findByIncorporationOrName( - serverRequest.queryParam("incorporationNumber").orElse(null), - serverRequest.queryParam("companyName").orElse(null) - ), - ForestClientDto.class - ) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops - .tag(tag) - .description("List forest client entries by incorporation number or name") - .beanClass(ClientSearchIncorporationHandler.class) - .beanMethod("handle") - .operationId("handle") - .parameter( - parameterBuilder() - .description("The incorporation ID to lookup") - .allowEmptyValue(true) - .example("BC0772006") - .schema(schemaBuilder().implementation(String.class)) - .in(ParameterIn.QUERY) - .name("incorporationNumber") - ) - .parameter( - parameterBuilder() - .description("The name to lookup") - .allowEmptyValue(true) - .example("Power Corp") - .schema(schemaBuilder().implementation(String.class)) - .in(ParameterIn.QUERY) - .name("companyName") - ) - .response( - responseBuilder() - .responseCode("200") - .description("Found") - .content( - contentBuilder() - .array( - arraySchemaBuilder() - .schema( - schemaBuilder() - .name("ForestClient") - .implementation(ForestClientDto.class) - ) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ) - .response( - responseBuilder() - .responseCode("412") - .description("Missing value for parameter incorporationNumber or companyName") - .content( - contentBuilder() - .schema( - schemaBuilder() - .implementation(String.class) - .example( - "Missing value for parameter incorporationNumber or companyName") - ) - - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ); - } -} - diff --git a/legacy/src/main/java/ca/bc/gov/app/handlers/ClientSearchNameBirthHandler.java b/legacy/src/main/java/ca/bc/gov/app/handlers/ClientSearchNameBirthHandler.java deleted file mode 100644 index 03b68c44b1..0000000000 --- a/legacy/src/main/java/ca/bc/gov/app/handlers/ClientSearchNameBirthHandler.java +++ /dev/null @@ -1,109 +0,0 @@ -package ca.bc.gov.app.handlers; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.arrayschema.Builder.arraySchemaBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.ApplicationConstants; -import ca.bc.gov.app.dto.ForestClientDto; -import ca.bc.gov.app.service.ClientSearchService; -import ca.bc.gov.app.util.HandlerUtil; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@RequiredArgsConstructor -@Slf4j -public class ClientSearchNameBirthHandler implements BaseHandler { - - private final ClientSearchService service; - - @Override - public Mono handle(ServerRequest serverRequest) { - return - ServerResponse - .ok() - .contentType(serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON)) - .body( - service - .findByNameAndBirth( - serverRequest - .queryParam(ApplicationConstants.CLIENT_SEARCH_FIRST_NAME), - serverRequest - .queryParam(ApplicationConstants.CLIENT_SEARCH_LAST_NAME), - serverRequest - .queryParam(ApplicationConstants.CLIENT_SEARCH_BIRTHDATE) - ), - ForestClientDto.class) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops - .tag(tag) - .description("List forest client entries by first name, last name and date of birth") - .beanClass(ClientSearchNameBirthHandler.class) - .beanMethod("handle") - .operationId("handle") - .parameter( - parameterBuilder() - .description("First name to lookup. For companies, you can pass an empty value") - .allowEmptyValue(true) - .example("Jhon") - .schema(schemaBuilder().implementation(String.class)) - .in(ParameterIn.QUERY) - .name(ApplicationConstants.CLIENT_SEARCH_FIRST_NAME) - ) - .parameter( - parameterBuilder() - .description("Last name to lookup. For companies, this will be the company name") - .allowEmptyValue(false) - .example("Doh") - .schema(schemaBuilder().implementation(String.class)) - .in(ParameterIn.QUERY) - .name(ApplicationConstants.CLIENT_SEARCH_LAST_NAME) - ) - .parameter( - parameterBuilder() - .description(""" - Date of birth to lookup in an ISO Local Date format, - such as YYYY-MM-dd.
- For companies, you can pass an empty value""") - .allowEmptyValue(true) - .example("1955-05-09") - .schema(schemaBuilder().implementation(String.class)) - .in(ParameterIn.QUERY) - .name(ApplicationConstants.CLIENT_SEARCH_BIRTHDATE) - ) - .response( - responseBuilder() - .responseCode("200") - .description("Found") - .content( - contentBuilder() - .array( - arraySchemaBuilder() - .schema( - schemaBuilder() - .name("ForestClient") - .implementation(ForestClientDto.class) - ) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ); - } -} diff --git a/legacy/src/main/java/ca/bc/gov/app/handlers/ForestClientBandsHandler.java b/legacy/src/main/java/ca/bc/gov/app/handlers/ForestClientBandsHandler.java deleted file mode 100644 index a7308b7220..0000000000 --- a/legacy/src/main/java/ca/bc/gov/app/handlers/ForestClientBandsHandler.java +++ /dev/null @@ -1,64 +0,0 @@ -package ca.bc.gov.app.handlers; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.arrayschema.Builder.arraySchemaBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.FirstNationBandVidationDto; -import ca.bc.gov.app.service.ForestClientService; -import ca.bc.gov.app.util.HandlerUtil; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@RequiredArgsConstructor -@Slf4j -public class ForestClientBandsHandler implements BaseHandler { - - private final ForestClientService service; - - @Override - public Mono handle(ServerRequest serverRequest) { - return ServerResponse - .ok() - .contentType(serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON)) - .body(service.getFirstNationBandInfo(), FirstNationBandVidationDto.class) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops.tag(tag) - .description("List First nation band validation information") - .beanClass(ForestClientBandsHandler.class) - .beanMethod("handle") - .operationId("handle") - .response( - responseBuilder() - .responseCode("200") - .description("Found") - .content( - contentBuilder() - .array( - arraySchemaBuilder() - .schema( - schemaBuilder() - .name("FirstNationBand") - .implementation(FirstNationBandVidationDto.class) - ) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ); - } -} diff --git a/legacy/src/main/java/ca/bc/gov/app/handlers/ForestClientBusinessHandler.java b/legacy/src/main/java/ca/bc/gov/app/handlers/ForestClientBusinessHandler.java deleted file mode 100644 index 9db1cedade..0000000000 --- a/legacy/src/main/java/ca/bc/gov/app/handlers/ForestClientBusinessHandler.java +++ /dev/null @@ -1,65 +0,0 @@ -package ca.bc.gov.app.handlers; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.arrayschema.Builder.arraySchemaBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.ClientPublicViewDto; -import ca.bc.gov.app.service.ForestClientService; -import ca.bc.gov.app.util.HandlerUtil; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@RequiredArgsConstructor -@Slf4j -public class ForestClientBusinessHandler implements BaseHandler { - - private final ForestClientService service; - - @Override - public Mono handle(ServerRequest serverRequest) { - return ServerResponse - .ok() - .contentType(serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON)) - .body(service.getClientDoingBusiness(), ClientPublicViewDto.class) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops.tag(tag) - .description("List all clients we are doing business with") - .beanClass(ForestClientBusinessHandler.class) - .beanMethod("handle") - .operationId("handle") - .response( - responseBuilder() - .responseCode("200") - .description("Found") - .content( - contentBuilder() - .array( - arraySchemaBuilder() - .schema( - schemaBuilder() - .name("ClientInformation") - .implementation(ClientPublicViewDto.class) - ) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ); - } - -} diff --git a/legacy/src/main/java/ca/bc/gov/app/handlers/ForestClientUnregisteredHandler.java b/legacy/src/main/java/ca/bc/gov/app/handlers/ForestClientUnregisteredHandler.java deleted file mode 100644 index b17753ec44..0000000000 --- a/legacy/src/main/java/ca/bc/gov/app/handlers/ForestClientUnregisteredHandler.java +++ /dev/null @@ -1,63 +0,0 @@ -package ca.bc.gov.app.handlers; - -import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; -import static org.springdoc.core.fn.builders.arrayschema.Builder.arraySchemaBuilder; -import static org.springdoc.core.fn.builders.content.Builder.contentBuilder; -import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder; - -import ca.bc.gov.app.dto.ClientPublicViewDto; -import ca.bc.gov.app.service.ForestClientService; -import ca.bc.gov.app.util.HandlerUtil; -import java.util.function.Consumer; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springdoc.core.fn.builders.operation.Builder; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.server.ResponseStatusException; -import reactor.core.publisher.Mono; - -@Component -@RequiredArgsConstructor -@Slf4j -public class ForestClientUnregisteredHandler implements BaseHandler { - - private final ForestClientService service; - @Override - public Mono handle(ServerRequest serverRequest) { - return ServerResponse - .ok() - .contentType(serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON)) - .body(service.getUnregisteredCompanies(), ClientPublicViewDto.class) - .doOnError(ResponseStatusException.class, HandlerUtil.handleStatusResponse()) - .doOnError(HandlerUtil.handleError()); - } - - @Override - public Consumer documentation(String tag) { - return ops -> ops.tag(tag) - .description("List all clients that are unregistered") - .beanClass(ForestClientUnregisteredHandler.class) - .beanMethod("handle") - .operationId("handle") - .response( - responseBuilder() - .responseCode("200") - .description("Found") - .content( - contentBuilder() - .array( - arraySchemaBuilder() - .schema( - schemaBuilder() - .name("ClientInformation") - .implementation(ClientPublicViewDto.class) - ) - ) - .mediaType(MediaType.APPLICATION_JSON_VALUE) - ) - ); - } -} diff --git a/legacy/src/main/java/ca/bc/gov/app/routes/BaseRouter.java b/legacy/src/main/java/ca/bc/gov/app/routes/BaseRouter.java deleted file mode 100644 index f6393699e4..0000000000 --- a/legacy/src/main/java/ca/bc/gov/app/routes/BaseRouter.java +++ /dev/null @@ -1,15 +0,0 @@ -package ca.bc.gov.app.routes; - -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerResponse; - -public interface BaseRouter { - String basePath(); - - RouterFunction routerRoute(); - - String routeTagName(); - - String routeTagDescription(); - -} diff --git a/legacy/src/main/java/ca/bc/gov/app/routes/ClientSearchRouter.java b/legacy/src/main/java/ca/bc/gov/app/routes/ClientSearchRouter.java deleted file mode 100644 index fdb3507167..0000000000 --- a/legacy/src/main/java/ca/bc/gov/app/routes/ClientSearchRouter.java +++ /dev/null @@ -1,55 +0,0 @@ -package ca.bc.gov.app.routes; - -import static org.springdoc.webflux.core.fn.SpringdocRouteBuilder.route; -import static org.springframework.web.reactive.function.server.RequestPredicates.accept; - -import ca.bc.gov.app.handlers.ClientSearchIncorporationHandler; -import ca.bc.gov.app.handlers.ClientSearchNameBirthHandler; -import lombok.RequiredArgsConstructor; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -@RequiredArgsConstructor -public class ClientSearchRouter implements BaseRouter { - - private final ClientSearchNameBirthHandler nameBirthHandler; - private final ClientSearchIncorporationHandler incorporationHandler; - - @Override - public String basePath() { - return "/search"; - } - - @Override - public String routeTagName() { - return "Search Client"; - } - - @Override - public String routeTagDescription() { - return "Search clients based on some criterias"; - } - - @Override - public RouterFunction routerRoute() { - return - route() - .GET( - "/incorporationOrName", - accept(MediaType.APPLICATION_JSON, MediaType.TEXT_EVENT_STREAM), - incorporationHandler::handle, - incorporationHandler.documentation(routeTagName()) - ) - .GET( - "/nameAndBirth", - accept(MediaType.APPLICATION_JSON, MediaType.TEXT_EVENT_STREAM), - nameBirthHandler::handle, - nameBirthHandler.documentation(routeTagName()) - ) - .build(); - } - -} diff --git a/legacy/src/main/java/ca/bc/gov/app/routes/ForestClientRouter.java b/legacy/src/main/java/ca/bc/gov/app/routes/ForestClientRouter.java deleted file mode 100644 index eaa0f17bb2..0000000000 --- a/legacy/src/main/java/ca/bc/gov/app/routes/ForestClientRouter.java +++ /dev/null @@ -1,64 +0,0 @@ -package ca.bc.gov.app.routes; - -import static org.springdoc.webflux.core.fn.SpringdocRouteBuilder.route; -import static org.springframework.web.reactive.function.server.RequestPredicates.accept; - -import ca.bc.gov.app.handlers.ForestClientBandsHandler; -import ca.bc.gov.app.handlers.ForestClientBusinessHandler; -import ca.bc.gov.app.handlers.ForestClientUnregisteredHandler; -import lombok.RequiredArgsConstructor; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -@RequiredArgsConstructor -public class ForestClientRouter implements BaseRouter { - - private final ForestClientBusinessHandler businessHandler; - private final ForestClientBandsHandler bandsHandler; - - private final ForestClientUnregisteredHandler unregisteredHandler; - - @Override - public String basePath() { - return "/client"; - } - - @Override - public String routeTagName() { - return "Forest Client"; - } - - @Override - public String routeTagDescription() { - return "Aggregation and other reports for forest clients"; - } - - @Override - public RouterFunction routerRoute() { - return route() - .GET( - "/bands", - accept(MediaType.APPLICATION_JSON, MediaType.TEXT_EVENT_STREAM), - bandsHandler::handle, - bandsHandler.documentation(routeTagName()) - ) - .GET( - "/business", - accept(MediaType.APPLICATION_JSON, MediaType.TEXT_EVENT_STREAM), - businessHandler::handle, - businessHandler.documentation(routeTagName()) - ) - .GET( - "/unregistered", - accept(MediaType.APPLICATION_JSON, MediaType.TEXT_EVENT_STREAM), - unregisteredHandler::handle, - unregisteredHandler.documentation(routeTagName()) - ) - .build(); - } - - -} diff --git a/legacy/src/main/resources/application.yml b/legacy/src/main/resources/application.yml index 7abcfcd527..e824229093 100644 --- a/legacy/src/main/resources/application.yml +++ b/legacy/src/main/resources/application.yml @@ -9,7 +9,7 @@ spring: banner-mode: "off" allow-bean-definition-overriding: true r2dbc: - url: r2dbcs:oracle:thin:@tcps://${ca.bc.gov.nrs.oracle.host}/${ca.bc.gov.nrs.oracle.service} + url: r2dbcs:oracle:thin:@tcps://${ca.bc.gov.nrs.oracle.host}:${ca.bc.gov.nrs.oracle.port}/${ca.bc.gov.nrs.oracle.service}?javax.net.ssl.trustStore=${ca.bc.gov.nrs.oracle.keystore}&javax.net.ssl.trustStorePassword=${ca.bc.gov.nrs.oracle.secret}&javax.net.ssl.keyStore=${ca.bc.gov.nrs.oracle.keystore}&javax.net.ssl.keyStorePassword=${ca.bc.gov.nrs.oracle.secret}&oracle.net.ssl_certificate_alias=${ca.bc.gov.nrs.oracle.host}&oracle.net.ssl_server_dn_match=false username: ${ca.bc.gov.nrs.oracle.username} password: ${ca.bc.gov.nrs.oracle.password} pool: @@ -23,6 +23,7 @@ spring: poolName: FsaLegacyClientConPool management: + enable-native-support: true endpoint: health: show-details: always @@ -51,6 +52,9 @@ ca: oracle: service: ${ORACLEDB_SERVICENAME:fsa-forest} database: ${ORACLEDB_DATABASE:fsa-forest} - host: ${ORACLEDB_HOST:localhost}:${ORACLEDB_PORT:1521} + host: ${ORACLEDB_HOST:localhost} + port: ${ORACLEDB_PORT:1521} username: ${ORACLEDB_USER:user} - password: ${ORACLEDB_PASSWORD:passwd} \ No newline at end of file + password: ${ORACLEDB_PASSWORD:passwd} + keystore: ${ORACLEDB_KEYSTORE:jssecacerts.jks} + secret: ${ORACLEDB_SECRET:changeit} \ No newline at end of file diff --git a/legacy/src/test/java/ca/bc/gov/app/extensions/AbstractTestContainerIntegrationTest.java b/legacy/src/test/java/ca/bc/gov/app/extensions/AbstractTestContainerIntegrationTest.java index a5f8753176..436751a5fc 100644 --- a/legacy/src/test/java/ca/bc/gov/app/extensions/AbstractTestContainerIntegrationTest.java +++ b/legacy/src/test/java/ca/bc/gov/app/extensions/AbstractTestContainerIntegrationTest.java @@ -19,7 +19,7 @@ public abstract class AbstractTestContainerIntegrationTest { static final OracleContainer database; static { - database = new OracleContainer("gvenzl/oracle-xe:21-slim-faststart") + database = new OracleContainer("gvenzl/oracle-xe:21.3.0-slim-faststart") .withDatabaseName("legacyfsa") .withUsername("THE") .withPassword(UUID.randomUUID().toString().substring(24)); @@ -43,11 +43,12 @@ static void registerDynamicProperties(DynamicPropertyRegistry registry) { registry .add( "ca.bc.gov.nrs.oracle.host", - () -> String.format("%s:%d", - database.getHost(), - database.getMappedPort(1521) - ) - ); + database::getHost); + + registry + .add( + "ca.bc.gov.nrs.oracle.port", + () -> database.getMappedPort(1521)); registry .add( diff --git a/legacy/src/test/resources/application-default.yml b/legacy/src/test/resources/application-default.yml index 7cb677bf6c..f2a9fdf789 100644 --- a/legacy/src/test/resources/application-default.yml +++ b/legacy/src/test/resources/application-default.yml @@ -4,12 +4,14 @@ server: enabled: false spring: + r2dbc: + url: r2dbc:oracle://${ca.bc.gov.nrs.oracle.host}:${ca.bc.gov.nrs.oracle.port}/${ca.bc.gov.nrs.oracle.database} flyway: enabled: true validate-on-migrate: true user: ${ca.bc.gov.nrs.oracle.username} password: ${ca.bc.gov.nrs.oracle.password} - url: jdbc:oracle:thin:@${ca.bc.gov.nrs.oracle.host}/${ca.bc.gov.nrs.oracle.service} + url: jdbc:oracle:thin:@${ca.bc.gov.nrs.oracle.host}:${ca.bc.gov.nrs.oracle.port}/${ca.bc.gov.nrs.oracle.service} ca: diff --git a/legacy/startup.sh b/legacy/startup.sh deleted file mode 100644 index e6580fa976..0000000000 --- a/legacy/startup.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -java --source 17 InstallCert.java --quiet "${ORACLEDB_HOST}:${ORACLEDB_PORT}" -keytool -exportcert -alias "${ORACLEDB_HOST}-1" -keystore jssecacerts -storepass changeit -file oracle.cer -keytool -importcert -alias orakey -noprompt -cacerts -storepass changeit -file oracle.cer - -java -Djava.security.egd=file:/dev/./urandom -jar /app/service.jar -