Skip to content

Commit

Permalink
feat: in-memory cache (#38)
Browse files Browse the repository at this point in the history
* Add signature creation for empty list responses

* Added caching to services

* Checkstyle fixes

* Fixed JUnit tests
  • Loading branch information
slaurenz authored Sep 27, 2021
1 parent 356d8bc commit 904ed9a
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;

/**
* The Application class.
*/
@SpringBootApplication
@EnableCaching
@EnableConfigurationProperties({DgcConfigProperties.class, JksSigningConfig.class})
public class DgcBusinessRuleServiceApplication extends SpringBootServletInitializer {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -53,36 +56,50 @@ public class BusinessRuleService {

private final BusinessRulesUtils businessRulesUtils;

/**
* Creates the signature for the empty rules list after start up.
*/
@PostConstruct
@Transactional
public void businessRuleServiceInit() {
listSigningService.updateSignedList(getBusinessRulesList(),ListType.Rules);
}

/**
* Gets list of all business rules ids and hashes.
*
*/
@Cacheable("business_rules")
public List<BusinessRuleListItemDto> getBusinessRulesList() {

log.debug("Get Rules list executed.");
List<BusinessRuleListItemDto> rulesItems = businessRuleRepository.findAllByOrderByIdentifierAsc();
return rulesItems;
}

@Cacheable("business_rules")
public Optional<SignedListEntity> getBusinessRulesSignedList() {
log.debug("Get Rules list executed.");
return signedListRepository.findById(ListType.Rules);
}

/**
* Gets list of all business rules ids and hashes for a country.
*/
@Cacheable("business_rules")
public List<BusinessRuleListItemDto> getBusinessRulesListForCountry(String country) {

log.debug("Get Rules list for country ({}) executed.", country);
List<BusinessRuleListItemDto> rulesItems =
businessRuleRepository.findAllByCountryOrderByIdentifierAsc(country.toUpperCase(Locale.ROOT));
return rulesItems;
}

/**f
* Gets a business rule by hash.
* Gets a business rule by country and hash.
*/
@Transactional
@Cacheable("business_rules")
public BusinessRuleEntity getBusinessRuleByCountryAndHash(String country, String hash) {

log.debug("Get rule for country ({}) and hash ({}) executed.", country, hash);
return businessRuleRepository.findOneByCountryAndHash(country, hash);
}

Expand All @@ -91,6 +108,7 @@ public BusinessRuleEntity getBusinessRuleByCountryAndHash(String country, String
* @param businessRules list of actual value sets
*/
@Transactional
@CacheEvict(value = "business_rules", allEntries = true)
public void updateBusinessRules(List<BusinessRuleItem> businessRules) {
List<String> ruleHashes =
businessRules.stream().map(BusinessRuleItem::getHash).collect(Collectors.toList());
Expand Down Expand Up @@ -154,7 +172,6 @@ public List<BusinessRuleItem> createBusinessRuleItemList(List<ValidationRule> va
return businessRuleItems;
}


/**
* Gets a list of hash values of all stored business rules.
* @return List of hash values
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -46,10 +48,13 @@ public class CountryListService {
* @return the country list.
*/
@Transactional
@Cacheable("country_list")
public CountryListEntity getCountryList() {
log.debug("Get country list executed");
CountryListEntity cle = countryListRepository.getFirstById(COUNTRY_LIST_ID);
if (cle == null) {
cle = new CountryListEntity(COUNTRY_LIST_ID,"[]",null,null);
cle = createCountryListEntity("[]");
countryListRepository.save(cle);
}
return cle;
}
Expand All @@ -60,20 +65,16 @@ public CountryListEntity getCountryList() {
* @param newCountryListData new country list data
*/
@Transactional
@CacheEvict(value = "country_list", allEntries = true)
public void updateCountryList(String newCountryListData) {
CountryListEntity oldList = getCountryList();
if (!newCountryListData.equals(oldList.getRawData())) {
saveCountryList(newCountryListData);
countryListRepository.save(createCountryListEntity(newCountryListData));
}
}


/**
* Saves a country list by replacing an old one.
* @param listData the country list to be saved.
*/
@Transactional
public void saveCountryList(String listData) {
private CountryListEntity createCountryListEntity(String listData) {
CountryListEntity cle = new CountryListEntity(COUNTRY_LIST_ID,listData,null,null);
try {
cle.setHash(businessRulesUtils.calculateHash(listData));
Expand All @@ -83,10 +84,7 @@ public void saveCountryList(String listData) {
if (signingService.isPresent()) {
cle.setSignature(signingService.get().computeSignature(cle.getHash()));
}
countryListRepository.save(cle);
return cle;
}




}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -51,16 +54,28 @@ public class ValueSetService {
private final SignedListRepository signedListRepository;
private final Optional<SigningService> signingService;

/**
* Creates the signature for the empty value sets list after start up.
*/
@PostConstruct
@Transactional
public void valueSetServiceInit() {
listSigningService.updateSignedList(getValueSetsList(), ListType.ValueSets);
}

/**
* Gets list of all value set ids and hashes.
*/
@Cacheable("value_sets")
public List<ValueSetListItemDto> getValueSetsList() {

log.debug("Get value sets list executed");
List<ValueSetListItemDto> valueSetItems = valueSetRepository.findAllByOrderByIdAsc();
return valueSetItems;
}

@Cacheable("value_sets")
public Optional<SignedListEntity> getValueSetsSignedList() {
log.debug("Get value sets list (SignedList) executed");
return signedListRepository.findById(ListType.ValueSets);
}

Expand All @@ -69,8 +84,9 @@ public Optional<SignedListEntity> getValueSetsSignedList() {
* Gets a value set by its hash value.
*/
@Transactional
@Cacheable("value_sets")
public ValueSetEntity getValueSetByHash(String hash) {

log.debug("Get value set ({})executed", hash);
return valueSetRepository.findOneByHash(hash);
}

Expand All @@ -79,6 +95,7 @@ public ValueSetEntity getValueSetByHash(String hash) {
* @param valueSets list of actual value sets
*/
@Transactional
@CacheEvict(value = "value_sets", allEntries = true)
public void updateValueSets(List<ValueSetItem> valueSets) {
List<String> valueSetsHashes = valueSets.stream().map(ValueSetItem::getHash).collect(Collectors.toList());
List<String> alreadyStoredValueSets = getValueSetsHashList();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package eu.europa.ec.dgc.businessrule.restapi.controller;

import eu.europa.ec.dgc.businessrule.repository.BusinessRuleRepository;
import eu.europa.ec.dgc.businessrule.service.BusinessRuleService;
import eu.europa.ec.dgc.businessrule.testdata.BusinessRulesTestHelper;
import eu.europa.ec.dgc.gateway.connector.DgcGatewayCountryListDownloadConnector;
import eu.europa.ec.dgc.gateway.connector.DgcGatewayValidationRuleDownloadConnector;
Expand All @@ -11,6 +12,7 @@
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.cache.CacheManager;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
Expand All @@ -35,16 +37,24 @@ class BusinessRuleControllerIntegrationTest {
@Autowired
BusinessRuleRepository businessRuleRepository;

@Autowired
BusinessRuleService businessRuleService;

@Autowired
BusinessRulesTestHelper businessRulesTestHelper;

@Autowired
private MockMvc mockMvc;

@Autowired
CacheManager cacheManager;

@BeforeEach
void clearRepositoryData() {

businessRuleRepository.deleteAll();
cacheManager.getCache("business_rules").clear();
businessRuleService.businessRuleServiceInit();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.cache.CacheManager;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
Expand Down Expand Up @@ -62,11 +63,14 @@ class CountryListControllerIntegrationTest {
@BeforeEach
void clearRepositoryData() {
countryListRepository.deleteAll();
cacheManager.getCache("country_list").clear();
}

@Autowired
private MockMvc mockMvc;

@Autowired
CacheManager cacheManager;

@Test
void getEmptyCountryList() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.cache.CacheManager;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
Expand Down Expand Up @@ -78,10 +79,15 @@ class ValueSetControllerIntegrationTest {
@Autowired
private SignedListRepository signedListRepository;

@Autowired
CacheManager cacheManager;

@BeforeEach
void clearRepositoryData() {
valueSetRepository.deleteAll();
signedListRepository.deleteAll();
cacheManager.getCache( "value_sets").clear();
valueSetService.valueSetServiceInit();
}

@Test
Expand Down Expand Up @@ -110,7 +116,7 @@ void getValueSetList() throws Exception {
BusinessRulesTestHelper.VALUESET_IDENTIFIER_2,
BusinessRulesTestHelper.VALUESET_DATA_2);

listSigningService.updateSignedList(valueSetService.getValueSetsList(), ListType.ValueSets);


mockMvc.perform(get("/valuesets").header(API_VERSION_HEADER, "1.0"))
.andExpect(status().isOk())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import eu.europa.ec.dgc.businessrule.entity.ValueSetEntity;
import eu.europa.ec.dgc.businessrule.repository.BusinessRuleRepository;
import eu.europa.ec.dgc.businessrule.repository.ValueSetRepository;
import eu.europa.ec.dgc.businessrule.service.BusinessRuleService;
import eu.europa.ec.dgc.businessrule.service.ValueSetService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

Expand Down Expand Up @@ -163,6 +165,10 @@ public class BusinessRulesTestHelper {

private final BusinessRuleRepository businessRuleRepository;

private final BusinessRuleService businessRuleService;

private final ValueSetService valueSetService;

public void insertBusinessRule(String hash, String identifier, String country, String version, String data) {
BusinessRuleEntity bre = new BusinessRuleEntity();
bre.setHash(hash);
Expand All @@ -172,6 +178,7 @@ public void insertBusinessRule(String hash, String identifier, String country, S
bre.setRawData(data);

businessRuleRepository.save(bre);
businessRuleService.businessRuleServiceInit();
}


Expand All @@ -182,6 +189,7 @@ public void insertValueSet(String hash, String identifier, String data) {
vse.setRawData(data);

valueSetRepository.save(vse);
valueSetService.valueSetServiceInit();

}
}

0 comments on commit 904ed9a

Please sign in to comment.