Skip to content

Commit

Permalink
GRAD2-2637 - Cache institute api data into Redis (#331)
Browse files Browse the repository at this point in the history
* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis

* GRAD2-2637 - Cache institute api data into Redis
  • Loading branch information
kamal-mohammed authored Jun 20, 2024
1 parent a5fa5dd commit 51381f5
Show file tree
Hide file tree
Showing 33 changed files with 1,262 additions and 217 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,12 @@ public class CacheInitializer implements CommandLineRunner {

@Override
public void run(String... args) {
schoolService.loadSchoolsIntoRedisCache(
schoolService.getSchoolsFromInstituteApi()
);
log.info("Institutes loaded into Redis");

districtService.loadDistrictsIntoRedisCache(
districtService.getDistrictsFromInstituteApi()
);
log.info("Districts loaded into Redis");

codeService.loadSchoolCategoryCodesIntoRedisCache(
codeService.getSchoolCategoryCodesFromInstituteApi()
);
log.info("School Category Codes loaded into Redis");
codeService.loadSchoolFundingGroupCodesIntoRedisCache(
codeService.getSchoolFundingGroupCodesFromInstituteApi()
);
log.info("School Funding Group Codes loaded into Redis");
schoolService.initializeSchoolCache(false);
districtService.initializeDistrictCache(false);
codeService.initializeSchoolCategoryCodeCache(false);
codeService.initializeSchoolFundingGroupCodeCache(false);
schoolService.initializeSchoolDetailCache(false);

log.info("Redis Cache initialized!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
import org.springframework.security.oauth2.client.*;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
Expand Down Expand Up @@ -66,7 +64,23 @@ public WebClient getTraxClientWebClient(OAuth2AuthorizedClientManager authorized
.apply(filter.oauth2Configuration())
.build();
}
@Bean


@Bean("instituteWebClient")
public WebClient getInstituteWebClient(OAuth2AuthorizedClientManager authorizedClientManager) {
ServletOAuth2AuthorizedClientExchangeFilterFunction filter = new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
filter.setDefaultClientRegistrationId("institute-web-client");
return WebClient.builder()
.exchangeStrategies(ExchangeStrategies
.builder()
.codecs(codecs -> codecs
.defaultCodecs()
.maxInMemorySize(50 * 1024 * 1024))
.build())
.apply(filter.oauth2Configuration())
.build();
}
/*@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
Expand All @@ -76,9 +90,27 @@ public OAuth2AuthorizedClientManager authorizedClientManager(
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}*/

@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientService clientService) {

OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceOAuth2AuthorizedClientManager(clientRegistrationRepository, clientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

return authorizedClientManager;
}



@Bean
public WebClient webClient() {
//extend buffer to 50MB
Expand Down
14 changes: 14 additions & 0 deletions api/src/main/java/ca/bc/gov/educ/api/trax/config/RedisConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.Jedis;

@Configuration
@EnableRedisRepositories("ca.bc.gov.educ.api.trax.repository.redis")
Expand All @@ -22,6 +26,15 @@ public JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(constants.getRedisUrl());
redisStandaloneConfiguration.setPort(Integer.parseInt(constants.getRedisPort()));
redisStandaloneConfiguration.setPassword(constants.getRedisSecret());

//Cluster Configuration
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
RedisNode node0 = new RedisNode(constants.getRedisUrl(), Integer.parseInt(constants.getRedisPort()));
redisClusterConfiguration.addClusterNode(node0);

RedisClusterNode rcn = new RedisClusterNode(constants.getRedisUrl(), Integer.parseInt(constants.getRedisPort()));

return new JedisConnectionFactory(redisStandaloneConfiguration);
}

Expand All @@ -38,4 +51,5 @@ public RedisTemplate<String, Object> redisTemplate() {

return template;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ca.bc.gov.educ.api.trax.constant;

public enum CacheKey {
SCHOOL_CACHE, SCHOOL_DETAIL_CACHE, DISTRICT_CACHE, SCHOOL_CATEGORY_CODE_CACHE, SCHOOL_FUNDING_GROUP_CODE_CACHE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ca.bc.gov.educ.api.trax.constant;

public enum CacheStatus {
LOADING, READY
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
Expand All @@ -36,10 +34,6 @@ public class CodeController {

@Autowired
CodeService codeService;

@Autowired
GradValidation validation;

@Autowired
ResponseHelper response;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ public class DistrictController {

@Autowired
DistrictService districtService;

@Autowired
GradValidation validation;

@Autowired
ResponseHelper response;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ca.bc.gov.educ.api.trax.controller.v2;

import ca.bc.gov.educ.api.trax.model.dto.institute.School;
import ca.bc.gov.educ.api.trax.model.dto.institute.SchoolDetail;
import ca.bc.gov.educ.api.trax.service.institute.SchoolService;
import ca.bc.gov.educ.api.trax.util.EducGradTraxApiConstants;
import ca.bc.gov.educ.api.trax.util.GradValidation;
Expand All @@ -22,7 +23,7 @@
@CrossOrigin
@RestController("SchoolControllerV2")
@Slf4j
@OpenAPIDefinition(info = @Info(title = "API for School Data.", description = "This Read API is for Reading school data.", version = "1"),
@OpenAPIDefinition(info = @Info(title = "API for School Data.", description = "This Read API is for Reading school data from Redis Cache.", version = "2"),
security = {@SecurityRequirement(name = "OAUTH2", scopes = {"READ_GRAD_SCHOOL_DATA"})})
public class SchoolController {

Expand All @@ -39,11 +40,20 @@ public SchoolController(SchoolService schoolService, GradValidation validation,

@GetMapping(EducGradTraxApiConstants.GRAD_SCHOOL_URL_MAPPING_V2)
@PreAuthorize(PermissionsConstants.READ_SCHOOL_DATA)
@Operation(summary = "Find All Schools", description = "Get All Schools", tags = { "School" })
@Operation(summary = "Find All Schools from Cache", description = "Get All Schools from Cache", tags = { "School" })
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
public List<School> getAllSchools() {
log.debug("getAllSchools : ");
return schoolService.getSchoolsFromInstituteApi();
return schoolService.getSchoolsFromRedisCache();
}

@GetMapping(EducGradTraxApiConstants.GRAD_SCHOOL_DETAIL_URL_MAPPING_V2)
@PreAuthorize(PermissionsConstants.READ_SCHOOL_DATA)
@Operation(summary = "Find All School details from Cache", description = "Get All School details from Cache", tags = { "School" })
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
public List<SchoolDetail> getAllSchoolDetails() {
log.debug("getAllSchoolDetails : ");
return schoolService.getSchoolDetailsFromRedisCache();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package ca.bc.gov.educ.api.trax.exception;

import lombok.Data;

@Data
public class ServiceException extends RuntimeException {

private int statusCode;

public ServiceException() {
super();
}

public ServiceException(String message) {
super(message);
}

public ServiceException(String message, Throwable cause) {
super(message, cause);
}

public ServiceException(Throwable cause) {
super(cause);
}

protected ServiceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}

public ServiceException(String message, int value) {
super(message);
this.statusCode = value;
}

public ServiceException(String s, int value, Exception e) {
super(s, e);
this.statusCode = value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package ca.bc.gov.educ.api.trax.model.dto.institute;

import ca.bc.gov.educ.api.trax.model.dto.BaseModel;
import ca.bc.gov.educ.api.trax.model.dto.SchoolContact;
import ca.bc.gov.educ.api.trax.model.entity.institute.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.index.Indexed;
import org.springframework.stereotype.Component;

import java.util.List;

@Data
@EqualsAndHashCode(callSuper = true)
@Component("SchoolDetail")
public class SchoolDetail extends BaseModel {

private String schoolId;
private String districtId;
private String mincode;
private String independentAuthorityId;
private String schoolNumber;
private String faxNumber;
private String phoneNumber;
private String email;
private String website;
private String displayName;
private String displayNameNoSpecialChars;
private String schoolReportingRequirementCode;
private String schoolOrganizationCode;
private String schoolCategoryCode;
private String facilityTypeCode;
private String openedDate;
private String closedDate;
private boolean canIssueTranscripts;
private boolean canIssueCertificates;
private String createUser;
private String updateUser;
private String createDate;
private String updateDate;
List<SchoolContact> contacts;
List<SchoolAddress> addresses;
List<Note> notes;
List<Grade> grades;
List<SchoolFundingGroup> schoolFundingGroups;
List<NeighborhoodLearning> neighborhoodLearnings;
List<SchoolMove> schoolMoves;

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,12 @@ public class SchoolDetailEntity {
private String districtId;
@Indexed
private String mincode;
@Indexed
private String independentAuthorityId;
@Indexed
private String schoolNumber;
private String faxNumber;
private String phoneNumber;
private String email;
private String website;
@Indexed
private String displayName;
private String displayNameNoSpecialChars;
private String schoolReportingRequirementCode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,12 @@ public class SchoolEntity {
private String districtId;
@Indexed
private String mincode;
@Indexed
private String independentAuthorityId;
@Indexed
private String schoolNumber;
private String faxNumber;
private String phoneNumber;
private String email;
private String website;
@Indexed
private String displayName;
private String displayNameNoSpecialChars;
private String schoolReportingRequirementCode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import ca.bc.gov.educ.api.trax.model.dto.institute.District;
import ca.bc.gov.educ.api.trax.model.entity.institute.DistrictEntity;
import ca.bc.gov.educ.api.trax.model.entity.institute.SchoolDetailEntity;
import org.modelmapper.ModelMapper;
import org.modelmapper.TypeToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Component("InstituteDistrictTransformer")
public class DistrictTransformer {
Expand Down Expand Up @@ -36,7 +38,11 @@ public DistrictEntity transformToEntity(District district) {
return modelMapper.map(district, DistrictEntity.class);
}

public List<DistrictEntity> transformToEntity (Iterable<District> districts ) {
return modelMapper.map(districts, new TypeToken<List<DistrictEntity>>(){}.getType());
public List<DistrictEntity> transformToEntity (List<District> districts ) {
if (districts == null) return null;
return districts
.stream()
.map(district -> modelMapper.map(district, DistrictEntity.class))
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Component("SchoolCategoryCodeTransformer")
public class SchoolCategoryCodeTransformer {
Expand Down Expand Up @@ -36,7 +37,11 @@ public SchoolCategoryCodeEntity transformToEntity(SchoolCategoryCode schoolCateg
return modelMapper.map(schoolCategoryCode, SchoolCategoryCodeEntity.class);
}

public List<SchoolCategoryCodeEntity> transformToEntity (Iterable<SchoolCategoryCode> schoolCategoryCodes ) {
return modelMapper.map(schoolCategoryCodes, new TypeToken<List<SchoolCategoryCodeEntity>>(){}.getType());
public List<SchoolCategoryCodeEntity> transformToEntity (List<SchoolCategoryCode> schoolCategoryCodes ) {
if (schoolCategoryCodes == null) return null;
return schoolCategoryCodes
.stream()
.map(scc -> modelMapper.map(scc, SchoolCategoryCodeEntity.class))
.collect(Collectors.toList());
}
}
Loading

0 comments on commit 51381f5

Please sign in to comment.