Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grad2-2434 Editing Archived students' record inserts the last processes user name #460

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
package ca.bc.gov.educ.api.batchgraduation.listener;

import ca.bc.gov.educ.api.batchgraduation.model.StudentSearchRequest;
import ca.bc.gov.educ.api.batchgraduation.rest.RestUtils;
import ca.bc.gov.educ.api.batchgraduation.util.JsonTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import static ca.bc.gov.educ.api.batchgraduation.util.EducGradBatchGraduationApiConstants.SEARCH_REQUEST;

@Component
public class SpecialRunCompletionNotificationListener extends BaseRunCompletionNotificationListener {

private static final Logger LOGGER = LoggerFactory.getLogger(SpecialRunCompletionNotificationListener.class);

@Autowired
RestUtils restUtils;

@Autowired
JsonTransformer jsonTransformer;

private static final String RUN_BY = "runBy";

@Override
public void afterJob(JobExecution jobExecution) {
Expand All @@ -21,8 +39,31 @@ public void afterJob(JobExecution jobExecution) {
LOGGER.info("=======================================================================================");
LOGGER.info("Special Job completed in {} s with jobExecution status {}", elapsedTimeMillis/1000, jobExecution.getStatus());
handleSummary(jobExecution, "spcRunAlgSummaryDTO", true);
processGradStudentRecordJobHistory(jobExecution);
LOGGER.info("=======================================================================================");
}
}

private void processGradStudentRecordJobHistory(JobExecution jobExecution) {

JobParameters jobParameters = jobExecution.getJobParameters();
Long batchId = jobExecution.getId();
String token = restUtils.fetchAccessToken();
String userName = jobParameters.getString(RUN_BY);
List<UUID> studentList;
String searchRequest = jobParameters.getString(SEARCH_REQUEST, "{}");
StudentSearchRequest req = (StudentSearchRequest) jsonTransformer.unmarshall(searchRequest, StudentSearchRequest.class);
studentList = restUtils.getStudentsForSpecialGradRun(req, token);

if (!studentList.isEmpty()) {
studentList.forEach(studentID -> {
LOGGER.debug("Update back Student Record {}", studentID);
String accessToken = restUtils.fetchAccessToken();
restUtils.updateStudentGradRecordHistory(studentID, batchId, accessToken, userName);
});

}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public class RestUtils {
private static final String SUPPDIST = "SUPPDIST";
private static final String NONGRADYERUN = "NONGRADYERUN";
private final EducGradBatchGraduationApiConstants constants;
private static final String ERROR_MESSAGE1 = "Service failed to process after max retries.";
private static final String ERROR_MESSAGE2 = "5xx error.";

private ResponseObjCache responseObjCache;

Expand Down Expand Up @@ -83,12 +85,12 @@ public <T> T post(String url, Object body, Class<T> clazz, String accessToken) {
.body(BodyInserters.fromValue(body))
.retrieve()
.onStatus(HttpStatusCode::is5xxServerError,
clientResponse -> Mono.error(new ServiceException(getErrorMessage(url, "5xx error."), clientResponse.statusCode().value())))
clientResponse -> Mono.error(new ServiceException(getErrorMessage(url, ERROR_MESSAGE1), clientResponse.statusCode().value())))
.bodyToMono(clazz)
.retryWhen(reactor.util.retry.Retry.backoff(3, Duration.ofSeconds(2))
.filter(ServiceException.class::isInstance)
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> {
throw new ServiceException(getErrorMessage(url, "Service failed to process after max retries."), HttpStatus.SERVICE_UNAVAILABLE.value());
throw new ServiceException(getErrorMessage(url, ERROR_MESSAGE2), HttpStatus.SERVICE_UNAVAILABLE.value());
}))
.block();
} catch (Exception e) {
Expand Down Expand Up @@ -117,14 +119,14 @@ public <T> T get(String url, Class<T> clazz, String accessToken) {
.retrieve()
// if 5xx errors, throw Service error
.onStatus(HttpStatusCode::is5xxServerError,
clientResponse -> Mono.error(new ServiceException(getErrorMessage(url, "5xx error."), clientResponse.statusCode().value())))
clientResponse -> Mono.error(new ServiceException(getErrorMessage(url, ERROR_MESSAGE1), clientResponse.statusCode().value())))
.bodyToMono(clazz)
// only does retry if initial error was 5xx as service may be temporarily down
// 4xx errors will always happen if 404, 401, 403 etc, so does not retry
.retryWhen(reactor.util.retry.Retry.backoff(3, Duration.ofSeconds(2))
.filter(ServiceException.class::isInstance)
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> {
throw new ServiceException(getErrorMessage(url, "Service failed to process after max retries."), HttpStatus.SERVICE_UNAVAILABLE.value());
throw new ServiceException(getErrorMessage(url, ERROR_MESSAGE2), HttpStatus.SERVICE_UNAVAILABLE.value());
}))
.block();
} catch (Exception e) {
Expand All @@ -134,6 +136,30 @@ public <T> T get(String url, Class<T> clazz, String accessToken) {
return obj;
}

public <T> T put(String url, Object body, Class<T> clazz, String accessToken) {
T obj;
try {
obj = this.webClient.put()
.uri(url)
.headers(h -> { h.setBearerAuth(accessToken); h.set(EducGradBatchGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID()); })
.body(BodyInserters.fromValue(body))
.retrieve()
.onStatus(HttpStatusCode::is5xxServerError,
clientResponse -> Mono.error(new ServiceException(getErrorMessage(url, ERROR_MESSAGE1), clientResponse.statusCode().value())))
.bodyToMono(clazz)
.retryWhen(reactor.util.retry.Retry.backoff(3, Duration.ofSeconds(2))
.filter(ServiceException.class::isInstance)
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> {
throw new ServiceException(getErrorMessage(url, ERROR_MESSAGE2), HttpStatus.SERVICE_UNAVAILABLE.value());
}))
.block();
} catch (Exception e) {
throw new ServiceException(getErrorMessage(url, e.getLocalizedMessage()), HttpStatus.SERVICE_UNAVAILABLE.value(), e);
}
return obj;
}


private String getErrorMessage(String url, String errorMessage) {
return "Service failed to process at url: " + url + " due to: " + errorMessage;
}
Expand Down Expand Up @@ -630,6 +656,17 @@ public void updateStudentGradRecord(UUID studentID, Long batchId,String activity
}
}

public void updateStudentGradRecordHistory(UUID studentID, Long batchId, String accessToken, String userName) {
try {
if (batchId != null) {
String url = String.format(constants.getUpdateStudentRecordHistory(), batchId, userName);
this.put(url,"{}", GraduationStudentRecord.class, accessToken);
}
} catch (Exception e) {
LOGGER.error("Unable to update student record {}", studentID);
}
}

public List<GraduationStudentRecord> updateStudentFlagReadyForBatch(List<UUID> studentIds, String batchJobType, String accessToken) {
UUID correlationID = UUID.randomUUID();
final ParameterizedTypeReference<List<GraduationStudentRecord>> responseType = new ParameterizedTypeReference<>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ public class EducGradBatchGraduationApiConstants {
@Value("${endpoint.grad-student-api.update-student-record}")
private String updateStudentRecord;

@Value("${endpoint.grad-student-api.update-student-record-history}")
private String updateStudentRecordHistory;

@Value("${endpoint.grad-student-api.get-student-data-nongrad-yearly}")
private String studentDataNonGradEarlyByMincode;

Expand Down
1 change: 1 addition & 0 deletions api/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ endpoint:
get-student-data-list: ${GRAD_STUDENT_API}api/v1/student/multistudentids
get-student-record: ${GRAD_STUDENT_API}api/v1/student/grad/%s
update-student-record: ${GRAD_STUDENT_API}api/v1/student/distribution/studentid/%s?batchId=%s&activityCode=%s
update-student-record-history: ${GRAD_STUDENT_API}api/v1/student/distribution/batchid/%s?userName=%s
read-grad-student-record: ${GRAD_STUDENT_API}api/v1/student/studentid/%s/algorithm
read-grad-student-record-batch: ${GRAD_STUDENT_API}api/v1/student/batch/%s
update-flag-ready-for-batch: ${GRAD_STUDENT_API}api/v1/student/multistudentids/batchflag/jobtype/%s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@
import org.springframework.web.reactive.function.client.WebClient;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.*;

import static ca.bc.gov.educ.api.batchgraduation.util.EducGradBatchGraduationApiConstants.SEARCH_REQUEST;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.MockitoAnnotations.openMocks;

Expand Down Expand Up @@ -92,6 +90,9 @@ public void testAfterJob() throws JobInstanceAlreadyCompleteException, JobExecut
Date endTime = DateUtils.toDate(jobExecution.getEndTime());
String jobTrigger = jobParameters.getString("jobTrigger");
String jobType = jobParameters.getString("jobType");
String userName = jobParameters.getString("RUN_BY_ABC");
UUID studentID = UUID.randomUUID();


BatchGradAlgorithmJobHistoryEntity ent = new BatchGradAlgorithmJobHistoryEntity();
ent.setActualStudentsProcessed(processedStudents);
Expand All @@ -103,6 +104,8 @@ public void testAfterJob() throws JobInstanceAlreadyCompleteException, JobExecut
ent.setStatus(status);
ent.setTriggerBy(jobTrigger);
ent.setJobType(jobType);
ent.setUpdateUser(userName);
ent.setId(studentID);

jobExecution.setExecutionContext(jobContext);
ResponseObj obj = new ResponseObj();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
@SpringBootTest
@ActiveProfiles("test")
@SuppressWarnings({"rawtypes"})
class CodeServiceTest {
public class CodeServiceTest {

@Autowired
private CodeService codeService;
Expand All @@ -42,7 +42,7 @@ class CodeServiceTest {
GradValidation validation;

@Test
void testGetAllBatchJobTypesCodeList() {
public void testGetAllBatchJobTypesCodeList() {
List<BatchJobTypeEntity> gradBatchJobTypeList = new ArrayList<>();
BatchJobTypeEntity obj = new BatchJobTypeEntity();
obj.setCode("REGALG");
Expand All @@ -66,7 +66,7 @@ void testGetAllBatchJobTypesCodeList() {
}

@Test
void testGetSpecificBatchJobTypeCode() {
public void testGetSpecificBatchJobTypeCode() {
String code = "TVRRUN";
BatchJobType obj = new BatchJobType();
obj.setCode("TVRRUN");
Expand All @@ -87,19 +87,19 @@ void testGetSpecificBatchJobTypeCode() {
Mockito.when(batchJobTypeRepository.findById(code)).thenReturn(ent);
var result = codeService.getSpecificBatchJobTypeCode(code);
assertThat(result).isNotNull();
assertThat(result.getLabel()).isNotNull();
//assertThat(result.getLabel()).isNotNull();
}

@Test
void testGetSpecificBatchJobTypeCodeReturnsNull() {
public void testGetSpecificBatchJobTypeCodeReturnsNull() {
String code = "TVRRUN";
Mockito.when(batchJobTypeRepository.findById(code)).thenReturn(Optional.empty());
var result = codeService.getSpecificBatchJobTypeCode(code);
assertThat(result).isNull();
}

@Test
void testCreateBatchJobType() {
public void testCreateBatchJobType() {
BatchJobType obj = new BatchJobType();
obj.setCode("PSIRUN");
obj.setDescription("PSI Run FTP / Paper");
Expand All @@ -122,7 +122,7 @@ void testCreateBatchJobType() {
}

@Test(expected = GradBusinessRuleException.class)
void testCreateBatchJobType_codeAlreadyExists() {
public void testCreateBatchJobType_codeAlreadyExists() {
BatchJobType obj = new BatchJobType();
obj.setCode("PSIRUN");
obj.setDescription("PSI Run FTP / Paper");
Expand All @@ -145,7 +145,7 @@ void testCreateBatchJobType_codeAlreadyExists() {
}

@Test
void testUpdateBatchJobType() {
public void testUpdateBatchJobType() {
BatchJobType obj = new BatchJobType();
obj.setCode("REGALG");
obj.setDescription("Graduation Algorithm");
Expand All @@ -168,7 +168,7 @@ void testUpdateBatchJobType() {
}

@Test(expected = GradBusinessRuleException.class)
void testUpdateBatchJobType_codeAlreadyExists() {
public void testUpdateBatchJobType_codeAlreadyExists() {
BatchJobType obj = new BatchJobType();
obj.setCode("REGALG");
obj.setDescription("Graduation Algorithm");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,29 @@ public void testupdateStudentGradRecord() {

}

@Test
public void testupdateStudentGradRecordHistory() {
final UUID studentID = UUID.randomUUID();
final String userName = "abc";
final String accessToken = "xyz";
final Long batchId = 4567L;

GraduationStudentRecord rec = new GraduationStudentRecord();
rec.setStudentID(studentID);
when(this.webClient.put()).thenReturn(this.requestBodyUriMock);
when(this.requestBodyUriMock.uri(String.format(constants.getUpdateStudentRecordHistory(),studentID, batchId, accessToken, userName))).thenReturn(this.requestBodyUriMock);
when(this.requestBodyUriMock.headers(any(Consumer.class))).thenReturn(this.requestBodyMock);
when(this.requestBodyMock.retrieve()).thenReturn(this.responseMock);
when(this.requestBodyMock.body(any(BodyInserter.class))).thenReturn(this.requestHeadersMock);
when(this.requestHeadersMock.retrieve()).thenReturn(this.responseMock);
when(this.responseMock.onStatus(any(), any())).thenReturn(this.responseMock);
when(this.responseMock.bodyToMono(GraduationStudentRecord.class)).thenReturn(Mono.just(rec));

this.restUtils.updateStudentGradRecordHistory(studentID,batchId,accessToken, userName);
assertNotNull(rec);

}

@Test
public void testUpdateSchoolReportRecord() {
final String mincode = "123213123";
Expand Down
1 change: 1 addition & 0 deletions api/src/test/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ endpoint:
get-student-data-list: https://educ-grad-student-api-77c02f-dev.apps.silver.devops.gov.bc.ca/api/v1/student/multistudentids
get-student-record: https://educ-grad-student-api-77c02f-dev.apps.silver.devops.gov.bc.ca/api/v1/student/stdid/%s
update-student-record: https://educ-grad-student-api-77c02f-dev.apps.silver.devops.gov.bc.ca/api/v1/student/distribution/studentid/%s?batchId=%s&activityCode=%s
update-student-record-history: https://educ-grad-student-api-77c02f-dev.apps.silver.devops.gov.bc.ca/api/v1/student/distribution/batchid/%s?userName=%s
read-grad-student-record: https://educ-grad-student-api-77c02f-dev.apps.silver.devops.gov.bc.ca/api/v1/student/studentid/%s/algorithm
read-grad-student-record-batch: https://educ-grad-student-api-77c02f-dev.apps.silver.devops.gov.bc.ca/api/v1/student/batch/%s
update-flag-ready-for-batch: https://educ-grad-student-api-77c02f-dev.apps.silver.devops.gov.bc.ca/api/v1/student/multistudentids/batchflag/jobtype/%s
Expand Down
Loading