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

Changes to place fallback for v2 calls. #428

Open
wants to merge 11 commits into
base: grad-release
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.security.oauth2.client.*;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction;
Expand All @@ -26,6 +28,7 @@
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;

@EnableAsync
@Configuration
@Profile("!test")
public class GradTraxConfig {
Expand Down Expand Up @@ -125,5 +128,16 @@ public LockProvider lockProvider(@Autowired JdbcTemplate jdbcTemplate, @Autowire
return new JdbcTemplateLockProvider(jdbcTemplate, transactionManager, "REPLICATION_SHEDLOCK");
}

/**
* Thread pool task scheduler thread pool task scheduler.
*
* @return the thread pool task scheduler
*/
@Bean(name = "taskExecutor")
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
final ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(5);
return threadPoolTaskScheduler;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package ca.bc.gov.educ.api.trax.model.dto.institute;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.EqualsAndHashCode;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import java.util.ArrayList;
import java.util.List;

public class PaginatedResponse<T> extends PageImpl<T> {
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
public PaginatedResponse(@JsonProperty("content") List<T> content,
@JsonProperty("number") int number,
@JsonProperty("size") int size,
@JsonProperty("totalElements") Long totalElements,
@JsonProperty("pageable") JsonNode pageable,
@JsonProperty("last") boolean last,
@JsonProperty("totalPages") int totalPages,
@JsonProperty("sort") JsonNode sort,
@JsonProperty("first") boolean first,
@JsonProperty("empty") boolean empty) {

super(content, PageRequest.of(number, size), totalElements);
}

public PaginatedResponse(List<T> content, Pageable pageable, long total) {
super(content, pageable, total);
}

public PaginatedResponse(List<T> content) {
super(content);
}

public PaginatedResponse() {
super(new ArrayList<>());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package ca.bc.gov.educ.api.trax.service.institute;

import ca.bc.gov.educ.api.trax.model.entity.institute.*;
import ca.bc.gov.educ.api.trax.repository.redis.*;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;

@Slf4j
@RequiredArgsConstructor
@Service("cacheService")
public class CacheService {

@Autowired
SchoolRedisRepository schoolRedisRepository;

@Autowired
SchoolDetailRedisRepository schoolDetailRedisRepository;

@Autowired
DistrictRedisRepository districtRedisRepository;

@Autowired
SchoolCategoryCodeRedisRepository schoolCategoryCodeRedisRepository;

@Autowired
SchoolFundingGroupCodeRedisRepository schoolFundingGroupCodeRedisRepository;

@Async("taskExecutor")
public void loadSchoolsIntoRedisCacheAsync(List<SchoolEntity> schools) {
if(!CollectionUtils.isEmpty(schools)) {
loadSchoolsIntoRedisCache(schools);
}
}

public void loadSchoolsIntoRedisCache(List<SchoolEntity> schools) {
if(!CollectionUtils.isEmpty(schools)) {
long start = System.currentTimeMillis();
log.debug("****Before loading schools into cache");
for (List<SchoolEntity> partition : Lists.partition(schools, 1000)) {
schoolRedisRepository.saveAll(partition);
}
log.info("{} Schools Loaded into cache in {} ms.", schools.size(), (System.currentTimeMillis() - start));
}
}

@Async("taskExecutor")
public void loadSchoolDetailsIntoRedisCacheAsync(List<SchoolDetailEntity> schoolDetails) {
if(!CollectionUtils.isEmpty(schoolDetails)) {
loadSchoolDetailsIntoRedisCache(schoolDetails);
}
}

public void loadSchoolDetailsIntoRedisCache(List<SchoolDetailEntity> schoolDetails) {
if(!CollectionUtils.isEmpty(schoolDetails)) {
long start = System.currentTimeMillis();
log.debug("****Before loading school details into cache");
for (List<SchoolDetailEntity> partition : Lists.partition(schoolDetails, 1000)) {
schoolDetailRedisRepository.saveAll(partition);
}
log.info("{} School Details Loaded into cache in {} ms.", schoolDetails.size(), (System.currentTimeMillis() - start));
}
}

@Async("taskExecutor")
public void loadDistrictsIntoRedisCacheAsync(List<DistrictEntity> districts) {
if(!CollectionUtils.isEmpty(districts)) {
loadDistrictsIntoRedisCache(districts);
}
}

public void loadDistrictsIntoRedisCache(List<DistrictEntity> districts) {
if(!CollectionUtils.isEmpty(districts)) {
long start = System.currentTimeMillis();
log.debug("****Before loading districts into cache");
districtRedisRepository.saveAll(districts);
log.info("{} Districts Loaded into cache in {} ms.", districts.size(), (System.currentTimeMillis() - start));
}
}

@Async("taskExecutor")
public void loadSchoolCategoryCodesIntoRedisCacheAsync(List<SchoolCategoryCodeEntity> schoolCategoryCodes) {
if(!CollectionUtils.isEmpty(schoolCategoryCodes)) {
loadSchoolCategoryCodesIntoRedisCache(schoolCategoryCodes);
}
}

public void loadSchoolCategoryCodesIntoRedisCache(List<SchoolCategoryCodeEntity> schoolCategoryCodes) {
if(!CollectionUtils.isEmpty(schoolCategoryCodes)) {
long start = System.currentTimeMillis();
log.debug("****Before loading School Category Codes into cache");
schoolCategoryCodeRedisRepository.saveAll(schoolCategoryCodes);
log.info("{} School Category Codes Loaded into cache in {} ms.", schoolCategoryCodes.size(), (System.currentTimeMillis() - start));
}
}

@Async("taskExecutor")
public void loadSchoolFundingGroupCodesIntoRedisCacheAsync(List<SchoolFundingGroupCodeEntity> schoolFundingGroupCodes) {
loadSchoolFundingGroupCodesIntoRedisCache(schoolFundingGroupCodes);
}

public void loadSchoolFundingGroupCodesIntoRedisCache(List<SchoolFundingGroupCodeEntity> schoolFundingGroupCodes) {
if(!CollectionUtils.isEmpty(schoolFundingGroupCodes)) {
long start = System.currentTimeMillis();
log.debug("****Before loading School Funding Group Codes into cache");
schoolFundingGroupCodeRedisRepository.saveAll(schoolFundingGroupCodes);
log.info("{} School Funding Group Codes Loaded into cache in {} ms.", schoolFundingGroupCodes.size(), (System.currentTimeMillis() - start));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;

import java.util.Collections;
import java.util.List;

@Slf4j
Expand All @@ -41,6 +43,8 @@ public class CodeService {
ServiceHelper<CodeService> serviceHelper;
@Autowired
RESTService restService;
@Autowired
CacheService cacheService;

public List<SchoolCategoryCode> getSchoolCategoryCodesFromInstituteApi() {
try {
Expand All @@ -53,23 +57,37 @@ public List<SchoolCategoryCode> getSchoolCategoryCodesFromInstituteApi() {
} catch (Exception e) {
log.error(String.format("Error while calling school-api: %s", e.getMessage()));
}
return null;
return Collections.emptyList();
}

public List<SchoolCategoryCode> loadSchoolCategoryCodesFromInstituteApiIntoRedisCacheAsync() {
List<SchoolCategoryCode> schoolCategoryCodes = getSchoolCategoryCodesFromInstituteApi();
if(!CollectionUtils.isEmpty(schoolCategoryCodes)) {
cacheService.loadSchoolCategoryCodesIntoRedisCacheAsync(schoolCategoryCodeTransformer.transformToEntity(schoolCategoryCodes));
}
return schoolCategoryCodes;
}

public void loadSchoolCategoryCodesIntoRedisCache(List<SchoolCategoryCode> schoolCategoryCodes) {
schoolCategoryCodeRedisRepository
.saveAll(schoolCategoryCodeTransformer.transformToEntity(schoolCategoryCodes));
log.info(String.format("%s School Category Codes Loaded into cache.", schoolCategoryCodes.size()));
if(!CollectionUtils.isEmpty(schoolCategoryCodes)) {
cacheService.loadSchoolCategoryCodesIntoRedisCache(schoolCategoryCodeTransformer.transformToEntity(schoolCategoryCodes));
}
}

public SchoolCategoryCode getSchoolCategoryCodeFromRedisCache(String schoolCategoryCode) {
log.debug("**** Getting school category codes from Redis Cache.");
return schoolCategoryCodeTransformer.transformToDTO(schoolCategoryCodeRedisRepository.findById(schoolCategoryCode));
return schoolCategoryCodeRedisRepository.findById(schoolCategoryCode)
.map(schoolCategoryCodeTransformer::transformToDTO)
.orElseGet(() -> getSchoolCategoryCodesFromInstituteApi().stream()
.filter(schoolCategoryCode1 -> schoolCategoryCode1.getSchoolCategoryCode().equals(schoolCategoryCode))
.findFirst()
.orElse(null));
}

public List<SchoolCategoryCode> getSchoolCategoryCodesFromRedisCache() {
log.debug("**** Getting school category codes from Redis Cache.");
return schoolCategoryCodeTransformer.transformToDTO(schoolCategoryCodeRedisRepository.findAll());
List<SchoolCategoryCode> schoolCategoryCodes = schoolCategoryCodeTransformer.transformToDTO(schoolCategoryCodeRedisRepository.findAll());
return CollectionUtils.isEmpty(schoolCategoryCodes) ? loadSchoolCategoryCodesFromInstituteApiIntoRedisCacheAsync() : schoolCategoryCodes;
}

public void initializeSchoolCategoryCodeCache(boolean force) {
Expand All @@ -87,18 +105,27 @@ public List<SchoolFundingGroupCode> getSchoolFundingGroupCodesFromInstituteApi()
} catch (Exception e) {
log.error(String.format("Error while calling school-api: %s", e.getMessage()));
}
return null;
return Collections.emptyList();
}

public List<SchoolFundingGroupCode> loadSchoolFundingGroupCodesFromInstituteApiIntoRedisCacheAsync() {
List<SchoolFundingGroupCode> schoolFundingGroupCodes = getSchoolFundingGroupCodesFromInstituteApi();
if(!CollectionUtils.isEmpty(schoolFundingGroupCodes)) {
cacheService.loadSchoolFundingGroupCodesIntoRedisCacheAsync(schoolFundingGroupCodeTransformer.transformToEntity(schoolFundingGroupCodes));
}
return schoolFundingGroupCodes;
}

public void loadSchoolFundingGroupCodesIntoRedisCache(List<SchoolFundingGroupCode> schoolFundingGroupCodes) {
schoolFundingGroupCodeRedisRepository
.saveAll(schoolFundingGroupCodeTransformer.transformToEntity(schoolFundingGroupCodes));
log.info(String.format("%s School Funding Group Codes Loaded into cache.", schoolFundingGroupCodes.size()));
if(!CollectionUtils.isEmpty(schoolFundingGroupCodes)) {
cacheService.loadSchoolFundingGroupCodesIntoRedisCache(schoolFundingGroupCodeTransformer.transformToEntity(schoolFundingGroupCodes));
}
}

public List<SchoolFundingGroupCode> getSchoolFundingGroupCodesFromRedisCache() {
log.debug("**** Getting school funding group codes from Redis Cache.");
return schoolFundingGroupCodeTransformer.transformToDTO(schoolFundingGroupCodeRedisRepository.findAll());
List<SchoolFundingGroupCode> schoolFundingGroupCodes = schoolFundingGroupCodeTransformer.transformToDTO(schoolFundingGroupCodeRedisRepository.findAll());
return CollectionUtils.isEmpty(schoolFundingGroupCodes) ? loadSchoolFundingGroupCodesFromInstituteApiIntoRedisCacheAsync() : schoolFundingGroupCodes;
}

public void initializeSchoolFundingGroupCodeCache(boolean force) {
Expand Down
Loading
Loading