Skip to content

Commit

Permalink
GRAD2-2869 (#347)
Browse files Browse the repository at this point in the history
* Added an extra type hierarchy for school events for filtering on transcript eligibility

* Added some unit tests to support history filtering on school created events

* Added testing for school updated

* Added testing and code for move school filtering

* Added rules for UPDATE_SCHOOL_CONTACT

* Removed old update event with history method.

* Removed redundant method from abstract class.

---------

Co-authored-by: chris.ditcher <[email protected]>
  • Loading branch information
cditcher and chris.ditcher authored Aug 20, 2024
1 parent 49e23f5 commit d6efa14
Show file tree
Hide file tree
Showing 19 changed files with 169 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
import ca.bc.gov.educ.api.trax.model.entity.EventHistoryEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;
import java.util.UUID;

@Repository
public interface EventHistoryRepository extends JpaRepository<EventHistoryEntity, UUID> {

Optional<EventHistoryEntity> findByEvent_ReplicationEventId(UUID replicationEventId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class AuthorityContactCreatedService extends EventBaseService<AuthorityCo
public void processEvent(final AuthorityContact districtContact, EventEntity eventEntity) {
log.debug("Processing Authority Contact Created");
// process the eventEntity here as per https://eccbc.atlassian.net/browse/GRAD2-2648
this.updateEvent(eventEntity);
this.updateEvent(eventEntity, false);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class AuthorityContactDeletedService extends EventBaseService<AuthorityCo
public void processEvent(final AuthorityContact districtContact, EventEntity eventEntity) {
log.debug("Processing Authority Contact Deleted");
// process the eventEntity here as per https://eccbc.atlassian.net/browse/GRAD2-2648
this.updateEvent(eventEntity);
this.updateEvent(eventEntity, false);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class AuthorityContactUpdatedService extends EventBaseService<AuthorityCo
public void processEvent(final AuthorityContact districtContact, EventEntity eventEntity) {
log.debug("Processing Authority Contact Updated");
// process the eventEntity here as per https://eccbc.atlassian.net/browse/GRAD2-2648
this.updateEvent(eventEntity);
this.updateEvent(eventEntity, false);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ protected DistrictContactEventBaseService(DistrictService districtService) {
public void processEvent(DistrictContact districtContact, EventEntity eventEntity) {log.debug("Processing {}", eventEntity.getEventType());
try {
districtService.updateDistrictCache(districtContact.getDistrictId());
this.updateEvent(eventEntity);
this.updateEvent(eventEntity, false);
} catch (ServiceException e) {
// do not mark eventEntity as processed
log.error(e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void processEvent(final DistrictContact districtContact, EventEntity even
log.debug("Processing District Contact Deleted");
try{
districtService.updateDistrictCache(districtContact.getDistrictId());
this.updateEventWithHistory(eventEntity);
this.updateEvent(eventEntity, true);
} catch (ServiceException e) {
// do not mark eventEntity as processed
log.error(e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void processEvent(final District district, EventEntity eventEntity) {
log.debug("Processing District Created");
try{
districtService.updateDistrictCache(district.getDistrictId());
this.updateEvent(eventEntity);
this.updateEvent(eventEntity, false);
} catch (ServiceException e) {
log.error(e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void processEvent(final District district, EventEntity eventEntity) {
log.debug("Processing District Updated");
try{
districtService.updateDistrictCache(district.getDistrictId());
this.updateEventWithHistory(eventEntity);
this.updateEvent(eventEntity, true);
} catch (ServiceException e) {
log.error(e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.util.Optional;

public abstract class EventBaseService<T> implements EventService<T> {

Expand All @@ -17,28 +16,17 @@ public abstract class EventBaseService<T> implements EventService<T> {
@Autowired
protected EventHistoryRepository eventHistoryRepository;

protected void updateEvent(final EventEntity eventEntity) {
protected void updateEvent(final EventEntity eventEntity, boolean includeHistory) {
this.eventRepository.findByEventId(eventEntity.getEventId()).ifPresent(existingEvent -> {
existingEvent.setEventStatus(EventStatus.PROCESSED.toString());
existingEvent.setUpdateDate(LocalDateTime.now());
this.eventRepository.save(existingEvent);
if(includeHistory){
EventHistoryEntity eventHistoryEntity = new EventHistoryEntity();
eventHistoryEntity.setEvent(existingEvent);
this.eventHistoryRepository.save(eventHistoryEntity);
}
});
}

/**
* Adds the event to the EventHistory table. Implementing classes may want to
* use this method if they are interested in history tracking
* @param eventEntity the event entity
*/
protected void updateEventWithHistory(final EventEntity eventEntity) {
this.updateEvent(eventEntity);
Optional<EventEntity> savedEvent = this.eventRepository.findByEventId(eventEntity.getEventId());
if(savedEvent.isPresent()){
EventHistoryEntity eventHistoryEntity = new EventHistoryEntity();
eventHistoryEntity.setEvent(savedEvent.get());
this.eventHistoryRepository.save(eventHistoryEntity);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public void processEvent(SchoolContact schoolContact, EventEntity eventEntity) {
log.debug("Processing {}", eventEntity.getEventType());
try {
schoolService.updateSchoolCache(schoolContact.getSchoolId());
this.updateEvent(eventEntity);
this.updateEvent(eventEntity, false);
} catch (ServiceException e) {
// do not mark eventEntity as processed
log.error(e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import ca.bc.gov.educ.api.trax.constant.EventType;
import ca.bc.gov.educ.api.trax.exception.ServiceException;
import ca.bc.gov.educ.api.trax.model.dto.SchoolContact;
import ca.bc.gov.educ.api.trax.model.dto.institute.SchoolDetail;
import ca.bc.gov.educ.api.trax.model.entity.EventEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -11,21 +12,20 @@

@Service
@Slf4j
public class SchoolContactUpdatedService extends EventBaseService<SchoolContact> {

SchoolService schoolService;
public class SchoolContactUpdatedService extends SchoolEventBaseService<SchoolContact> {

@Autowired
public SchoolContactUpdatedService(SchoolService schoolService) {
this.schoolService = schoolService;
super(schoolService);
}

@Override
public void processEvent(final SchoolContact schoolContact, EventEntity eventEntity) {
log.debug("Processing School Contact Updated");
try{
schoolService.updateSchoolCache(schoolContact.getSchoolId());
this.updateEventWithHistory(eventEntity);
SchoolDetail schoolDetail = this.schoolService.getSchoolDetailByIdFromInstituteApi(schoolContact.getSchoolId());
schoolService.updateSchoolCache(schoolDetail);
this.updateEvent(eventEntity, schoolDetail.isCanIssueTranscripts());
} catch (ServiceException e) {
// do not mark eventEntity as processed
log.error(e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,19 @@

@Service
@Slf4j
public class SchoolCreatedService extends EventBaseService<School> {

SchoolService schoolService;
public class SchoolCreatedService extends SchoolEventBaseService<School> {

@Autowired
public SchoolCreatedService(SchoolService schoolService) {
this.schoolService = schoolService;
super(schoolService);
}

@Override
public void processEvent(final School school, EventEntity eventEntity) {
log.debug("Processing School Created");
try{
schoolService.updateSchoolCache(school.getSchoolId());
this.updateEventWithHistory(eventEntity);
this.updateEvent(eventEntity, this.shouldCreateHistory(school));
} catch (ServiceException e) {
log.error(e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ca.bc.gov.educ.api.trax.service;

import ca.bc.gov.educ.api.trax.model.dto.institute.School;
import ca.bc.gov.educ.api.trax.service.institute.SchoolService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public abstract class SchoolEventBaseService<T> extends EventBaseService<T> {

protected SchoolService schoolService;

protected SchoolEventBaseService(SchoolService schoolService) {
this.schoolService = schoolService;
}

/**
* Acts as a filter. Add rules here for if a school event should be added to history table
* @param school a school object
* @return true if the school object passes eligibility for history table
*/
protected boolean shouldCreateHistory(School school) {
// currently only schools that can issue transcripts qualify
return school.isCanIssueTranscripts();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import ca.bc.gov.educ.api.trax.constant.EventType;
import ca.bc.gov.educ.api.trax.exception.ServiceException;
import ca.bc.gov.educ.api.trax.model.dto.institute.MoveSchoolData;
import ca.bc.gov.educ.api.trax.model.dto.institute.SchoolDetail;
import ca.bc.gov.educ.api.trax.model.entity.EventEntity;
import ca.bc.gov.educ.api.trax.service.institute.SchoolService;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -13,21 +14,23 @@

@Service
@Slf4j
public class SchoolMovedService extends EventBaseService<MoveSchoolData> {

SchoolService schoolService;
public class SchoolMovedService extends SchoolEventBaseService<MoveSchoolData> {

@Autowired
public SchoolMovedService(SchoolService schoolService) {
this.schoolService = schoolService;
super(schoolService);
}

@Override
public void processEvent(final MoveSchoolData moveSchoolData, EventEntity eventEntity) {
log.debug("Processing School Moved");
try{
schoolService.updateSchoolCache(Arrays.asList(moveSchoolData.getFromSchoolId(), moveSchoolData.getToSchool().getSchoolId()));
this.updateEventWithHistory(eventEntity);
// have to check event history eligibility on from and to schools for move.
// if one can issue transcripts, set history eligibility
SchoolDetail schoolDetail = this.schoolService.getSchoolDetailByIdFromInstituteApi(moveSchoolData.getFromSchoolId());
boolean shouldCreateHistory = (schoolDetail.isCanIssueTranscripts() || this.shouldCreateHistory(moveSchoolData.getToSchool()));
this.updateEvent(eventEntity, shouldCreateHistory);
} catch (ServiceException e) {
log.error(e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ public void updateSchoolCache(String schoolId) throws ServiceException {
schoolDetailRedisRepository.save(schoolDetailTransformer.transformToEntity(schoolDetail));
}

/**
* Updates the school and school details in the cache
* @param schoolDetail the school detail object
*/
public void updateSchoolCache(SchoolDetail schoolDetail) throws ServiceException {
schoolDetailRedisRepository.save(schoolDetailTransformer.transformToEntity(schoolDetail));
}

/**
* Updates the school and school details in the cache
* based on schoolId
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ca.bc.gov.educ.api.trax.service;

import ca.bc.gov.educ.api.trax.constant.EventType;
import ca.bc.gov.educ.api.trax.exception.ServiceException;
import ca.bc.gov.educ.api.trax.service.institute.SchoolService;
import ca.bc.gov.educ.api.trax.support.TestUtils;
Expand All @@ -12,6 +13,7 @@
import static org.assertj.core.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.when;

public class SchoolContactUpdatedServiceTest extends BaseReplicationServiceTest {

Expand All @@ -25,6 +27,9 @@ public class SchoolContactUpdatedServiceTest extends BaseReplicationServiceTest
public void testProcessEvent_givenUPDATE_SCHOOL_CONTACT_Event_shouldProcessEvent() throws JsonProcessingException {
final var request = TestUtils.createSchoolContact();
final var event = TestUtils.createEvent("UPDATE_SCHOOL_CONTACT", request, this.replicationTestUtils.getEventRepository());
var schoolDetails = TestUtils.createSchoolDetail();
schoolDetails.setSchoolId(request.getSchoolId());
when(schoolServiceMock.getSchoolDetailByIdFromInstituteApi(request.getSchoolId())).thenReturn(schoolDetails);
this.schoolContactUpdatedService.processEvent(request, event);
var result = this.replicationTestUtils.getEventRepository().findById(event.getReplicationEventId());
if(result.isPresent()){
Expand All @@ -37,9 +42,9 @@ public void testProcessEvent_givenUPDATE_SCHOOL_CONTACT_Event_shouldProcessEvent
@Test
public void testProcessEvent_givenUPDATE_SCHOOL_CONTACT_Event_ServiceUnavailable_triggerError() throws JsonProcessingException {
final String ERROR_MSG = "Test Exception";
doThrow(new ServiceException(ERROR_MSG)).when(schoolServiceMock).updateSchoolCache(anyString());
final var request = TestUtils.createSchoolContact();
final var event = TestUtils.createEvent("UPDATE_SCHOOL_CONTACT", request, this.replicationTestUtils.getEventRepository());
doThrow(new ServiceException(ERROR_MSG)).when(schoolServiceMock).getSchoolDetailByIdFromInstituteApi(anyString());
this.schoolContactUpdatedService.processEvent(request, event);
var result = this.replicationTestUtils.getEventRepository().findById(event.getReplicationEventId());
if(result.isPresent()){
Expand All @@ -48,4 +53,27 @@ public void testProcessEvent_givenUPDATE_SCHOOL_CONTACT_Event_ServiceUnavailable
fail("UPDATE_SCHOOL_CONTACT failed to process");
}
}

@Test
public void testProcessEvent_givenUPDATE_SCHOOL_CONTACT_EventWithPassingHistoryCriteria_shouldStoreInHistoryTable() throws JsonProcessingException {
final var request = TestUtils.createSchoolContact();
final var event = TestUtils.createEvent(EventType.CREATE_SCHOOL_CONTACT.toString(), request, this.replicationTestUtils.getEventRepository());
var schoolDetails = TestUtils.createSchoolDetail();
when(schoolServiceMock.getSchoolDetailByIdFromInstituteApi(request.getSchoolId())).thenReturn(schoolDetails);
this.schoolContactUpdatedService.processEvent(request, event);
var result = this.replicationTestUtils.getEventHistoryRepository().findByEvent_ReplicationEventId(event.getReplicationEventId());
Assert.assertTrue(result.isPresent());
}

@Test
public void testProcessEvent_givenUPDATE_SCHOOL_CONTACT_EventWithFailingHistoryCriteria_shouldNotStoreInHistoryTable() throws JsonProcessingException {
final var request = TestUtils.createSchoolContact();
final var event = TestUtils.createEvent(EventType.CREATE_SCHOOL_CONTACT.toString(), request, this.replicationTestUtils.getEventRepository());
var schoolDetails = TestUtils.createSchoolDetail();
schoolDetails.setCanIssueTranscripts(false);
when(schoolServiceMock.getSchoolDetailByIdFromInstituteApi(request.getSchoolId())).thenReturn(schoolDetails);
this.schoolContactUpdatedService.processEvent(request, event);
var result = this.replicationTestUtils.getEventHistoryRepository().findByEvent_ReplicationEventId(event.getReplicationEventId());
Assert.assertFalse(result.isPresent());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,23 @@ public void testProcessEvent_givenCREATE_SCHOOL_Event_ServiceUnavailable_trigger
fail("CREATE_SCHOOL failed to process");
}
}

@Test
public void testProcessEvent_givenCREATE_SCHOOL_EventWithPassingHistoryCriteria_shouldStoreInHistoryTable() throws JsonProcessingException {
final var request = TestUtils.createSchool();
final var event = TestUtils.createEvent(EventType.CREATE_SCHOOL.toString(), request, this.replicationTestUtils.getEventRepository());
this.schoolCreatedService.processEvent(request, event);
var result = this.replicationTestUtils.getEventHistoryRepository().findByEvent_ReplicationEventId(event.getReplicationEventId());
Assert.assertTrue(result.isPresent());
}

@Test
public void testProcessEvent_givenCREATE_SCHOOL_EventWithFailingHistoryCriteria_shouldNotStoreInHistoryTable() throws JsonProcessingException {
final var request = TestUtils.createSchool();
request.setCanIssueTranscripts(false);
final var event = TestUtils.createEvent(EventType.CREATE_SCHOOL.toString(), request, this.replicationTestUtils.getEventRepository());
this.schoolCreatedService.processEvent(request, event);
var result = this.replicationTestUtils.getEventHistoryRepository().findByEvent_ReplicationEventId(event.getReplicationEventId());
Assert.assertFalse(result.isPresent());
}
}
Loading

0 comments on commit d6efa14

Please sign in to comment.