Skip to content

Commit cb092df

Browse files
Code review comments.
1 parent 34528af commit cb092df

File tree

5 files changed

+91
-53
lines changed

5 files changed

+91
-53
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package ca.bc.gov.educ.api.trax.constant;
22

33
public enum CacheKey {
4-
SCHOOL_CACHE, DISTRICT_CACHE, SCHOOL_CATEGORY_CODE_CACHE, SCHOOL_FUNDING_GROUP_CODE_CACHE
4+
SCHOOL_CACHE, SCHOOL_DETAIL_CACHE, DISTRICT_CACHE, SCHOOL_CATEGORY_CODE_CACHE, SCHOOL_FUNDING_GROUP_CODE_CACHE
55
}
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,36 @@
11
package ca.bc.gov.educ.api.trax.service.institute;
22

3+
import ca.bc.gov.educ.api.trax.constant.CacheKey;
4+
import ca.bc.gov.educ.api.trax.constant.CacheStatus;
35
import ca.bc.gov.educ.api.trax.model.entity.institute.*;
46
import ca.bc.gov.educ.api.trax.repository.redis.*;
57
import com.google.common.collect.Lists;
6-
import lombok.RequiredArgsConstructor;
8+
import lombok.AllArgsConstructor;
79
import lombok.extern.slf4j.Slf4j;
8-
import org.springframework.beans.factory.annotation.Autowired;
910
import org.springframework.scheduling.annotation.Async;
1011
import org.springframework.stereotype.Service;
1112
import org.springframework.util.CollectionUtils;
13+
import redis.clients.jedis.JedisCluster;
1214

1315
import java.util.List;
1416

1517
@Slf4j
16-
@RequiredArgsConstructor
18+
@AllArgsConstructor
1719
@Service("cacheService")
1820
public class CacheService {
1921

20-
@Autowired
2122
SchoolRedisRepository schoolRedisRepository;
2223

23-
@Autowired
2424
SchoolDetailRedisRepository schoolDetailRedisRepository;
2525

26-
@Autowired
2726
DistrictRedisRepository districtRedisRepository;
2827

29-
@Autowired
3028
SchoolCategoryCodeRedisRepository schoolCategoryCodeRedisRepository;
3129

32-
@Autowired
3330
SchoolFundingGroupCodeRedisRepository schoolFundingGroupCodeRedisRepository;
3431

32+
JedisCluster jedisCluster;
33+
3534
@Async("taskExecutor")
3635
public void loadSchoolsIntoRedisCacheAsync(List<SchoolEntity> schools) {
3736
if(!CollectionUtils.isEmpty(schools)) {
@@ -40,13 +39,15 @@ public void loadSchoolsIntoRedisCacheAsync(List<SchoolEntity> schools) {
4039
}
4140

4241
public void loadSchoolsIntoRedisCache(List<SchoolEntity> schools) {
43-
if(!CollectionUtils.isEmpty(schools)) {
42+
if(!isCacheLoading(CacheKey.SCHOOL_CACHE) && !CollectionUtils.isEmpty(schools)) {
43+
setCacheStateLoading(CacheKey.SCHOOL_CACHE);
4444
long start = System.currentTimeMillis();
4545
log.debug("****Before loading schools into cache");
4646
for (List<SchoolEntity> partition : Lists.partition(schools, 1000)) {
4747
schoolRedisRepository.saveAll(partition);
4848
}
4949
log.info("{} Schools Loaded into cache in {} ms.", schools.size(), (System.currentTimeMillis() - start));
50+
setCacheReadiness(CacheKey.SCHOOL_CACHE);
5051
}
5152
}
5253

@@ -58,13 +59,15 @@ public void loadSchoolDetailsIntoRedisCacheAsync(List<SchoolDetailEntity> school
5859
}
5960

6061
public void loadSchoolDetailsIntoRedisCache(List<SchoolDetailEntity> schoolDetails) {
61-
if(!CollectionUtils.isEmpty(schoolDetails)) {
62+
if(!isCacheLoading(CacheKey.SCHOOL_DETAIL_CACHE) && !CollectionUtils.isEmpty(schoolDetails)) {
63+
setCacheStateLoading(CacheKey.SCHOOL_DETAIL_CACHE);
6264
long start = System.currentTimeMillis();
6365
log.debug("****Before loading school details into cache");
6466
for (List<SchoolDetailEntity> partition : Lists.partition(schoolDetails, 1000)) {
6567
schoolDetailRedisRepository.saveAll(partition);
6668
}
6769
log.info("{} School Details Loaded into cache in {} ms.", schoolDetails.size(), (System.currentTimeMillis() - start));
70+
setCacheReadiness(CacheKey.SCHOOL_DETAIL_CACHE);
6871
}
6972
}
7073

@@ -76,11 +79,13 @@ public void loadDistrictsIntoRedisCacheAsync(List<DistrictEntity> districts) {
7679
}
7780

7881
public void loadDistrictsIntoRedisCache(List<DistrictEntity> districts) {
79-
if(!CollectionUtils.isEmpty(districts)) {
82+
if(!isCacheLoading(CacheKey.DISTRICT_CACHE) && !CollectionUtils.isEmpty(districts)) {
83+
setCacheStateLoading(CacheKey.DISTRICT_CACHE);
8084
long start = System.currentTimeMillis();
8185
log.debug("****Before loading districts into cache");
8286
districtRedisRepository.saveAll(districts);
8387
log.info("{} Districts Loaded into cache in {} ms.", districts.size(), (System.currentTimeMillis() - start));
88+
setCacheReadiness(CacheKey.DISTRICT_CACHE);
8489
}
8590
}
8691

@@ -92,26 +97,46 @@ public void loadSchoolCategoryCodesIntoRedisCacheAsync(List<SchoolCategoryCodeEn
9297
}
9398

9499
public void loadSchoolCategoryCodesIntoRedisCache(List<SchoolCategoryCodeEntity> schoolCategoryCodes) {
95-
if(!CollectionUtils.isEmpty(schoolCategoryCodes)) {
100+
if(!isCacheLoading(CacheKey.SCHOOL_CATEGORY_CODE_CACHE) && !CollectionUtils.isEmpty(schoolCategoryCodes)) {
96101
long start = System.currentTimeMillis();
97102
log.debug("****Before loading School Category Codes into cache");
103+
setCacheStateLoading(CacheKey.SCHOOL_CATEGORY_CODE_CACHE);
98104
schoolCategoryCodeRedisRepository.saveAll(schoolCategoryCodes);
99105
log.info("{} School Category Codes Loaded into cache in {} ms.", schoolCategoryCodes.size(), (System.currentTimeMillis() - start));
106+
setCacheReadiness(CacheKey.SCHOOL_CATEGORY_CODE_CACHE);
100107
}
101108
}
102109

103110
@Async("taskExecutor")
104111
public void loadSchoolFundingGroupCodesIntoRedisCacheAsync(List<SchoolFundingGroupCodeEntity> schoolFundingGroupCodes) {
105-
loadSchoolFundingGroupCodesIntoRedisCache(schoolFundingGroupCodes);
112+
if(!CollectionUtils.isEmpty(schoolFundingGroupCodes)) {
113+
loadSchoolFundingGroupCodesIntoRedisCache(schoolFundingGroupCodes);
114+
}
106115
}
107116

108117
public void loadSchoolFundingGroupCodesIntoRedisCache(List<SchoolFundingGroupCodeEntity> schoolFundingGroupCodes) {
109-
if(!CollectionUtils.isEmpty(schoolFundingGroupCodes)) {
118+
if(!isCacheLoading(CacheKey.SCHOOL_FUNDING_GROUP_CODE_CACHE) && !CollectionUtils.isEmpty(schoolFundingGroupCodes)) {
110119
long start = System.currentTimeMillis();
111120
log.debug("****Before loading School Funding Group Codes into cache");
121+
setCacheStateLoading(CacheKey.SCHOOL_FUNDING_GROUP_CODE_CACHE);
112122
schoolFundingGroupCodeRedisRepository.saveAll(schoolFundingGroupCodes);
113123
log.info("{} School Funding Group Codes Loaded into cache in {} ms.", schoolFundingGroupCodes.size(), (System.currentTimeMillis() - start));
124+
setCacheReadiness(CacheKey.SCHOOL_FUNDING_GROUP_CODE_CACHE);
114125
}
115126
}
116127

128+
private boolean isCacheLoading(CacheKey cacheKey) {
129+
String cacheStatus = jedisCluster.get(cacheKey.name());
130+
return CacheStatus.LOADING.name().equals(cacheStatus);
131+
}
132+
133+
private void setCacheStateLoading(CacheKey cacheKey) {
134+
jedisCluster.set(cacheKey.name(), CacheStatus.LOADING.name());
135+
}
136+
137+
private void setCacheReadiness(CacheKey cacheKey) {
138+
jedisCluster.set(cacheKey.name(), CacheStatus.READY.name());
139+
log.info(String.format("Success! - %s is now READY", cacheKey));
140+
}
141+
117142
}

api/src/main/java/ca/bc/gov/educ/api/trax/service/institute/CodeService.java

+25-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package ca.bc.gov.educ.api.trax.service.institute;
22

33
import ca.bc.gov.educ.api.trax.constant.CacheKey;
4+
import ca.bc.gov.educ.api.trax.exception.ServiceException;
45
import ca.bc.gov.educ.api.trax.model.dto.institute.SchoolCategoryCode;
6+
import ca.bc.gov.educ.api.trax.model.dto.institute.SchoolDetail;
57
import ca.bc.gov.educ.api.trax.model.dto.institute.SchoolFundingGroupCode;
68
import ca.bc.gov.educ.api.trax.model.entity.institute.SchoolCategoryCodeEntity;
79
import ca.bc.gov.educ.api.trax.model.entity.institute.SchoolFundingGroupCodeEntity;
@@ -48,7 +50,7 @@ public class CodeService {
4850

4951
public List<SchoolCategoryCode> getSchoolCategoryCodesFromInstituteApi() {
5052
try {
51-
log.debug("****Before Calling Institute API");
53+
log.debug("****Before Calling Institute API for SchoolCategoryCode");
5254
List<SchoolCategoryCodeEntity> response = this.restService.get(constants.getAllSchoolCategoryCodesFromInstituteApiUrl(),
5355
List.class, webClient);
5456
return schoolCategoryCodeTransformer.transformToDTO(response);
@@ -75,13 +77,20 @@ public void loadSchoolCategoryCodesIntoRedisCache(List<SchoolCategoryCode> schoo
7577
}
7678

7779
public SchoolCategoryCode getSchoolCategoryCodeFromRedisCache(String schoolCategoryCode) {
78-
log.debug("**** Getting school category codes from Redis Cache.");
80+
log.debug("**** Getting school category codes from Redis Cache for : {}.", schoolCategoryCode);
7981
return schoolCategoryCodeRedisRepository.findById(schoolCategoryCode)
8082
.map(schoolCategoryCodeTransformer::transformToDTO)
81-
.orElseGet(() -> getSchoolCategoryCodesFromInstituteApi().stream()
82-
.filter(schoolCategoryCode1 -> schoolCategoryCode1.getSchoolCategoryCode().equals(schoolCategoryCode))
83-
.findFirst()
84-
.orElse(null));
83+
.orElseGet(() -> {
84+
SchoolCategoryCode schoolCategory = getSchoolCategoryCodesFromInstituteApi().stream()
85+
.filter(schoolCategoryCode1 -> schoolCategoryCode1.getSchoolCategoryCode().equals(schoolCategoryCode))
86+
.findFirst()
87+
.orElse(null);
88+
if(schoolCategory != null) {
89+
updateSchoolCategoryCode(schoolCategory);
90+
}
91+
return schoolCategory;
92+
93+
});
8594
}
8695

8796
public List<SchoolCategoryCode> getSchoolCategoryCodesFromRedisCache() {
@@ -96,7 +105,7 @@ public void initializeSchoolCategoryCodeCache(boolean force) {
96105

97106
public List<SchoolFundingGroupCode> getSchoolFundingGroupCodesFromInstituteApi() {
98107
try {
99-
log.debug("****Before Calling Institute API");
108+
log.debug("****Before Calling Institute API for SchoolFundingGroupCode");
100109
List<SchoolFundingGroupCodeEntity> response = this.restService.get(constants.getAllSchoolFundingGroupCodesFromInstituteApiUrl(),
101110
List.class, webClient);
102111
return schoolFundingGroupCodeTransformer.transformToDTO(response);
@@ -131,4 +140,13 @@ public List<SchoolFundingGroupCode> getSchoolFundingGroupCodesFromRedisCache() {
131140
public void initializeSchoolFundingGroupCodeCache(boolean force) {
132141
serviceHelper.initializeCache(force, CacheKey.SCHOOL_FUNDING_GROUP_CODE_CACHE, this);
133142
}
143+
144+
/**
145+
* Updates the school category code in the cache
146+
* @param schoolCategoryCode the school detail object
147+
*/
148+
public void updateSchoolCategoryCode(SchoolCategoryCode schoolCategoryCode) throws ServiceException {
149+
schoolCategoryCodeRedisRepository.save(schoolCategoryCodeTransformer.transformToEntity(schoolCategoryCode));
150+
}
151+
134152
}

api/src/main/java/ca/bc/gov/educ/api/trax/service/institute/SchoolService.java

+26-24
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
import ca.bc.gov.educ.api.trax.service.RESTService;
1414
import ca.bc.gov.educ.api.trax.util.EducGradTraxApiConstants;
1515
import ca.bc.gov.educ.api.trax.model.dto.institute.PaginatedResponse;
16+
import ca.bc.gov.educ.api.trax.util.JsonUtil;
1617
import ca.bc.gov.educ.api.trax.util.ThreadLocalStateUtil;
18+
import com.fasterxml.jackson.core.type.TypeReference;
19+
import com.fasterxml.jackson.databind.DeserializationFeature;
20+
import com.fasterxml.jackson.databind.ObjectMapper;
1721
import com.google.common.base.Strings;
1822
import lombok.RequiredArgsConstructor;
1923
import lombok.extern.slf4j.Slf4j;
@@ -25,10 +29,12 @@
2529
import org.springframework.util.CollectionUtils;
2630
import org.springframework.web.reactive.function.client.WebClient;
2731
import org.springframework.web.reactive.function.client.WebClientResponseException;
32+
import org.springframework.web.util.UriBuilder;
2833
import reactor.core.publisher.Flux;
2934
import reactor.core.publisher.Mono;
3035

3136
import java.util.*;
37+
import java.util.stream.Collectors;
3238

3339
@Slf4j
3440
@RequiredArgsConstructor
@@ -55,6 +61,8 @@ public class SchoolService {
5561
@Autowired
5662
CacheService cacheService;
5763

64+
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
65+
5866
public List<School> getSchoolsFromRedisCache() {
5967
log.debug("**** Getting schools from Redis Cache.");
6068
List<School> schools = schoolTransformer.transformToDTO(schoolRedisRepository.findAll());
@@ -134,45 +142,39 @@ public SchoolDetail getSchoolDetailByIdFromInstituteApi(String schoolId) {
134142
return null;
135143
}
136144

137-
private Mono<PaginatedResponse<SchoolDetail>> getSchoolDetailsPaginatedFromInstituteApi(int pageNumber) {
145+
private PaginatedResponse<SchoolDetail> getSchoolDetailsPaginatedFromInstituteApi(int pageNumber) {
138146
int pageSize = 1000;
139147
try {
140-
return this.webClient.get()
141-
.uri(constants.getSchoolsPaginatedFromInstituteApiUrl(),
142-
uri -> uri.queryParam("pageNumber", pageNumber)
143-
.queryParam("pageSize", pageSize)
144-
.build())
145-
.headers(h -> {
146-
h.set(EducGradTraxApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID());
147-
}) .retrieve()
148-
.bodyToMono(new ParameterizedTypeReference<>() {
149-
});
148+
return this.restService.get(String.format(constants.getSchoolsPaginatedFromInstituteApiUrl()+"?pageNumber=%d&pageSize=%d", pageNumber, pageSize),
149+
PaginatedResponse.class, webClient);
150150
} catch (WebClientResponseException e) {
151151
log.warn(String.format("Error getting School Details from Institute API: %s", e.getMessage()));
152152
} catch (Exception e) {
153153
log.error(String.format("Error while calling institute-api: %s", e.getMessage()));
154154
}
155155
log.warn("No school details found for the given search criteria.");
156-
return Mono.empty();
156+
return null;
157157
}
158158

159159
// Recursive method to fetch school details page by page
160-
public Mono<List<SchoolDetail>> getSchoolDetailsPaginatedFromInstituteApi() {
161-
return getSchoolDetailsPaginatedFromInstituteApi(0)
162-
.expand(response -> {
163-
if (response.hasNext()) {
164-
return getSchoolDetailsPaginatedFromInstituteApi(response.nextPageable().getPageNumber());
165-
}
166-
return Mono.empty();
167-
})
168-
.flatMap(response -> Flux.fromIterable(response.getContent()))
169-
.collectList();
160+
public List<SchoolDetail> getSchoolDetailsPaginatedFromInstituteApi(int pageNumber, List<SchoolDetail> schoolDetails) {
161+
PaginatedResponse response = getSchoolDetailsPaginatedFromInstituteApi(pageNumber);
162+
if (response == null) {
163+
return schoolDetails;
164+
}
165+
schoolDetails.addAll(response.getContent().stream()
166+
.map(entry -> mapper.convertValue(entry, SchoolDetail.class))
167+
.toList());
168+
169+
if (response.hasNext()) {
170+
return getSchoolDetailsPaginatedFromInstituteApi(response.nextPageable().getPageNumber(), schoolDetails);
171+
}
172+
return schoolDetails;
170173
}
171174

172175
public List<SchoolDetail> getSchoolDetailsFromInstituteApi() {
173176
log.debug("****Before Calling Institute API for school details");
174-
List<SchoolDetail> test = getSchoolDetailsPaginatedFromInstituteApi().block();
175-
return test;
177+
return getSchoolDetailsPaginatedFromInstituteApi(0, new ArrayList<>());
176178
}
177179

178180
public List<SchoolDetail> loadSchoolDetailsFromInstituteApiIntoRedisCacheAsync() {

api/src/main/java/ca/bc/gov/educ/api/trax/service/institute/ServiceHelper.java

-7
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,7 @@ public void initializeCache(boolean force, CacheKey cacheKey, T service) {
3737
}
3838

3939
private void loadCache(CacheKey cacheKey, T service) {
40-
jedisCluster.set(cacheKey.name(), CacheStatus.LOADING.name());
4140
loadDataIntoRedisCache(cacheKey, service);
42-
jedisCluster.set(cacheKey.name(), CacheStatus.READY.name());
43-
log.info(String.format("Success! - %s is now READY", cacheKey));
4441
}
4542

4643
private void loadDataIntoRedisCache(CacheKey cacheKey, T service) {
@@ -51,21 +48,18 @@ private void loadDataIntoRedisCache(CacheKey cacheKey, T service) {
5148
if(!CollectionUtils.isEmpty(schoolCategoryCodes)) {
5249
((CodeService)service).loadSchoolCategoryCodesIntoRedisCache(schoolCategoryCodes);
5350
}
54-
break;
5551
}
5652
case SCHOOL_FUNDING_GROUP_CODE_CACHE -> {
5753
List<SchoolFundingGroupCode> schoolFundingGroupCodes = ((CodeService)service).getSchoolFundingGroupCodesFromInstituteApi();
5854
if(!CollectionUtils.isEmpty(schoolFundingGroupCodes)) {
5955
((CodeService)service).loadSchoolFundingGroupCodesIntoRedisCache(schoolFundingGroupCodes);
6056
}
61-
break;
6257
}
6358
case DISTRICT_CACHE -> {
6459
List<District> districts = ((DistrictService)service).getDistrictsFromInstituteApi();
6560
if(!CollectionUtils.isEmpty(districts)) {
6661
((DistrictService) service).loadDistrictsIntoRedisCache(districts);
6762
}
68-
break;
6963
}
7064
case SCHOOL_CACHE -> {
7165
List<School> schools = ((SchoolService)service).getSchoolsFromInstituteApi();
@@ -76,7 +70,6 @@ private void loadDataIntoRedisCache(CacheKey cacheKey, T service) {
7670
if(!CollectionUtils.isEmpty(schoolDetails)) {
7771
((SchoolService) service).loadSchoolDetailsIntoRedisCache(schoolDetails);
7872
}
79-
break;
8073
}
8174
default -> {
8275
log.info(String.format("Invalid Cache Key %s", cacheKey));

0 commit comments

Comments
 (0)