diff --git a/.github/workflows/api.yaml b/.github/workflows/api.yaml deleted file mode 100644 index fbdf4d0..0000000 --- a/.github/workflows/api.yaml +++ /dev/null @@ -1,54 +0,0 @@ -name: API CI - -on: - workflow_dispatch: - push: - branches: - - master - - 'feature/**' - - 'Feature/**' - - 'fix/*' - - 'Fix/*' - paths: - - 'api/**' - pull_request: - branches: [ master ] - paths: - - 'api/**' -jobs: - quality_profile: - - runs-on: ubuntu-latest - - defaults: - run: - working-directory: api - - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - uses: actions/setup-java@v1 - with: - java-version: 11 - - uses: actions/cache@v1 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Run unit tests - run: mvn clean package - - name: Cache SonarCloud packages - uses: actions/cache@v1 - with: - path: ~/.sonar/cache - key: ${{ runner.os }}-sonar - - name: Run Sonar Analysis - run: mvn -f pom.xml sonar:sonar - -Dsonar.login=${{ secrets.SONAR_TOKEN }} - -Dsonar.host.url=https://sonarcloud.io - -Dsonar.organization=bcgov-sonarcloud - -Dsonar.projectKey=${{ secrets.SONAR_PROJECT_KEY }} - env: - GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/workflows/ci-api.build.and.test.yml b/.github/workflows/ci-api.build.and.test.yml index 104a843..4ebef9d 100644 --- a/.github/workflows/ci-api.build.and.test.yml +++ b/.github/workflows/ci-api.build.and.test.yml @@ -1,6 +1,7 @@ name: API CI on: + workflow_dispatch: push: branches: - main @@ -24,22 +25,23 @@ jobs: working-directory: api steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v3 with: - java-version: 11 - - uses: actions/cache@v1 + java-version: 17 + distribution: oracle + - uses: actions/cache@v3 with: path: ~/.m2/repository - key: ${{ runner.os }}-maven-5Jun-${{ hashFiles('**/pom.xml') }} + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | - ${{ runner.os }}-maven-5Jun- + ${{ runner.os }}-maven- - name: Run unit tests run: mvn -f pom.xml clean package - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@0.2.5 + uses: aquasecurity/trivy-action@0.13.0 with: scan-type: 'fs' ignore-unfixed: true @@ -48,11 +50,11 @@ jobs: severity: 'CRITICAL' - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v1 + uses: github/codeql-action/upload-sarif@v2 with: sarif_file: 'trivy-results.sarif' - name: Cache SonarCloud packages - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar diff --git a/.github/workflows/deploy-to.openshift-dev.yml b/.github/workflows/deploy-to.openshift-dev.yml index 4783462..bdede75 100644 --- a/.github/workflows/deploy-to.openshift-dev.yml +++ b/.github/workflows/deploy-to.openshift-dev.yml @@ -33,7 +33,7 @@ env: TAG: "latest" TARGET_ENV: "dev" MIN_REPLICAS: "1" - MAX_REPLICAS: "1" + MAX_REPLICAS: "2" MIN_CPU: "75m" MAX_CPU: "150m" MIN_MEM: "400Mi" @@ -47,7 +47,7 @@ jobs: openshift-ci-cd: name: Build and deploy to OpenShift DEV # ubuntu-20.04 can also be used. - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 environment: dev outputs: @@ -56,7 +56,7 @@ jobs: steps: - name: Check for required secrets - uses: actions/github-script@v4 + uses: actions/github-script@v6 with: script: | const secrets = { @@ -94,7 +94,7 @@ jobs: } - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Determine image tags if: env.IMAGE_TAGS == '' @@ -102,7 +102,7 @@ jobs: echo "IMAGE_TAGS=latest ${GITHUB_SHA::12}" | tee -a $GITHUB_ENV - name: Login to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: ${{ env.DOCKER_ARTIFACTORY_REPO }} username: ${{ secrets.DOCKER_HUB_USERNAME }} @@ -141,7 +141,7 @@ jobs: oc: 4 # https://github.com/redhat-actions/oc-login#readme - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Deploy API run: | @@ -169,6 +169,6 @@ jobs: oc rollout status dc/${{ env.SPRING_BOOT_IMAGE_NAME }} - name: ZAP Scan - uses: zaproxy/action-api-scan@v0.1.0 + uses: zaproxy/action-api-scan@v0.5.0 with: - target: 'https://${{ env.APP_NAME }}-${{ env.OPENSHIFT_NAMESPACE }}-dev.apps.silver.devops.gov.bc.ca/v3/api-docs' \ No newline at end of file + target: 'https://${{ env.APP_NAME }}-${{ env.OPENSHIFT_NAMESPACE }}-dev.apps.silver.devops.gov.bc.ca/v3/api-docs' diff --git a/.github/workflows/deploy-to.openshift-prod.yml b/.github/workflows/deploy-to.openshift-prod.yml index 17e5fb8..12b2d04 100644 --- a/.github/workflows/deploy-to.openshift-prod.yml +++ b/.github/workflows/deploy-to.openshift-prod.yml @@ -27,7 +27,7 @@ env: TAG: "latest" TARGET_ENV: "prod" MIN_REPLICAS: "3" - MAX_REPLICAS: "3" + MAX_REPLICAS: "5" MIN_CPU: "75m" MAX_CPU: "150m" MIN_MEM: "400Mi" @@ -41,7 +41,7 @@ jobs: openshift-ci-cd: name: Deploy to OpenShift PROD # ubuntu-20.04 can also be used. - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 environment: production outputs: @@ -50,7 +50,7 @@ jobs: steps: - name: Check for required secrets - uses: actions/github-script@v4 + uses: actions/github-script@v6 with: script: | const secrets = { @@ -88,7 +88,7 @@ jobs: } - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Get latest tag uses: actions-ecosystem/action-get-latest-tag@v1 @@ -100,7 +100,7 @@ jobs: oc: 4 # https://github.com/redhat-actions/oc-login#readme - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Deploy run: | set -eux @@ -124,4 +124,4 @@ jobs: || true && echo "Rollout in progress" oc logs -f dc/${{ env.SPRING_BOOT_IMAGE_NAME }} # Get status, returns 0 if rollout is successful - oc rollout status dc/${{ env.SPRING_BOOT_IMAGE_NAME }} \ No newline at end of file + oc rollout status dc/${{ env.SPRING_BOOT_IMAGE_NAME }} diff --git a/.github/workflows/deploy-to.openshift-test.yml b/.github/workflows/deploy-to.openshift-test.yml index 2bc40ee..e389c1e 100644 --- a/.github/workflows/deploy-to.openshift-test.yml +++ b/.github/workflows/deploy-to.openshift-test.yml @@ -27,7 +27,7 @@ env: TAG: "latest" TARGET_ENV: "test" MIN_REPLICAS: "3" - MAX_REPLICAS: "3" + MAX_REPLICAS: "5" MIN_CPU: "75m" MAX_CPU: "150m" MIN_MEM: "400Mi" @@ -41,7 +41,7 @@ jobs: openshift-ci-cd: name: Deploy to OpenShift TEST # ubuntu-20.04 can also be used. - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 environment: test outputs: @@ -50,7 +50,7 @@ jobs: steps: - name: Check for required secrets - uses: actions/github-script@v4 + uses: actions/github-script@v6 with: script: | const secrets = { @@ -88,7 +88,7 @@ jobs: } - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Get latest tag uses: actions-ecosystem/action-get-latest-tag@v1 @@ -100,7 +100,7 @@ jobs: oc: 4 # https://github.com/redhat-actions/oc-login#readme - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Deploy run: | set -eux @@ -124,4 +124,4 @@ jobs: || true && echo "Rollout in progress" oc logs -f dc/${{ env.SPRING_BOOT_IMAGE_NAME }} # Get status, returns 0 if rollout is successful - oc rollout status dc/${{ env.SPRING_BOOT_IMAGE_NAME }} \ No newline at end of file + oc rollout status dc/${{ env.SPRING_BOOT_IMAGE_NAME }} diff --git a/.github/workflows/tag-create.git.and.imagestream.tag.yml b/.github/workflows/tag-create.git.and.imagestream.tag.yml index 1b674b9..e0f9591 100644 --- a/.github/workflows/tag-create.git.and.imagestream.tag.yml +++ b/.github/workflows/tag-create.git.and.imagestream.tag.yml @@ -27,7 +27,7 @@ jobs: openshift-ci-cd: name: Tag Image # ubuntu-20.04 can also be used. - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 environment: dev outputs: @@ -36,10 +36,10 @@ jobs: steps: - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Create tag - uses: actions/github-script@v5 + uses: actions/github-script@v6 with: script: | github.rest.git.createRef({ @@ -55,7 +55,7 @@ jobs: oc: 4 # https://github.com/redhat-actions/oc-login#readme - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Tag in OpenShift run: | set -eux @@ -63,4 +63,4 @@ jobs: oc login --token=${{ env.OPENSHIFT_TOKEN }} --server=${{ env.OPENSHIFT_SERVER }} oc project ${{ env.OPENSHIFT_NAMESPACE }} - oc tag ${{ env.NAMESPACE }}-dev/${{ env.REPO_NAME }}-${{ env.BRANCH }}:latest ${{ env.NAMESPACE }}-dev/${{ env.REPO_NAME }}-${{ env.BRANCH }}:${{ github.event.inputs.version }} \ No newline at end of file + oc tag ${{ env.NAMESPACE }}-dev/${{ env.REPO_NAME }}-${{ env.BRANCH }}:latest ${{ env.NAMESPACE }}-dev/${{ env.REPO_NAME }}-${{ env.BRANCH }}:${{ github.event.inputs.version }} diff --git a/Dockerfile b/Dockerfile index 2a64de3..524bcf2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM artifacts.developer.gov.bc.ca/docker-remote/maven:3-jdk-11 as build +FROM artifacts.developer.gov.bc.ca/docker-remote/maven:3.8.7-openjdk-18 AS build WORKDIR /workspace/app COPY api/pom.xml . @@ -10,7 +10,7 @@ FROM build AS vulnscan COPY --from=artifacts.developer.gov.bc.ca/docker-remote/aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy RUN trivy filesystem --severity CRITICAL --exit-code 0 --no-progress / -FROM artifacts.developer.gov.bc.ca/docker-remote/openjdk:11-jdk as pen-myed +FROM artifacts.developer.gov.bc.ca/docker-remote/openjdk:18.0.2.1-jdk-oracle AS pen-myed RUN useradd -ms /bin/bash spring RUN mkdir -p /logs RUN chown -R spring:spring /logs diff --git a/api/pom.xml b/api/pom.xml index 3a5c3d7..8a95e11 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -14,7 +14,7 @@ src/main/resources/**, - 11 + 17 3.8.0 ${java.version} @@ -22,6 +22,7 @@ 1.4.1.Final 4.20.0 1.5.2 + 1.18.30 2.11.0 12.2.0.1 30.1.1-jre diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/controller/v1/PenMyEdController.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/controller/v1/PenMyEdController.java index 9c26365..bb7cfeb 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/controller/v1/PenMyEdController.java +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/controller/v1/PenMyEdController.java @@ -8,7 +8,7 @@ import ca.bc.gov.educ.api.pen.myed.mappers.v1.PenRegBatchMapper; import ca.bc.gov.educ.api.pen.myed.service.v1.PenMyEdService; import ca.bc.gov.educ.api.pen.myed.struct.v1.*; -import ca.bc.gov.educ.api.pen.myed.struct.v1.school.PenCoordinator; +import ca.bc.gov.educ.api.pen.myed.struct.v1.school.StudentRegistrationContact; import ca.bc.gov.educ.api.pen.myed.validator.PenMyEdPayloadValidator; import lombok.extern.slf4j.Slf4j; import lombok.val; @@ -81,8 +81,8 @@ public Mono> batchSubmissionResult(final UU } @Override - public Mono>> getPenCoordinators() { - return this.penMyEdService.getPenCoordinators(); + public List getStudentRegistrationContacts() { + return this.penMyEdService.getStudentRegistrationContacts(); } @Override diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/endpoint/v1/PenMyEdApiEndpoint.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/endpoint/v1/PenMyEdApiEndpoint.java index 7ed324f..9b4dd08 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/endpoint/v1/PenMyEdApiEndpoint.java +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/endpoint/v1/PenMyEdApiEndpoint.java @@ -1,7 +1,7 @@ package ca.bc.gov.educ.api.pen.myed.endpoint.v1; import ca.bc.gov.educ.api.pen.myed.struct.v1.*; -import ca.bc.gov.educ.api.pen.myed.struct.v1.school.PenCoordinator; +import ca.bc.gov.educ.api.pen.myed.struct.v1.school.StudentRegistrationContact; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.media.ArraySchema; @@ -65,10 +65,10 @@ public interface PenMyEdApiEndpoint { */ @GetMapping("/pen-coordinators") @PreAuthorize("hasAuthority('SCOPE_MYED_READ_PEN_COORDINATOR')") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(name = "PenCoordinator", implementation = PenCoordinator.class)))), + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(name = "StudentRegistrationContact", implementation = StudentRegistrationContact.class)))), @ApiResponse(responseCode = "404", description = "NOT FOUND")}) - @Tag(name = "Endpoint to get all Pen Coordinators.", description = "Endpoint to get all Pen Coordinators.") - Mono>> getPenCoordinators(); + @Tag(name = "Endpoint to get all student registration contacts.", description = "Endpoint to get all student registration contacts.") + List getStudentRegistrationContacts(); /** diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/properties/ApplicationProperties.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/properties/ApplicationProperties.java index 99ecf33..73dcf57 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/properties/ApplicationProperties.java +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/properties/ApplicationProperties.java @@ -5,61 +5,26 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -/** - * The type Application properties. - */ @Component @Getter @Setter public class ApplicationProperties { - /** - * The constant API_NAME. - */ public static final String API_NAME = "PEN_MYED_API"; - /** - * The Client id. - */ @Value("${client.id}") private String clientID; - /** - * The Client secret. - */ @Value("${client.secret}") private String clientSecret; - /** - * The Token url. - */ @Value("${url.token}") private String tokenURL; - - /** - * The Pen reg batch api url. - */ @Value("${url.api.pen.reg.batch}") private String penRegBatchApiUrl; - - /** - * The School api url. - */ - @Value("${url.api.school}") - private String schoolApiUrl; - - /** - * The Pen services api url. - */ + @Value("${url.api.institute}") + private String instituteApiUrl; @Value("${url.api.pen.services}") private String penServicesApiURL; - - /** - * The Pen match api url. - */ @Value("${url.api.pen.match}") private String penMatchApiURL; - - /** - * The Student api url. - */ @Value("${url.api.student}") private String studentApiURL; diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/rest/RestUtils.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/rest/RestUtils.java index 26110bc..2dfb2b0 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/rest/RestUtils.java +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/rest/RestUtils.java @@ -9,15 +9,19 @@ import ca.bc.gov.educ.api.pen.myed.struct.v1.PenRequestBatchSubmissionResult; import ca.bc.gov.educ.api.pen.myed.struct.v1.PenRequestResult; import ca.bc.gov.educ.api.pen.myed.struct.v1.Request; +import ca.bc.gov.educ.api.pen.myed.struct.v1.district.District; +import ca.bc.gov.educ.api.pen.myed.struct.v1.district.DistrictContactSearchWrapper; import ca.bc.gov.educ.api.pen.myed.struct.v1.penregbatch.PenRequestBatch; -import ca.bc.gov.educ.api.pen.myed.struct.v1.school.PenCoordinator; import ca.bc.gov.educ.api.pen.myed.struct.v1.school.School; +import ca.bc.gov.educ.api.pen.myed.struct.v1.school.SchoolContactSearchWrapper; +import ca.bc.gov.educ.api.pen.myed.struct.v1.school.StudentRegistrationContact; import ca.bc.gov.educ.api.pen.myed.struct.v1.student.RestPageImpl; import ca.bc.gov.educ.api.pen.myed.struct.v1.student.Student; import com.google.common.util.concurrent.ThreadFactoryBuilder; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import lombok.val; +import org.apache.commons.lang3.StringUtils; import org.jboss.threads.EnhancedQueueExecutor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -25,7 +29,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; @@ -36,6 +39,7 @@ import javax.annotation.PostConstruct; import java.net.URI; import java.time.Duration; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -64,15 +68,15 @@ public class RestUtils { * The School lock. */ private final ReadWriteLock schoolLock = new ReentrantReadWriteLock(); - /** - * The School map. - */ + @Getter - private final Map schoolMap = new ConcurrentHashMap<>(); + private final Map schoolMincodeMap = new ConcurrentHashMap<>(); - /** - * The Props. - */ + @Getter + private final Map schoolIDMap = new ConcurrentHashMap<>(); + + @Getter + private final Map districtIDMap = new ConcurrentHashMap<>(); private final ApplicationProperties props; /** @@ -105,12 +109,12 @@ public RestUtils(final ApplicationProperties props, final WebClient webClient) { public void init() { if (this.isBackgroundInitializationEnabled != null && this.isBackgroundInitializationEnabled) { this.bgTask.execute(() -> { - this.populateSchoolMap(); - this.getPenCoordinators().block(); + this.populateSchoolMaps(); + this.populateDistrictMap(); }); } else { - this.populateSchoolMap(); - this.getPenCoordinators().block(); + this.populateSchoolMaps(); + this.populateDistrictMap(); } } @@ -128,14 +132,19 @@ public void scheduled() { } } - /** - * Populate school map. - */ - private void populateSchoolMap() { + private void populateSchoolMaps() { for (val school : this.getSchools()) { - this.schoolMap.put(school.getDistNo() + school.getSchlNo(), school); + this.schoolMincodeMap.put(school.getMincode(), school); + this.schoolIDMap.put(school.getSchoolId(), school); } - log.info("loaded {} schools to memory", this.schoolMap.values().size()); + log.info("Loaded {} schools to memory", this.schoolIDMap.values().size()); + } + + private void populateDistrictMap() { + for (val district : this.getDistricts()) { + this.districtIDMap.put(district.getDistrictId(), district); + } + log.info("Loaded {} districts to memory", this.districtIDMap.values().size()); } /** @@ -160,20 +169,26 @@ public Mono> postBatchSubmission(final PenRequestBatch pe }); } - /** - * Gets schools. - * - * @return the schools - */ + public List getDistricts() { + log.info("Calling Institute api to get list of districts"); + return this.webClient.get() + .uri(this.props.getInstituteApiUrl() + "/district") + .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .retrieve() + .bodyToFlux(District.class) + .collectList() + .block(); + } + public List getSchools() { - log.info("calling school api to load schools to memory"); + log.info("Calling Institute api to get list of schools"); return this.webClient.get() - .uri(this.props.getSchoolApiUrl()) - .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .retrieve() - .bodyToFlux(School.class) - .collectList() - .block(); + .uri(this.props.getInstituteApiUrl() + "/school") + .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .retrieve() + .bodyToFlux(School.class) + .collectList() + .block(); } /** @@ -229,21 +244,69 @@ public Mono> postPenRequestToBatchAPI(final Req }); } - public Mono>> getPenCoordinators() { - log.info("making api call to get pen coordinators data "); - return this.webClient.get() - .uri(this.props.getSchoolApiUrl() + "/pen-coordinator") - .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .exchangeToMono(response -> { - if (response.statusCode().equals(HttpStatus.OK)) { - log.info("API call to get Pen coordinators success :: {}", response.rawStatusCode()); - return response.toEntity(new ParameterizedTypeReference>() { - }); - } else { - log.error("API call to get Pen coordinators failed :: {}", response.rawStatusCode()); - return Mono.just(ResponseEntity.status(response.statusCode()).build()); - } + private URI getSchoolContactURI(String criterion){ + return UriComponentsBuilder.fromHttpUrl(this.props.getInstituteApiUrl() + "/school/contact/paginated") + .queryParam("pageNumber", "0") + .queryParam("pageSize", "10000") + .queryParam("searchCriteriaList", criterion).build().toUri(); + } + + private URI getDistrictContactURI(String criterion){ + return UriComponentsBuilder.fromHttpUrl(this.props.getInstituteApiUrl() + "/district/contact/paginated") + .queryParam("pageNumber", "0") + .queryParam("pageSize", "10000") + .queryParam("searchCriteriaList", criterion).build().toUri(); + } + + public List getStudentRegistrationContactList() { + try { + log.info("Calling Institute api to get list of school and district student registration contacts"); + String criterion = "[{\"searchCriteriaList\":[{\"key\":\"schoolContactTypeCode\",\"operation\":\"eq\",\"value\":\"STUDREGIS\",\"valueType\":\"STRING\",\"condition\":\"AND\"}]}]"; + SchoolContactSearchWrapper schoolContactSearchWrapper = this.webClient.get() + .uri(getSchoolContactURI(criterion)) + .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .retrieve() + .bodyToFlux(SchoolContactSearchWrapper.class) + .blockFirst(); + + criterion = "[{\"searchCriteriaList\":[{\"key\":\"districtContactTypeCode\",\"operation\":\"eq\",\"value\":\"STUDREGIS\",\"valueType\":\"STRING\",\"condition\":\"AND\"}]}]"; + DistrictContactSearchWrapper districtContactSearchWrapper = this.webClient.get() + .uri(getDistrictContactURI(criterion)) + .header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .retrieve() + .bodyToFlux(DistrictContactSearchWrapper.class) + .blockFirst(); + + var schools = getSchoolIDMap(); + var districts = getDistrictIDMap(); + + List studentRegistrationContacts = new ArrayList<>(); + schoolContactSearchWrapper.getContent().forEach(schoolContact -> { + var school = schools.get(schoolContact.getSchoolId()); + StudentRegistrationContact coordinator = new StudentRegistrationContact(); + coordinator.setMincode(school.getMincode()); + coordinator.setDistrictNumber(school.getMincode().substring(0, 3)); + coordinator.setSchoolNumber(school.getMincode().substring(4)); + coordinator.setPenCoordinatorName(StringUtils.trim(schoolContact.getFirstName() + " " + schoolContact.getLastName())); + coordinator.setPenCoordinatorEmail(schoolContact.getEmail()); + studentRegistrationContacts.add(coordinator); + }); + + districtContactSearchWrapper.getContent().forEach(districtContact -> { + var district = districts.get(districtContact.getDistrictId()); + StudentRegistrationContact coordinator = new StudentRegistrationContact(); + coordinator.setMincode(district.getDistrictNumber() + "00000"); + coordinator.setDistrictNumber(district.getDistrictNumber()); + coordinator.setSchoolNumber("00000"); + coordinator.setPenCoordinatorName(StringUtils.trim(districtContact.getFirstName() + " " + districtContact.getLastName())); + coordinator.setPenCoordinatorEmail(districtContact.getEmail()); + studentRegistrationContacts.add(coordinator); }); + return studentRegistrationContacts; + }catch(Exception e){ + log.error("API call to Institute API failure getting student registration contacts :: {}", e.getMessage()); + throw new MyEdAPIRuntimeException("API call to Institute API failure getting student registration contacts, contact the Ministry for more info."); + } } public Mono>> findStudentsByCriteria(final String criteriaJSON, final Integer pageSize) { diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/service/v1/PenMyEdService.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/service/v1/PenMyEdService.java index e5de63b..2b2c0f6 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/service/v1/PenMyEdService.java +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/service/v1/PenMyEdService.java @@ -1,6 +1,5 @@ package ca.bc.gov.educ.api.pen.myed.service.v1; -import ca.bc.gov.educ.api.pen.myed.exception.MyEdAPIRuntimeException; import ca.bc.gov.educ.api.pen.myed.mappers.v1.MyEdStudentMapper; import ca.bc.gov.educ.api.pen.myed.rest.RestUtils; import ca.bc.gov.educ.api.pen.myed.struct.v1.MyEdStudent; @@ -8,9 +7,8 @@ import ca.bc.gov.educ.api.pen.myed.struct.v1.PenRequestResult; import ca.bc.gov.educ.api.pen.myed.struct.v1.Request; import ca.bc.gov.educ.api.pen.myed.struct.v1.penregbatch.PenRequestBatch; -import ca.bc.gov.educ.api.pen.myed.struct.v1.school.PenCoordinator; +import ca.bc.gov.educ.api.pen.myed.struct.v1.school.StudentRegistrationContact; import ca.bc.gov.educ.api.pen.myed.struct.v1.student.*; -import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import lombok.val; import org.apache.commons.lang3.RegExUtils; @@ -81,8 +79,8 @@ public Mono> postPenRequestToBatchAPI(final Req }); } - public Mono>> getPenCoordinators() { - return this.restUtils.getPenCoordinators(); + public List getStudentRegistrationContacts() { + return this.restUtils.getStudentRegistrationContactList(); } public Mono>> findStudents(final List penList) { @@ -98,12 +96,12 @@ public Mono>> findStudents(final List p searches.add(Search.builder().searchCriteriaList(criteriaList).build()); students.addAll(this.restUtils.findStudentsByCriteria(getJsonStringFromObject(searches), batch.size()).block().getBody().getContent()); } - return Mono.just(ResponseEntity.ok(students.stream().map(MyEdStudentMapper.mapper::toMyEdStudent).collect(Collectors.toList()))); + return Mono.just(ResponseEntity.ok(students.stream().map(MyEdStudentMapper.mapper::toMyEdStudent).toList())); } public static List> getBatches(List collection, int batchSize) { return IntStream.iterate(0, i -> i < collection.size(), i -> i + batchSize) .mapToObj(i -> collection.subList(i, Math.min(i + batchSize, collection.size()))) - .collect(Collectors.toList()); + .toList(); } } diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/district/District.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/district/District.java new file mode 100644 index 0000000..7292e2f --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/district/District.java @@ -0,0 +1,64 @@ +package ca.bc.gov.educ.api.pen.myed.struct.v1.district; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import javax.validation.constraints.*; +import java.io.Serializable; + +/** + * The type Student. + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class District implements Serializable { + /** + * The constant serialVersionUID. + */ + private static final long serialVersionUID = 1L; + + private String districtId; + + @Size(max = 3) + @NotNull(message = "districtNumber can not be null.") + private String districtNumber; + + @Size(max = 10) + @Pattern(regexp = "^$|\\d{10}", message = "Invalid phone number format") + private String faxNumber; + + @Size(max = 10) + @Pattern(regexp = "^$|\\d{10}", message = "Invalid phone number format") + private String phoneNumber; + + @Size(max = 255) + @Email(message = "Email address should be a valid email address") + private String email; + + @Size(max = 255) + private String website; + + @Size(max = 255) + @NotNull(message = "displayName cannot be null") + private String displayName; + + @Size(max = 10) + @NotNull(message = "districtRegionCode cannot be null") + private String districtRegionCode; + + @Size(max = 10) + @NotNull(message = "districtStatusCode cannot be null") + private String districtStatusCode; + + @Size(max = 32) + public String createUser; + + @Size(max = 32) + public String updateUser; + + @Null(message = "createDate should be null.") + public String createDate; + + @Null(message = "updateDate should be null.") + public String updateDate; +} diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/district/DistrictContact.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/district/DistrictContact.java new file mode 100644 index 0000000..5ea89c5 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/district/DistrictContact.java @@ -0,0 +1,67 @@ +package ca.bc.gov.educ.api.pen.myed.struct.v1.district; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import javax.validation.constraints.*; +import java.io.Serializable; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class DistrictContact implements Serializable { + /** + * The constant serialVersionUID. + */ + private static final long serialVersionUID = 1L; + + private String districtContactId; + + private String districtId; + + @Size(max = 10) + @NotNull(message = "districtContactTypeCode cannot be null") + private String districtContactTypeCode; + + @Size(max = 10) + @Pattern(regexp = "^$|\\d{10}", message = "Invalid phone number format") + private String phoneNumber; + + private String jobTitle; + + @Size(max = 10) + private String phoneExtension; + + @Size(max = 10) + @Pattern(regexp = "^$|\\d{10}", message = "Invalid phone number format") + private String alternatePhoneNumber; + + @Size(max = 10) + private String alternatePhoneExtension; + + @Size(max = 255) + @Email(message = "Email address should be a valid email address") + private String email; + + @Size(max = 255) + private String firstName; + + @Size(max = 255) + @NotNull(message = "lastName cannot be null") + private String lastName; + + private String effectiveDate; + + private String expiryDate; + + @Size(max = 32) + public String createUser; + + @Size(max = 32) + public String updateUser; + + @Null(message = "createDate should be null.") + public String createDate; + + @Null(message = "updateDate should be null.") + public String updateDate; +} diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/district/DistrictContactSearchWrapper.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/district/DistrictContactSearchWrapper.java new file mode 100644 index 0000000..b520f13 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/district/DistrictContactSearchWrapper.java @@ -0,0 +1,19 @@ +package ca.bc.gov.educ.api.pen.myed.struct.v1.district; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class DistrictContactSearchWrapper implements Serializable { + private List content; +} diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/School.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/School.java index 661c172..5084b10 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/School.java +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/School.java @@ -6,7 +6,9 @@ import lombok.Data; import lombok.NoArgsConstructor; +import javax.validation.constraints.Email; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; import javax.validation.constraints.Size; import java.io.Serializable; @@ -19,537 +21,71 @@ @NoArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) public class School implements Serializable { - /** - * The constant serialVersionUID. - */ - private static final long serialVersionUID = 1L; - - /** - * The Dist no. - */ - @Size(max = 3) - @NotNull(message = "distNo can not be null.") - private String distNo; - - /** - * The Schl no. - */ - @Size(max = 5) - @NotNull(message = "schlNo can not be null.") - private String schlNo; - /** - * The Sc address line 1. - */ - @Size(max = 40) - private String scAddressLine1; + private static final long serialVersionUID = 1L; - /** - * The Sc address line 2. - */ - @Size(max = 40) - private String scAddressLine2; + @Null(message = "schoolId should be null") + private String schoolId; + @NotNull(message = "districtId can not be null.") + private String districtId; - /** - * The Sc city. - */ - @Size(max = 30) - private String scCity; + @Size(max = 10) + @NotNull(message = "schoolReportingRequirementCode cannot be null") + private String schoolReportingRequirementCode; - /** - * The Sc province code. - */ - @Size(max = 2) - private String scProvinceCode; + private String mincode; - /** - * The Sc country code. - */ - @Size(max = 3) - private String scCountryCode; + private String independentAuthorityId; - /** - * The Sc postal code. - */ - @Size(max = 6) - private String scPostalCode; + @Size(max = 5) + @NotNull(message = "schoolNumber can not be null.") + private String schoolNumber; - /** - * The Sc fax number. - */ @Size(max = 10) - private String scFaxNumber; + private String faxNumber; - /** - * The Sc phone number. - */ @Size(max = 10) - private String scPhoneNumber; + private String phoneNumber; - /** - * The Sc e mail id. - */ - @Size(max = 100) - private String scEMailId; + @Size(max = 255) + @Email(message = "Email address should be a valid email address") + private String email; - /** - * The Facility type code. - */ - @Size(max = 2) - private String facilityTypeCode; + @Size(max = 255) + private String website; - /** - * The School name. - */ - @Size(max = 40) - private String schoolName; + @Size(max = 255) + @NotNull(message = "displayName cannot be null") + private String displayName; - /** - * The School type code. - */ - @Size(max = 2) - private String schoolTypeCode; + @Size(max = 255) + private String displayNameNoSpecialChars; - /** - * The School organization code. - */ - @Size(max = 3) + @Size(max = 10) + @NotNull(message = "schoolOrganizationCode cannot be null") private String schoolOrganizationCode; - /** - * The School category code. - */ - @Size(max = 2) + @Size(max = 10) + @NotNull(message = "schoolCategoryCode cannot be null") private String schoolCategoryCode; - /** - * The Pr given name. - */ - @Size(max = 25) - private String prGivenName; - - /** - * The Pr surname. - */ - @Size(max = 25) - private String prSurname; - - /** - * The Pr middle name. - */ - @Size(max = 25) - private String prMiddleName; - - /** - * The Pr title code. - */ - @Size(max = 2) - private String prTitleCode; - - /** - * The Number of divisions. - */ - private Long numberOfDivisions; - - /** - * The Number of sec fte teachers. - */ - private Long numberOfSecFteTeachers; - - /** - * The Number of elm fte teachers. - */ - private Long numberOfElmFteTeachers; - - /** - * The Ttbl elem instr minutes. - */ - private Long ttblElemInstrMinutes; - - /** - * The School status code. - */ - @Size(max = 1) - private String schoolStatusCode; - - /** - * The Enrol headcount 1523. - */ - private Long enrolHeadcount1523; - - /** - * The Enrol headcount 1701. - */ - private Long enrolHeadcount1701; - - /** - * The Grade 01 ind. - */ - @Size(max = 1) - private String grade01Ind; - - /** - * The Grade 29 ind. - */ - @Size(max = 1) - private String grade29Ind; - - /** - * The Grade 04 ind. - */ - @Size(max = 1) - private String grade04Ind; - - /** - * The Grade 05 ind. - */ - @Size(max = 1) - private String grade05Ind; - - /** - * The Grade 06 ind. - */ - @Size(max = 1) - private String grade06Ind; - - /** - * The Grade 07 ind. - */ - @Size(max = 1) - private String grade07Ind; - - /** - * The Grade 08 ind. - */ - @Size(max = 1) - private String grade08Ind; - - /** - * The Grade 09 ind. - */ - @Size(max = 1) - private String grade09Ind; - - /** - * The Grade 10 ind. - */ - @Size(max = 1) - private String grade10Ind; - - /** - * The Grade 11 ind. - */ - @Size(max = 1) - private String grade11Ind; - - /** - * The Grade 12 ind. - */ - @Size(max = 1) - private String grade12Ind; - - /** - * The Grade 79 ind. - */ - @Size(max = 1) - private String grade79Ind; - - /** - * The Grade 89 ind. - */ - @Size(max = 1) - private String grade89Ind; + @Size(max = 10) + @NotNull(message = "facilityTypeCode cannot be null") + private String facilityTypeCode; - /** - * The Opened date. - */ - @Size(max = 8) private String openedDate; - /** - * The Closed date. - */ - @Size(max = 8) private String closedDate; - /** - * The Auth number. - */ - @Size(max = 3) - private String authNumber; - - /** - * The Create date. - */ - private Long createDate; - - /** - * The Create time. - */ - private Long createTime; - - /** - * The Create username. - */ - @Size(max = 12) - private String createUsername; - - /** - * The Edit date. - */ - private Long editDate; - - /** - * The Edit time. - */ - private Long editTime; - - /** - * The Edit username. - */ - @Size(max = 12) - private String editUsername; - - /** - * The Elem teachers hc. - */ - private Long elemTeachersHc; - - /** - * The Sec teachers hc. - */ - private Long secTeachersHc; - - /** - * The Grade kh ind. - */ - @Size(max = 1) - private String gradeKhInd; - - /** - * The Grade kf ind. - */ - @Size(max = 1) - private String gradeKfInd; - - /** - * The Grade 02 ind. - */ - @Size(max = 1) - private String grade02Ind; - - /** - * The Grade 03 ind. - */ - @Size(max = 1) - private String grade03Ind; - - /** - * The Grade eu ind. - */ - @Size(max = 1) - private String gradeEuInd; - - /** - * The Grade su ind. - */ - @Size(max = 1) - private String gradeSuInd; - - /** - * The Grade hs ind. - */ - @Size(max = 1) - private String gradeHsInd; - - /** - * The Conted fund flag. - */ - @Size(max = 4) - private String contedFundFlag; - - /** - * The Elem fte classroom. - */ - private Long elemFteClassroom; - - /** - * The Elem fte support. - */ - private Long elemFteSupport; - - /** - * The Elem fte admin. - */ - private Long elemFteAdmin; - - /** - * The Sec fte classroom. - */ - private Long secFteClassroom; - - /** - * The Sec fte support. - */ - private Long secFteSupport; - - /** - * The Sec fte admin. - */ - private Long secFteAdmin; - - /** - * The Phys address line 1. - */ - @Size(max = 40) - private String physAddressLine1; - - /** - * The Phys address line 2. - */ - @Size(max = 40) - private String physAddressLine2; - - /** - * The Phys city. - */ - @Size(max = 30) - private String physCity; - - /** - * The Phys province code. - */ - @Size(max = 2) - private String physProvinceCode; - - /** - * The Phys country code. - */ - @Size(max = 3) - private String physCountryCode; - - /** - * The Phys postal code. - */ - @Size(max = 6) - private String physPostalCode; - - /** - * The Educ method class cnt. - */ - private Long educMethodClassCnt; - - /** - * The Educ method del cnt. - */ - private Long educMethodDelCnt; - - /** - * The Educ method both cnt. - */ - private Long educMethodBothCnt; - - /** - * The New distno. - */ - @Size(max = 3) - private String newDistno; - - /** - * The New schlno. - */ - @Size(max = 5) - private String newSchlno; - - /** - * The Date opened. - */ - private String dateOpened; - - /** - * The Date closed. - */ - private String dateClosed; - - /** - * The Asset number. - */ - private Long assetNumber; - - /** - * The Asset assigned by. - */ - @Size(max = 12) - private String assetAssignedBy; - - /** - * The Asset assigned date. - */ - private String assetAssignedDate; - - /** - * The Asset changed by. - */ - @Size(max = 12) - private String assetChangedBy; - - /** - * The Asset changed date. - */ - private String assetChangedDate; - - /** - * The Restrict funding. - */ - @Size(max = 1) - private String restrictFunding; - - /** - * The Grade ga ind. - */ - @Size(max = 1) - private String gradeGaInd; - - /** - * The Nlc early learning flag. - */ - @Size(max = 1) - private String nlcEarlyLearningFlag; - - /** - * The Nlc after school program flag. - */ - @Size(max = 1) - private String nlcAfterSchoolProgramFlag; - - /** - * The Nlc continuing ed flag. - */ - @Size(max = 1) - private String nlcContinuingEdFlag; - - /** - * The Nlc seniors flag. - */ - @Size(max = 1) - private String nlcSeniorsFlag; - - /** - * The Nlc sport and rec flag. - */ - @Size(max = 1) - private String nlcSportAndRecFlag; + @Size(max = 32) + public String createUser; - /** - * The Nlc community use flag. - */ - @Size(max = 1) - private String nlcCommunityUseFlag; + @Size(max = 32) + public String updateUser; - /** - * The Nlc integrated services flag. - */ - @Size(max = 1) - private String nlcIntegratedServicesFlag; + @Null(message = "createDate should be null.") + public String createDate; + @Null(message = "updateDate should be null.") + public String updateDate; } diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/SchoolContact.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/SchoolContact.java new file mode 100644 index 0000000..54657d7 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/SchoolContact.java @@ -0,0 +1,68 @@ +package ca.bc.gov.educ.api.pen.myed.struct.v1.school; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import javax.validation.constraints.*; +import java.io.Serializable; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class SchoolContact implements Serializable { + /** + * The constant serialVersionUID. + */ + private static final long serialVersionUID = 1L; + + private String schoolContactId; + + private String schoolId; + + @Size(max = 10) + @NotNull(message = "schoolContactTypeCode cannot be null") + private String schoolContactTypeCode; + + @Size(max = 10) + @Pattern(regexp = "^$|\\d{10}", message = "Invalid phone number format") + private String phoneNumber; + + private String jobTitle; + + @Size(max = 10) + private String phoneExtension; + + @Size(max = 10) + @Pattern(regexp = "^$|\\d{10}", message = "Invalid phone number format") + private String alternatePhoneNumber; + + @Size(max = 10) + private String alternatePhoneExtension; + + @Size(max = 255) + @Email(message = "Email address should be a valid email address") + private String email; + + @Size(max = 255) + private String firstName; + + @Size(max = 255) + @NotNull(message = "lastName cannot be null") + private String lastName; + + private String effectiveDate; + + private String expiryDate; + + @Size(max = 32) + public String createUser; + + @Size(max = 32) + public String updateUser; + + @Null(message = "createDate should be null.") + public String createDate; + + @Null(message = "updateDate should be null.") + public String updateDate; + +} diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/SchoolContactSearchWrapper.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/SchoolContactSearchWrapper.java new file mode 100644 index 0000000..c316096 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/SchoolContactSearchWrapper.java @@ -0,0 +1,19 @@ +package ca.bc.gov.educ.api.pen.myed.struct.v1.school; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class SchoolContactSearchWrapper implements Serializable { + private List content; +} diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/PenCoordinator.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/StudentRegistrationContact.java similarity index 94% rename from api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/PenCoordinator.java rename to api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/StudentRegistrationContact.java index 0260175..db63217 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/PenCoordinator.java +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/struct/v1/school/StudentRegistrationContact.java @@ -14,7 +14,7 @@ @NoArgsConstructor @Builder @JsonIgnoreProperties(ignoreUnknown = true) -public class PenCoordinator { +public class StudentRegistrationContact { /** * The District number. */ diff --git a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/validator/PenMyEdPayloadValidator.java b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/validator/PenMyEdPayloadValidator.java index 1a5ac1d..3cfafe0 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/pen/myed/validator/PenMyEdPayloadValidator.java +++ b/api/src/main/java/ca/bc/gov/educ/api/pen/myed/validator/PenMyEdPayloadValidator.java @@ -99,12 +99,12 @@ public List validatePenRequestPayload(final Request request) { * @return the school */ private School validateSchoolInfo(String mincode, List apiValidationErrors) { - val school = this.restUtils.getSchoolMap().get(mincode); + val school = this.restUtils.getSchoolMincodeMap().get(mincode); if (school == null) { apiValidationErrors.add(createFieldError(MINCODE, mincode, "Invalid mincode.")); } else { - final String openedDate = school.getDateOpened(); - final String closedDate = school.getDateClosed(); + final String openedDate = school.getOpenedDate(); + final String closedDate = school.getClosedDate(); try { if (openedDate == null || LocalDate.parse(openedDate, DateTimeFormatter.ISO_LOCAL_DATE_TIME).isAfter(LocalDate.now()) || (closedDate != null && LocalDate.parse(closedDate, DateTimeFormatter.ISO_LOCAL_DATE_TIME).isBefore(LocalDate.now()))) { apiValidationErrors.add(createFieldError(MINCODE, mincode, "School is closed.")); diff --git a/api/src/main/resources/application.properties b/api/src/main/resources/application.properties index ec84c09..cd25fa5 100644 --- a/api/src/main/resources/application.properties +++ b/api/src/main/resources/application.properties @@ -19,7 +19,7 @@ logging.pattern.console=%d{yyyy-MM-dd hh:mm:ss.SSS} | [${HOSTNAME}] | %clr(%5p) client.id=${CLIENT_ID} client.secret=${CLIENT_SECRET} url.token=${TOKEN_URL} -url.api.school=${SCHOOL_API_URL} +url.api.institute=${INSTITUTE_API_URL} url.api.pen.reg.batch=${PEN_REG_BATCH_API_URL} url.api.pen.services=${PEN_SERVICES_API_URL} initialization.background.enabled=true diff --git a/tools/config/update-configmap.sh b/tools/config/update-configmap.sh index e4ca61a..a73507d 100644 --- a/tools/config/update-configmap.sh +++ b/tools/config/update-configmap.sh @@ -39,7 +39,7 @@ echo Creating client pen-myed-api-service curl -sX POST "https://$SOAM_KC/auth/admin/realms/$SOAM_KC_REALM_ID/clients" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TKN" \ - -d "{\"clientId\" : \"pen-myed-api-service\",\"surrogateAuthRequired\" : false,\"enabled\" : true,\"clientAuthenticatorType\" : \"client-secret\",\"redirectUris\" : [ ],\"webOrigins\" : [ ],\"notBefore\" : 0,\"bearerOnly\" : false,\"consentRequired\" : false,\"standardFlowEnabled\" : false,\"implicitFlowEnabled\" : false,\"directAccessGrantsEnabled\" : false,\"serviceAccountsEnabled\" : true,\"publicClient\" : false,\"frontchannelLogout\" : false,\"protocol\" : \"openid-connect\",\"attributes\" : {\"saml.assertion.signature\" : \"false\",\"saml.multivalued.roles\" : \"false\",\"saml.force.post.binding\" : \"false\",\"saml.encrypt\" : \"false\",\"saml.server.signature\" : \"false\",\"saml.server.signature.keyinfo.ext\" : \"false\",\"exclude.session.state.from.auth.response\" : \"false\",\"saml_force_name_id_format\" : \"false\",\"saml.client.signature\" : \"false\",\"tls.client.certificate.bound.access.tokens\" : \"false\",\"saml.authnstatement\" : \"false\",\"display.on.consent.screen\" : \"false\",\"saml.onetimeuse.condition\" : \"false\"},\"authenticationFlowBindingOverrides\" : { },\"fullScopeAllowed\" : true,\"nodeReRegistrationTimeout\" : -1,\"protocolMappers\" : [ {\"name\" : \"Client ID\",\"protocol\" : \"openid-connect\",\"protocolMapper\" : \"oidc-usersessionmodel-note-mapper\",\"consentRequired\" : false,\"config\" : {\"user.session.note\" : \"clientId\",\"id.token.claim\" : \"true\",\"access.token.claim\" : \"true\",\"claim.name\" : \"clientId\",\"jsonType.label\" : \"String\"}}, {\"name\" : \"Client Host\",\"protocol\" : \"openid-connect\",\"protocolMapper\" : \"oidc-usersessionmodel-note-mapper\",\"consentRequired\" : false,\"config\" : {\"user.session.note\" : \"clientHost\",\"id.token.claim\" : \"true\",\"access.token.claim\" : \"true\",\"claim.name\" : \"clientHost\",\"jsonType.label\" : \"String\"}}, {\"name\" : \"Client IP Address\",\"protocol\" : \"openid-connect\",\"protocolMapper\" : \"oidc-usersessionmodel-note-mapper\",\"consentRequired\" : false,\"config\" : {\"user.session.note\" : \"clientAddress\",\"id.token.claim\" : \"true\",\"access.token.claim\" : \"true\",\"claim.name\" : \"clientAddress\",\"jsonType.label\" : \"String\"}} ],\"defaultClientScopes\" : [ \"web-origins\",\"WRITE_PEN_REQUEST_BATCH\",\"READ_PEN_REQUEST_BATCH\",\"READ_SCHOOL\", \"READ_PEN_COORDINATOR\",\"VALIDATE_STUDENT_DEMOGRAPHICS\", \"READ_PEN_MATCH\",\"WRITE_STUDENT\",\"READ_STUDENT\",\"role_list\", \"profile\", \"roles\", \"email\"],\"optionalClientScopes\" : [ \"address\", \"phone\", \"offline_access\" ],\"access\" : {\"view\" : true,\"configure\" : true,\"manage\" : true}}" + -d "{\"clientId\" : \"pen-myed-api-service\",\"surrogateAuthRequired\" : false,\"enabled\" : true,\"clientAuthenticatorType\" : \"client-secret\",\"redirectUris\" : [ ],\"webOrigins\" : [ ],\"notBefore\" : 0,\"bearerOnly\" : false,\"consentRequired\" : false,\"standardFlowEnabled\" : false,\"implicitFlowEnabled\" : false,\"directAccessGrantsEnabled\" : false,\"serviceAccountsEnabled\" : true,\"publicClient\" : false,\"frontchannelLogout\" : false,\"protocol\" : \"openid-connect\",\"attributes\" : {\"saml.assertion.signature\" : \"false\",\"saml.multivalued.roles\" : \"false\",\"saml.force.post.binding\" : \"false\",\"saml.encrypt\" : \"false\",\"saml.server.signature\" : \"false\",\"saml.server.signature.keyinfo.ext\" : \"false\",\"exclude.session.state.from.auth.response\" : \"false\",\"saml_force_name_id_format\" : \"false\",\"saml.client.signature\" : \"false\",\"tls.client.certificate.bound.access.tokens\" : \"false\",\"saml.authnstatement\" : \"false\",\"display.on.consent.screen\" : \"false\",\"saml.onetimeuse.condition\" : \"false\"},\"authenticationFlowBindingOverrides\" : { },\"fullScopeAllowed\" : true,\"nodeReRegistrationTimeout\" : -1,\"protocolMappers\" : [ {\"name\" : \"Client ID\",\"protocol\" : \"openid-connect\",\"protocolMapper\" : \"oidc-usersessionmodel-note-mapper\",\"consentRequired\" : false,\"config\" : {\"user.session.note\" : \"clientId\",\"id.token.claim\" : \"true\",\"access.token.claim\" : \"true\",\"claim.name\" : \"clientId\",\"jsonType.label\" : \"String\"}}, {\"name\" : \"Client Host\",\"protocol\" : \"openid-connect\",\"protocolMapper\" : \"oidc-usersessionmodel-note-mapper\",\"consentRequired\" : false,\"config\" : {\"user.session.note\" : \"clientHost\",\"id.token.claim\" : \"true\",\"access.token.claim\" : \"true\",\"claim.name\" : \"clientHost\",\"jsonType.label\" : \"String\"}}, {\"name\" : \"Client IP Address\",\"protocol\" : \"openid-connect\",\"protocolMapper\" : \"oidc-usersessionmodel-note-mapper\",\"consentRequired\" : false,\"config\" : {\"user.session.note\" : \"clientAddress\",\"id.token.claim\" : \"true\",\"access.token.claim\" : \"true\",\"claim.name\" : \"clientAddress\",\"jsonType.label\" : \"String\"}} ],\"defaultClientScopes\" : [ \"web-origins\",\"WRITE_PEN_REQUEST_BATCH\",\"READ_PEN_REQUEST_BATCH\",\"READ_SCHOOL\",\"READ_SCHOOL_CONTACT\",\"READ_DISTRICT\",\"READ_DISTRICT_CONTACT\", \"READ_PEN_COORDINATOR\",\"VALIDATE_STUDENT_DEMOGRAPHICS\", \"READ_PEN_MATCH\",\"WRITE_STUDENT\",\"READ_STUDENT\",\"role_list\", \"profile\", \"roles\", \"email\"],\"optionalClientScopes\" : [ \"address\", \"phone\", \"offline_access\" ],\"access\" : {\"view\" : true,\"configure\" : true,\"manage\" : true}}" echo echo Retrieving client ID for pen-myed-api-service @@ -132,7 +132,7 @@ FLB_CONFIG="[SERVICE] " echo Creating config map "$APP_NAME"-config-map -oc create -n "$CLIENT_NAMESPACE"-"$envValue" configmap "$APP_NAME"-config-map --from-literal=TZ=$TZVALUE --from-literal=STUDENT_API_URL="http://student-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student" --from-literal=SCHOOL_API_URL="http://school-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/schools" --from-literal=PEN_REG_BATCH_API_URL="http://pen-reg-batch-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-request-batch" --from-literal=PEN_MATCH_API_URL="http://pen-match-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-match" --from-literal=PEN_SERVICES_API_URL="http://pen-services-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-services" --from-literal=TOKEN_URL="https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID/protocol/openid-connect/token" --from-literal=SPRING_SECURITY_LOG_LEVEL=INFO --from-literal=SPRING_WEB_LOG_LEVEL=INFO --from-literal=APP_LOG_LEVEL=INFO --from-literal=SPRING_BOOT_AUTOCONFIG_LOG_LEVEL=INFO --from-literal=SPRING_SHOW_REQUEST_DETAILS=false --from-literal=NATS_URL="$NATS_URL" --from-literal=TOKEN_ISSUER_URL="https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID" --from-literal=CLIENT_ID="pen-myed-api-service" --from-literal=CLIENT_SECRET="$PME_APIServiceClientSecret" --dry-run -o yaml | oc apply -f - +oc create -n "$CLIENT_NAMESPACE"-"$envValue" configmap "$APP_NAME"-config-map --from-literal=TZ=$TZVALUE --from-literal=STUDENT_API_URL="http://student-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/student" --from-literal=SCHOOL_API_URL="http://school-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/schools" --from-literal=PEN_REG_BATCH_API_URL="http://pen-reg-batch-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-request-batch" --from-literal=PEN_MATCH_API_URL="http://pen-match-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-match" --from-literal=INSTITUTE_API_URL="http://institute-api-master.$COMMON_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/institute" --from-literal=PEN_SERVICES_API_URL="http://pen-services-api-master.$PEN_NAMESPACE-$envValue.svc.cluster.local:8080/api/v1/pen-services" --from-literal=TOKEN_URL="https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID/protocol/openid-connect/token" --from-literal=SPRING_SECURITY_LOG_LEVEL=INFO --from-literal=SPRING_WEB_LOG_LEVEL=INFO --from-literal=APP_LOG_LEVEL=INFO --from-literal=SPRING_BOOT_AUTOCONFIG_LOG_LEVEL=INFO --from-literal=SPRING_SHOW_REQUEST_DETAILS=false --from-literal=NATS_URL="$NATS_URL" --from-literal=TOKEN_ISSUER_URL="https://$SOAM_KC/auth/realms/$SOAM_KC_REALM_ID" --from-literal=CLIENT_ID="pen-myed-api-service" --from-literal=CLIENT_SECRET="$PME_APIServiceClientSecret" --dry-run -o yaml | oc apply -f - echo echo Setting environment variables for "$APP_NAME-$SOAM_KC_REALM_ID" application diff --git a/tools/openshift/api.dc.yaml b/tools/openshift/api.dc.yaml index 4587dbd..b288a28 100644 --- a/tools/openshift/api.dc.yaml +++ b/tools/openshift/api.dc.yaml @@ -135,7 +135,7 @@ objects: selector: app: "${APP_NAME}-${BRANCH}" deploymentconfig: "${APP_NAME}-${BRANCH}" - - apiVersion: autoscaling/v2beta1 + - apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: "${APP_NAME}-${BRANCH}-cpu-autoscaler" @@ -151,7 +151,9 @@ objects: - type: Resource resource: name: cpu - targetAverageUtilization: 200 + target: + type: Utilization + averageUtilization: 200 parameters: - name: REPO_NAME description: Application repository name