Skip to content

Commit

Permalink
Grad release 1.12.0
Browse files Browse the repository at this point in the history
Grad release 1.12.0
  • Loading branch information
kamal-mohammed authored Jan 15, 2024
2 parents 61cbabc + d00b749 commit e48789a
Show file tree
Hide file tree
Showing 14 changed files with 186 additions and 42 deletions.
2 changes: 1 addition & 1 deletion api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>ca.bc.gov.educ</groupId>
<artifactId>educ-grad-student-api</artifactId>
<version>1.8.52</version>
<version>1.8.53</version>
<name>educ-grad-student-api</name>
<description>Student Demographics API for GRAD team</description>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
import ca.bc.gov.educ.api.gradstudent.constant.Topics;
import ca.bc.gov.educ.api.gradstudent.exception.EntityNotFoundException;
import ca.bc.gov.educ.api.gradstudent.model.dc.Event;
import ca.bc.gov.educ.api.gradstudent.model.dc.GradStatusPayload;
import ca.bc.gov.educ.api.gradstudent.model.dto.GraduationStudentRecord;
import ca.bc.gov.educ.api.gradstudent.service.GraduationStatusService;
import ca.bc.gov.educ.api.gradstudent.util.EducGradStudentApiConstants;
import ca.bc.gov.educ.api.gradstudent.util.JsonUtil;
import ca.bc.gov.educ.api.gradstudent.util.LogHelper;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.nats.client.*;
import lombok.val;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

Expand All @@ -22,14 +26,14 @@ public class FetchGradStatusSubscriber implements MessageHandler {
private Dispatcher dispatcher;
private final GraduationStatusService graduationStatusService;

private final EducGradStudentApiConstants constants;
private static final String TOPIC = Topics.GRAD_STUDENT_API_FETCH_GRAD_STATUS_TOPIC.toString();

private static final Logger log = LoggerFactory.getLogger(FetchGradStatusSubscriber.class);

@Autowired
public FetchGradStatusSubscriber(final Connection natsConnection, GraduationStatusService graduationStatusService, EducGradStudentApiConstants constants) {
this.natsConnection = natsConnection;
this.graduationStatusService = graduationStatusService;
this.constants = constants;
}

@PostConstruct
Expand All @@ -41,18 +45,40 @@ public void subscribe() {
@Override
public void onMessage(Message message) {
val eventString = new String(message.getData());
LogHelper.logMessagingEventDetails(eventString, constants.isSplunkLogHelperEnabled());
log.debug(eventString);
String response;
try {
Event event = JsonUtil.getJsonObjectFromString(Event.class, eventString);
UUID stdId = UUID.fromString(event.getEventPayload());
boolean hasStudentGraduated = graduationStatusService.hasStudentGraduated(stdId);
response = String.valueOf(hasStudentGraduated);
UUID stdId = JsonUtil.getJsonObjectFromString(UUID.class, event.getEventPayload());
GraduationStudentRecord graduationStatus = graduationStatusService.getGraduationStatus(stdId);
response = getResponse(graduationStatus);
} catch (Exception e) {
response = (e instanceof EntityNotFoundException) ? "not found" : "error";
LogHelper.logMessagingEventDetails("NATS message exception at FetchGradStatusSubscriber: " + response + " when processing: " + eventString, constants.isSplunkLogHelperEnabled());
response = getErrorResponse(e);
if(!(e instanceof EntityNotFoundException)){
log.error(String.format("NATS message exception at FetchGradStatusSubscriber: %s when processing: %s", e.getMessage(), eventString));
}
}
this.natsConnection.publish(message.getReplyTo(), response.getBytes());
}

private String getResponse(GraduationStudentRecord graduationStudentRecord) throws JsonProcessingException {
GradStatusPayload gradStatusPayload = GradStatusPayload.builder()
.program(graduationStudentRecord.getProgram())
.programCompletionDate(graduationStudentRecord.getProgramCompletionDate())
.build();
return JsonUtil.getJsonStringFromObject(gradStatusPayload);
}

private String getErrorResponse(Exception e) {
String ex = (e instanceof EntityNotFoundException) ? "not found" : "error";
GradStatusPayload gradStatusPayload = GradStatusPayload.builder()
.exception(ex)
.build();
try {
return JsonUtil.getJsonStringFromObject(gradStatusPayload);
} catch (JsonProcessingException exc) {
return "{\"program\": \"\", \"programCompletionDate\": \"\", \"exception\": \"JSON Parsing exception\"}";
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ca.bc.gov.educ.api.gradstudent.model.dc;

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class GradStatusPayload {

private String program;
private String programCompletionDate;
private String exception;

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,21 @@ public class GraduationStatusTransformer {
@Autowired
GradValidation validation;

public GraduationStudentRecord transformToDTO (GraduationStudentRecordEntity gradStatusEntity) {
public GraduationStudentRecord transformToDTOWithModifiedProgramCompletionDate(GraduationStudentRecordEntity gradStatusEntity) {
GraduationStudentRecord gradStatus = modelMapper.map(gradStatusEntity, GraduationStudentRecord.class);
gradStatus.setProgramCompletionDate(EducGradStudentApiUtils.parseDateFromString(gradStatusEntity.getProgramCompletionDate() != null ?
EducGradStudentApiUtils.formatDate(gradStatusEntity.getProgramCompletionDate()) : null));
return gradStatus;
}

public GraduationStudentRecord transformToDTO ( Optional<GraduationStudentRecordEntity> gradStatusEntity ) {
public GraduationStudentRecord transformToDTO(GraduationStudentRecordEntity gradStatusEntity) {
GraduationStudentRecord gradStatus = modelMapper.map(gradStatusEntity, GraduationStudentRecord.class);
gradStatus.setProgramCompletionDate(gradStatusEntity.getProgramCompletionDate() != null ?
EducGradStudentApiUtils.formatDate(gradStatusEntity.getProgramCompletionDate()) : null);
return gradStatus;
}

public GraduationStudentRecord transformToDTOWithModifiedProgramCompletionDate(Optional<GraduationStudentRecordEntity> gradStatusEntity ) {
GraduationStudentRecordEntity cae = new GraduationStudentRecordEntity();
if (gradStatusEntity.isPresent())
cae = gradStatusEntity.get();
Expand All @@ -50,7 +57,7 @@ public GraduationStudentRecord transformToDTO ( Optional<GraduationStudentRecord
return gradStatus;
}

public List<GraduationStudentRecord> transformToDTO (Iterable<GraduationStudentRecordEntity> gradStatusEntities ) {
public List<GraduationStudentRecord> transformToDTOWithModifiedProgramCompletionDate(Iterable<GraduationStudentRecordEntity> gradStatusEntities ) {
List<GraduationStudentRecord> gradStatusList = new ArrayList<>();
for (GraduationStudentRecordEntity gradStatusEntity : gradStatusEntities) {
GraduationStudentRecord gradStatus = modelMapper.map(gradStatusEntity, GraduationStudentRecord.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import ca.bc.gov.educ.api.gradstudent.model.entity.GradStatusEvent;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
Expand Down Expand Up @@ -35,4 +39,9 @@ public interface GradStatusEventRepository extends JpaRepository<GradStatusEvent
* @return the list
*/
List<GradStatusEvent> findByEventStatusOrderByCreateDate(String eventStatus);

@Transactional
@Modifying
@Query("delete from GradStatusEvent where createDate <= :createDate")
void deleteByCreateDateBefore(LocalDateTime createDate);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package ca.bc.gov.educ.api.gradstudent.scheduler;

import ca.bc.gov.educ.api.gradstudent.repository.GradStatusEventRepository;
import ca.bc.gov.educ.api.gradstudent.util.EducGradStudentApiConstants;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import net.javacrumbs.shedlock.core.LockAssert;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component
@Slf4j
public class PurgeOldRecordsScheduler {
private final GradStatusEventRepository gradStatusEventRepository;
private final EducGradStudentApiConstants constants;

public PurgeOldRecordsScheduler(final GradStatusEventRepository gradStatusEventRepository,
final EducGradStudentApiConstants constants) {
this.gradStatusEventRepository = gradStatusEventRepository;
this.constants = constants;
}

@Scheduled(cron = "${cron.scheduled.process.purge-old-records.run}")
@SchedulerLock(name = "PurgeOldRecordsLock",
lockAtLeastFor = "PT1H", lockAtMostFor = "PT1H") //midnight job so lock for an hour
@Transactional
public void purgeOldRecords() {
LockAssert.assertLocked();
final LocalDateTime createDateToCompare = this.calculateCreateDateBasedOnStaleEventInDays();
this.gradStatusEventRepository.deleteByCreateDateBefore(createDateToCompare);
}

private LocalDateTime calculateCreateDateBasedOnStaleEventInDays() {
final LocalDateTime currentTime = LocalDateTime.now();
return currentTime.minusDays(this.constants.getRecordsStaleInDays());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ public GraduationStudentRecord saveGraduationStudentRecord(UUID studentID, Gradu
if (gradStatusOptional.isPresent()) {
GraduationStudentRecordEntity gradEntity = gradStatusOptional.get();
gradEntity = handleExistingGraduationStatus(sourceObject, gradEntity, graduationStatus.getPen(), ongoingUpdate);
return graduationStatusTransformer.transformToDTO(gradEntity);
return graduationStatusTransformer.transformToDTOWithModifiedProgramCompletionDate(gradEntity);
} else {
sourceObject = handleNewGraduationStatus(sourceObject, graduationStatus.getPen(), ongoingUpdate);
return graduationStatusTransformer.transformToDTO(sourceObject);
return graduationStatusTransformer.transformToDTOWithModifiedProgramCompletionDate(sourceObject);
}
}

Expand All @@ -116,7 +116,7 @@ public GraduationStudentRecord updateGraduationStatusByFields(OngoingUpdateReque
if (constants.isStudentGuidPenXrefEnabled() && StringUtils.isNotBlank(requestDTO.getPen())) {
saveStudentGuidPenXref(gradEntity.getStudentID(), requestDTO.getPen());
}
return graduationStatusTransformer.transformToDTO(gradEntity);
return graduationStatusTransformer.transformToDTOWithModifiedProgramCompletionDate(gradEntity);
}
return null;
}
Expand Down Expand Up @@ -275,21 +275,33 @@ private void populateOngoingUpdateFields(List<OngoingUpdateFieldDTO> fields, Gra
if (f.getName() == FieldName.GRAD_PROGRAM) {
String newProgram = (String) f.getValue();
String currentProgram = targetObject.getProgram();
if (!StringUtils.equalsIgnoreCase(currentProgram, newProgram)) {
if("SCCP".equalsIgnoreCase(currentProgram)) {
log.info(" {} ==> {}: Archive Student Achievements and SLP_DATE is set to null.", currentProgram, newProgram);
targetObject.setProgramCompletionDate(null);
graduationStatusService.archiveStudentAchievements(targetObject.getStudentID(),accessToken);
} else {
log.info(" {} ==> {}: Delete Student Achievements.", currentProgram, newProgram);
graduationStatusService.deleteStudentAchievements(targetObject.getStudentID(), accessToken);
}
}
handleStudentAchievements(currentProgram, newProgram, targetObject, accessToken);
resetAdultStartDate(currentProgram, newProgram, targetObject);
}
populate(f, targetObject);
});
}

private void handleStudentAchievements(String currentProgram, String newProgram, GraduationStudentRecordEntity targetObject, String accessToken) {
if (!StringUtils.equalsIgnoreCase(currentProgram, newProgram)) {
if("SCCP".equalsIgnoreCase(currentProgram)) {
log.info(" {} ==> {}: Archive Student Achievements and SLP_DATE is set to null.", currentProgram, newProgram);
targetObject.setProgramCompletionDate(null);
graduationStatusService.archiveStudentAchievements(targetObject.getStudentID(),accessToken);
} else {
log.info(" {} ==> {}: Delete Student Achievements.", currentProgram, newProgram);
graduationStatusService.deleteStudentAchievements(targetObject.getStudentID(), accessToken);
}
}
}

private void resetAdultStartDate(String currentProgram, String newProgram, GraduationStudentRecordEntity targetObject) {
// Only when 1950 adult program is channged to another, reset adultStartDate to null
if (!StringUtils.equalsIgnoreCase(currentProgram, newProgram) && "1950".equalsIgnoreCase(currentProgram)) {
targetObject.setAdultStartDate(null);
}
}

private void populate(OngoingUpdateFieldDTO field, GraduationStudentRecordEntity targetObject) {
switch (field.getName()) {
case SCHOOL_OF_RECORD -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ private GradSearchStudent populateGradSearchStudent(Student student, String acce
BeanUtils.copyProperties(student, gradStu);
GraduationStudentRecordEntity graduationStatusEntity = graduationStatusRepository.findByStudentID(UUID.fromString(student.getStudentID()));
if(graduationStatusEntity != null) {
GraduationStudentRecord gradObj = graduationStatusTransformer.transformToDTO(graduationStatusEntity);
GraduationStudentRecord gradObj = graduationStatusTransformer.transformToDTOWithModifiedProgramCompletionDate(graduationStatusEntity);
gradStu.setProgram(gradObj.getProgram());
gradStu.setStudentGrade(gradObj.getStudentGrade());
gradStu.setStudentStatus(gradObj.getStudentStatus());
Expand Down
Loading

0 comments on commit e48789a

Please sign in to comment.