Skip to content

Commit

Permalink
Merge pull request #516 from bcgov/develop/alex-GRAD2-2377
Browse files Browse the repository at this point in the history
GRAD2-2377
  • Loading branch information
kamal-mohammed authored Apr 16, 2024
2 parents 8cb5605 + eecb0d4 commit 0e4cb6f
Show file tree
Hide file tree
Showing 13 changed files with 267 additions and 47 deletions.
5 changes: 5 additions & 0 deletions api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@
<artifactId>pdfbox</artifactId>
<version>2.0.26</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20220320</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package ca.bc.gov.educ.api.graduation.config;

import ca.bc.gov.educ.api.graduation.model.dto.ResponseObjCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import ca.bc.gov.educ.api.graduation.util.MessageHelper;

@Configuration
@PropertySource("classpath:messages.properties")
public class GradCommonConfig implements WebMvcConfigurer {
Expand All @@ -26,4 +25,8 @@ public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(requestInterceptor).addPathPatterns("/**");
}

@Bean
public ResponseObjCache createResponseObjCache() {
return new ResponseObjCache(60);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package ca.bc.gov.educ.api.graduation.model.dto;

import org.json.JSONObject;

import java.util.Base64;

public class ResponseObjCache {

private long tokenExpiry = 0;
private ResponseObj responseObj;

// tokenExpiry-[seconds] provides a slight offset, if token WILL expire in
// [seconds], obtain a new one
private int offset;

public ResponseObjCache(int offset) {
this.offset = offset;
}

public ResponseObj getResponseObj() {
return responseObj;
}

public void setResponseObj(ResponseObj responseObj) {
this.setTokenExpiry(responseObj);
this.responseObj = responseObj;
}

public boolean isExpired(){
// tokenExpiry-[seconds] provides a slight offset, if token WILL expire in
// 10 seconds, obtain a new one
return (responseObj == null) || (tokenExpiry-offset) < (System.currentTimeMillis() / 1000);
}

private void setTokenExpiry(ResponseObj responseObj){
String[] parts = responseObj.getAccess_token().split("\\.");
JSONObject payload = new JSONObject(new String(Base64.getUrlDecoder().decode(parts[1])));
this.tokenExpiry = payload.getLong("exp");
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ public byte[] getSchoolReports(List<String> uniqueSchoolList, String type, Strin

try {
List<GraduationStudentRecord> stdList = gradStatusService.getStudentListByMinCode(usl, accessToken);
SchoolTrax schoolDetails = schoolService.getSchoolDetails(usl, accessToken, new ExceptionMessage());
SchoolTrax schoolDetails = schoolService.getTraxSchoolDetails(usl, accessToken, new ExceptionMessage());
if (schoolDetails != null) {
School schoolObj = new School();
schoolObj.setMincode(schoolDetails.getMinCode());
Expand Down Expand Up @@ -266,7 +266,7 @@ public Integer createAndStoreSchoolReports(List<String> uniqueSchoolList, String
String listOfStudents = jsonTransformer.marshall(stdList);
logger.debug("*** Student List of {} Acquired {}", totalStudents, listOfStudents);
}
SchoolTrax schoolDetails = schoolService.getSchoolDetails(usl, accessToken, exception);
SchoolTrax schoolDetails = schoolService.getTraxSchoolDetails(usl, accessToken, exception);
if (schoolDetails != null) {
logger.debug("*** School Details Acquired {}", schoolDetails.getSchoolName());
if (stdList != null && !stdList.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public ReportData prepareTranscriptData(ca.bc.gov.educ.api.graduation.model.dto.
SchoolTrax traxSchool = null;
if(schoolAtGrad != null) {
String mincode = schoolAtGrad.getMincode();
traxSchool = schoolService.getSchoolDetails(mincode, accessToken, exception);
traxSchool = schoolService.getTraxSchoolDetails(mincode, accessToken, exception);
}
GraduationStatus graduationStatus = getGraduationStatus(graduationDataStatus, schoolAtGrad, schoolOfRecord);
GraduationData graduationData = getGraduationData(graduationDataStatus, gradResponse, accessToken);
Expand Down Expand Up @@ -769,7 +769,7 @@ private Student getStudentData(GradSearchStudent gradStudent, GraduationStudentR

private School getSchoolAtGradData(ca.bc.gov.educ.api.graduation.model.dto.GraduationData graduationDataStatus, String accessToken, ExceptionMessage exception) {
if (graduationDataStatus.getGradStatus() != null && !StringUtils.isBlank(graduationDataStatus.getGradStatus().getSchoolAtGrad())) {
SchoolTrax schoolDetails = schoolService.getSchoolDetails(graduationDataStatus.getGradStatus().getSchoolAtGrad(), accessToken, exception);
SchoolTrax schoolDetails = schoolService.getTraxSchoolDetails(graduationDataStatus.getGradStatus().getSchoolAtGrad(), accessToken, exception);
if (schoolDetails != null) {
return getSchoolData(schoolDetails);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ca.bc.gov.educ.api.graduation.model.dto.ReportGradStudentData;
import ca.bc.gov.educ.api.graduation.model.dto.SchoolReports;
import ca.bc.gov.educ.api.graduation.model.dto.SchoolTrax;
import ca.bc.gov.educ.api.graduation.model.report.*;
import ca.bc.gov.educ.api.graduation.util.*;
import lombok.SneakyThrows;
Expand Down Expand Up @@ -151,9 +152,15 @@ public Integer createAndStoreSchoolDistrictYearEndReports(String accessToken, St
logger.debug("***** {} Students Retrieved *****", reportGradStudentDataList.size());
if(schools != null && !schools.isEmpty()) {
boolean isDistrictSchool = schools.get(0).length() == 3;
if(isDistrictSchool) {
reportGradStudentDataList.removeIf(st -> ((StringUtils.isBlank(st.getMincodeAtGrad()) || StringUtils.equals(st.getMincode(), st.getMincodeAtGrad())) && !schools.contains(StringUtils.substring(st.getMincode(), 0, 3))));
reportGradStudentDataList.removeIf(st -> ((StringUtils.isNotBlank(st.getMincodeAtGrad()) && !StringUtils.equals(st.getMincode(), st.getMincodeAtGrad())) && !schools.contains(StringUtils.substring(st.getMincodeAtGrad(), 0, 3))));
}
boolean isSchoolSchool = schools.get(0).length() > 3;
reportGradStudentDataList.removeIf(st->isDistrictSchool && !schools.contains(StringUtils.substring(st.getMincode(), 0, 3)));
reportGradStudentDataList.removeIf(st->isSchoolSchool && !schools.contains(st.getMincode()));
if(isSchoolSchool) {
reportGradStudentDataList.removeIf(st -> ((StringUtils.isBlank(st.getMincodeAtGrad()) || StringUtils.equals(st.getMincode(), st.getMincodeAtGrad())) && !schools.contains(StringUtils.trimToEmpty(st.getMincode()))));
reportGradStudentDataList.removeIf(st -> ((StringUtils.isNotBlank(st.getMincodeAtGrad()) && !StringUtils.equals(st.getMincode(), st.getMincodeAtGrad())) && !schools.contains(StringUtils.trimToEmpty(st.getMincodeAtGrad()))));
}
}
return createAndStoreReports(reportGradStudentDataList, accessToken, slrt, drt, srt, null);
}
Expand Down Expand Up @@ -443,7 +450,8 @@ private String getReportOrgCode(String mincode) {

private School populateDistrictObjectByReportGradStudentData(Map<School, List<School>> districtSchoolsMap, ReportGradStudentData reportGradStudentData) {
//district data, not school
String distcode = StringUtils.substring(reportGradStudentData.getMincode(), 0, 3);
String mincode = StringUtils.isBlank(reportGradStudentData.getMincodeAtGrad()) ? reportGradStudentData.getMincode() : reportGradStudentData.getMincodeAtGrad();
String distcode = StringUtils.substring(mincode, 0, 3);
boolean addNewDistrict = true;
School district = null;
for (var entry : districtSchoolsMap.entrySet()) {
Expand All @@ -464,25 +472,27 @@ private School populateDistrictObjectByReportGradStudentData(Map<School, List<Sc
}

private School populateSchoolObjectByReportGradStudentData(ReportGradStudentData reportGradStudentData) {
String mincode = StringUtils.isBlank(reportGradStudentData.getMincodeAtGrad()) ? reportGradStudentData.getMincode() : reportGradStudentData.getMincodeAtGrad();
SchoolTrax traxSchool = schoolService.getTraxSchoolDetails(mincode);
School school = new School();
school.setDistno(StringUtils.substring(reportGradStudentData.getMincode(), 0, 3));
school.setMincode(reportGradStudentData.getMincode());
school.setName(reportGradStudentData.getSchoolName());
school.setDistno(StringUtils.substring(traxSchool.getMinCode(), 0, 3));
school.setMincode(traxSchool.getMinCode());
school.setName(traxSchool.getSchoolName());
school.setTypeBanner("Principal");
Address address = new Address();
address.setStreetLine1(reportGradStudentData.getSchoolAddress1());
address.setStreetLine2(reportGradStudentData.getSchoolAddress2());
address.setCity(reportGradStudentData.getSchoolCity());
address.setRegion(reportGradStudentData.getSchoolProvince());
address.setCountry(reportGradStudentData.getSchoolCountry());
address.setCode(reportGradStudentData.getSchoolPostal());
address.setStreetLine1(traxSchool.getAddress1());
address.setStreetLine2(traxSchool.getAddress2());
address.setCity(traxSchool.getCity());
address.setRegion(traxSchool.getProvCode());
address.setCountry(traxSchool.getCountryName());
address.setCode(traxSchool.getPostal());
school.setAddress(address);
school.setStudents(new ArrayList<>());
return school;
}

private School populateSchoolObjectByReportGradStudentData(Map<String, School> schoolMap, ReportGradStudentData reportGradStudentData) {
String mincode = reportGradStudentData.getMincode();
String mincode = StringUtils.isBlank(reportGradStudentData.getMincodeAtGrad()) ? reportGradStudentData.getMincode() : reportGradStudentData.getMincodeAtGrad();
School school = schoolMap.get(mincode);
if (school == null) {
school = populateSchoolObjectByReportGradStudentData(reportGradStudentData);
Expand Down Expand Up @@ -570,7 +580,8 @@ private Student populateStudentObjectByReportGradStudentData(ReportGradStudentDa

GraduationStatus gradStatus = new GraduationStatus();
gradStatus.setProgramCompletionDate(reportGradStudentData.getProgramCompletionDate());
gradStatus.setSchoolAtGrad(reportGradStudentData.getMincode());
gradStatus.setSchoolOfRecord(StringUtils.isBlank(reportGradStudentData.getMincodeAtGrad()) ? reportGradStudentData.getMincode() : reportGradStudentData.getMincodeAtGrad());
gradStatus.setSchoolAtGrad(reportGradStudentData.getMincodeAtGrad());
gradStatus.setProgramName(reportGradStudentData.getProgramCode());
gradStatus.setCertificates(reportGradStudentData.getCertificateTypeCode());
student.setGraduationStatus(gradStatus);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,34 @@
import ca.bc.gov.educ.api.graduation.model.dto.ExceptionMessage;
import ca.bc.gov.educ.api.graduation.model.dto.SchoolTrax;
import ca.bc.gov.educ.api.graduation.util.EducGraduationApiConstants;
import ca.bc.gov.educ.api.graduation.util.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SchoolService {
EducGraduationApiConstants educGraduationApiConstants;
RESTService restService;
TokenUtils tokenUtils;

@Autowired
public SchoolService(EducGraduationApiConstants educGraduationApiConstants, RESTService restService) {
public SchoolService(EducGraduationApiConstants educGraduationApiConstants, RESTService restService, TokenUtils tokenUtils) {
this.educGraduationApiConstants = educGraduationApiConstants;
this.restService = restService;
this.tokenUtils = tokenUtils;
}

public SchoolTrax getSchoolDetails(String mincode, String accessToken, ExceptionMessage message) {
public SchoolTrax getTraxSchoolDetails(String mincode, String accessToken, ExceptionMessage message) {
return this.restService.get(String.format(educGraduationApiConstants.getSchoolDetails(),mincode, accessToken),
SchoolTrax.class,
accessToken);
}

public SchoolTrax getTraxSchoolDetails(String mincode) {
String accessToken = tokenUtils.getAccessToken();
return this.restService.get(String.format(educGraduationApiConstants.getSchoolDetails(),mincode, accessToken),
SchoolTrax.class,
accessToken);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ca.bc.gov.educ.api.graduation.model.dto.ProcessorData;
import ca.bc.gov.educ.api.graduation.model.dto.ResponseObj;
import ca.bc.gov.educ.api.graduation.model.dto.ResponseObjCache;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -16,25 +17,27 @@

@Component
public class TokenUtils {
private static Logger logger = LoggerFactory.getLogger(TokenUtils.class);
private static final Logger LOGGER = LoggerFactory.getLogger(TokenUtils.class);

private ResponseObjCache responseObjCache;
private final EducGraduationApiConstants constants;
private final WebClient webClient;

@Autowired
public TokenUtils(final EducGraduationApiConstants constants, final WebClient webClient) {
public TokenUtils(final EducGraduationApiConstants constants, final WebClient webClient, final ResponseObjCache responseObjCache) {
this.constants = constants;
this.webClient = webClient;
this.responseObjCache = responseObjCache;
}

public Pair<String, Long> checkAndGetAccessToken(Pair<String, Long> req) {
long currentTime = System.currentTimeMillis();
long startTime = req.getRight();
long diff = (currentTime - startTime)/1000;

logger.debug("=========> Check Duration: {} sec <===========", diff);
LOGGER.debug("=========> Check Duration: {} sec <===========", diff);
if (diff > 120) { // if the previous step took more than 2 minutes, treat it as a long process, and get the new access token
logger.debug("=========> Getting the new Access Token after 2 minutes <===========");
LOGGER.debug("=========> Getting the new Access Token after 2 minutes <===========");
ResponseObj responseObj = getTokenResponseObject();
if (responseObj != null) {
return Pair.of(responseObj.getAccess_token(), currentTime);
Expand All @@ -52,13 +55,16 @@ public Pair<String, Long> getAccessToken(String accessToken) {
return Pair.of(accessToken, startTime);
}

public String getAccessToken() {
return this.getTokenResponseObject().getAccess_token();
}

public void checkAndSetAccessToken(ProcessorData processorData) {
long currentTime = System.currentTimeMillis();
long diff = (currentTime - processorData.getStartTime())/1000;

logger.debug("=========> Check Duration: {} sec <===========", diff);
LOGGER.debug("=========> Check Duration: {} sec <===========", diff);
if (diff > 120) { // if the previous step took more than 2 minutes, treat it as a long process, and get the new access token
logger.debug("=========> Getting the new Access Token after 2 minutes <===========");
LOGGER.debug("=========> Getting the new Access Token after 2 minutes <===========");
ResponseObj responseObj = getTokenResponseObject();
if (responseObj != null) {
processorData.setAccessToken(responseObj.getAccess_token());
Expand All @@ -76,7 +82,15 @@ public void setAccessToken(ProcessorData processorData) {
}
}

private ResponseObj getTokenResponseObject() {
public ResponseObj getTokenResponseObject() {
if(responseObjCache.isExpired()){
responseObjCache.setResponseObj(getResponseObj());
}
return responseObjCache.getResponseObj();
}

public ResponseObj getResponseObj() {
LOGGER.debug("Fetch token");
HttpHeaders httpHeadersKC = EducGraduationApiUtils.getHeaders(
constants.getUserName(), constants.getPassword());
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2028,7 +2028,7 @@ public void testCreateAndStoreSchoolReports() {
when(this.tokenUtils.checkAndGetAccessToken(any())).thenReturn(Pair.of("accessToken", System.currentTimeMillis()));

Mockito.when(gradStatusService.getStudentListByMinCode(mincode, "accessToken")).thenReturn(sList);
Mockito.when(schoolService.getSchoolDetails(mincode, "accessToken", exception)).thenReturn(sTrax);
Mockito.when(schoolService.getTraxSchoolDetails(mincode, "accessToken", exception)).thenReturn(sTrax);
int numberOfRecord = graduationService.createAndStoreSchoolReports(uniqueList,"REGALG","accessToken");
assertEquals(2,numberOfRecord);
}
Expand Down Expand Up @@ -2192,7 +2192,7 @@ public void testGetSchoolReports() {
when(this.restService.post(any(String.class), any(), any(), any())).thenReturn(bytesSAR3);

when(gradStatusService.getStudentListByMinCode(mincode, "accessToken")).thenReturn(sList);
when(schoolService.getSchoolDetails(mincode, "accessToken", exception)).thenReturn(sTrax);
when(schoolService.getTraxSchoolDetails(mincode, "accessToken", exception)).thenReturn(sTrax);
when(this.tokenUtils.getAccessToken(any())).thenReturn(Pair.of("accessToken", System.currentTimeMillis()));

byte[] result = graduationService.getSchoolReports(uniqueList,"GRADREG","accessToken");
Expand Down Expand Up @@ -2266,7 +2266,7 @@ public void testCreateAndStoreSchoolReports_TVR() {
when(this.tokenUtils.getAccessToken(any())).thenReturn(Pair.of("accessToken", System.currentTimeMillis()));

Mockito.when(gradStatusService.getStudentListByMinCode(mincode, "accessToken")).thenReturn(sList);
Mockito.when(schoolService.getSchoolDetails(mincode, "accessToken", exception)).thenReturn(sTrax);
Mockito.when(schoolService.getTraxSchoolDetails(mincode, "accessToken", exception)).thenReturn(sTrax);
int numberOfRecord = graduationService.createAndStoreSchoolReports(uniqueList,"TVRRUN","accessToken");
assertEquals(1,numberOfRecord);
}
Expand Down
Loading

0 comments on commit 0e4cb6f

Please sign in to comment.