Skip to content

Commit 904ed9a

Browse files
authored
feat: in-memory cache (#38)
* Add signature creation for empty list responses * Added caching to services * Checkstyle fixes * Fixed JUnit tests
1 parent 356d8bc commit 904ed9a

8 files changed

Lines changed: 82 additions & 20 deletions

File tree

src/main/java/eu/europa/ec/dgc/businessrule/DgcBusinessRuleServiceApplication.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@
2626
import org.springframework.boot.autoconfigure.SpringBootApplication;
2727
import org.springframework.boot.context.properties.EnableConfigurationProperties;
2828
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
29+
import org.springframework.cache.annotation.EnableCaching;
2930

3031
/**
3132
* The Application class.
3233
*/
3334
@SpringBootApplication
35+
@EnableCaching
3436
@EnableConfigurationProperties({DgcConfigProperties.class, JksSigningConfig.class})
3537
public class DgcBusinessRuleServiceApplication extends SpringBootServletInitializer {
3638

src/main/java/eu/europa/ec/dgc/businessrule/service/BusinessRuleService.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@
3535
import java.util.Locale;
3636
import java.util.Optional;
3737
import java.util.stream.Collectors;
38+
import javax.annotation.PostConstruct;
3839
import lombok.RequiredArgsConstructor;
3940
import lombok.extern.slf4j.Slf4j;
41+
import org.springframework.cache.annotation.CacheEvict;
42+
import org.springframework.cache.annotation.Cacheable;
4043
import org.springframework.stereotype.Service;
4144
import org.springframework.transaction.annotation.Transactional;
4245

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

5457
private final BusinessRulesUtils businessRulesUtils;
5558

59+
/**
60+
* Creates the signature for the empty rules list after start up.
61+
*/
62+
@PostConstruct
63+
@Transactional
64+
public void businessRuleServiceInit() {
65+
listSigningService.updateSignedList(getBusinessRulesList(),ListType.Rules);
66+
}
67+
5668
/**
5769
* Gets list of all business rules ids and hashes.
5870
*
5971
*/
72+
@Cacheable("business_rules")
6073
public List<BusinessRuleListItemDto> getBusinessRulesList() {
61-
74+
log.debug("Get Rules list executed.");
6275
List<BusinessRuleListItemDto> rulesItems = businessRuleRepository.findAllByOrderByIdentifierAsc();
6376
return rulesItems;
6477
}
6578

79+
@Cacheable("business_rules")
6680
public Optional<SignedListEntity> getBusinessRulesSignedList() {
81+
log.debug("Get Rules list executed.");
6782
return signedListRepository.findById(ListType.Rules);
6883
}
6984

7085
/**
7186
* Gets list of all business rules ids and hashes for a country.
7287
*/
88+
@Cacheable("business_rules")
7389
public List<BusinessRuleListItemDto> getBusinessRulesListForCountry(String country) {
74-
90+
log.debug("Get Rules list for country ({}) executed.", country);
7591
List<BusinessRuleListItemDto> rulesItems =
7692
businessRuleRepository.findAllByCountryOrderByIdentifierAsc(country.toUpperCase(Locale.ROOT));
7793
return rulesItems;
7894
}
7995

8096
/**f
81-
* Gets a business rule by hash.
97+
* Gets a business rule by country and hash.
8298
*/
8399
@Transactional
100+
@Cacheable("business_rules")
84101
public BusinessRuleEntity getBusinessRuleByCountryAndHash(String country, String hash) {
85-
102+
log.debug("Get rule for country ({}) and hash ({}) executed.", country, hash);
86103
return businessRuleRepository.findOneByCountryAndHash(country, hash);
87104
}
88105

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

157-
158175
/**
159176
* Gets a list of hash values of all stored business rules.
160177
* @return List of hash values

src/main/java/eu/europa/ec/dgc/businessrule/service/CountryListService.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import java.util.Optional;
2828
import lombok.RequiredArgsConstructor;
2929
import lombok.extern.slf4j.Slf4j;
30+
import org.springframework.cache.annotation.CacheEvict;
31+
import org.springframework.cache.annotation.Cacheable;
3032
import org.springframework.stereotype.Component;
3133
import org.springframework.transaction.annotation.Transactional;
3234

@@ -46,10 +48,13 @@ public class CountryListService {
4648
* @return the country list.
4749
*/
4850
@Transactional
51+
@Cacheable("country_list")
4952
public CountryListEntity getCountryList() {
53+
log.debug("Get country list executed");
5054
CountryListEntity cle = countryListRepository.getFirstById(COUNTRY_LIST_ID);
5155
if (cle == null) {
52-
cle = new CountryListEntity(COUNTRY_LIST_ID,"[]",null,null);
56+
cle = createCountryListEntity("[]");
57+
countryListRepository.save(cle);
5358
}
5459
return cle;
5560
}
@@ -60,20 +65,16 @@ public CountryListEntity getCountryList() {
6065
* @param newCountryListData new country list data
6166
*/
6267
@Transactional
68+
@CacheEvict(value = "country_list", allEntries = true)
6369
public void updateCountryList(String newCountryListData) {
6470
CountryListEntity oldList = getCountryList();
6571
if (!newCountryListData.equals(oldList.getRawData())) {
66-
saveCountryList(newCountryListData);
72+
countryListRepository.save(createCountryListEntity(newCountryListData));
6773
}
6874
}
6975

7076

71-
/**
72-
* Saves a country list by replacing an old one.
73-
* @param listData the country list to be saved.
74-
*/
75-
@Transactional
76-
public void saveCountryList(String listData) {
77+
private CountryListEntity createCountryListEntity(String listData) {
7778
CountryListEntity cle = new CountryListEntity(COUNTRY_LIST_ID,listData,null,null);
7879
try {
7980
cle.setHash(businessRulesUtils.calculateHash(listData));
@@ -83,10 +84,7 @@ public void saveCountryList(String listData) {
8384
if (signingService.isPresent()) {
8485
cle.setSignature(signingService.get().computeSignature(cle.getHash()));
8586
}
86-
countryListRepository.save(cle);
87+
return cle;
8788
}
8889

89-
90-
91-
9290
}

src/main/java/eu/europa/ec/dgc/businessrule/service/ValueSetService.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@
3434
import java.util.Map;
3535
import java.util.Optional;
3636
import java.util.stream.Collectors;
37+
import javax.annotation.PostConstruct;
3738
import lombok.RequiredArgsConstructor;
3839
import lombok.extern.slf4j.Slf4j;
40+
import org.springframework.cache.annotation.CacheEvict;
41+
import org.springframework.cache.annotation.Cacheable;
3942
import org.springframework.stereotype.Service;
4043
import org.springframework.transaction.annotation.Transactional;
4144

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

57+
/**
58+
* Creates the signature for the empty value sets list after start up.
59+
*/
60+
@PostConstruct
61+
@Transactional
62+
public void valueSetServiceInit() {
63+
listSigningService.updateSignedList(getValueSetsList(), ListType.ValueSets);
64+
}
65+
5466
/**
5567
* Gets list of all value set ids and hashes.
5668
*/
69+
@Cacheable("value_sets")
5770
public List<ValueSetListItemDto> getValueSetsList() {
58-
71+
log.debug("Get value sets list executed");
5972
List<ValueSetListItemDto> valueSetItems = valueSetRepository.findAllByOrderByIdAsc();
6073
return valueSetItems;
6174
}
6275

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

@@ -69,8 +84,9 @@ public Optional<SignedListEntity> getValueSetsSignedList() {
6984
* Gets a value set by its hash value.
7085
*/
7186
@Transactional
87+
@Cacheable("value_sets")
7288
public ValueSetEntity getValueSetByHash(String hash) {
73-
89+
log.debug("Get value set ({})executed", hash);
7490
return valueSetRepository.findOneByHash(hash);
7591
}
7692

@@ -79,6 +95,7 @@ public ValueSetEntity getValueSetByHash(String hash) {
7995
* @param valueSets list of actual value sets
8096
*/
8197
@Transactional
98+
@CacheEvict(value = "value_sets", allEntries = true)
8299
public void updateValueSets(List<ValueSetItem> valueSets) {
83100
List<String> valueSetsHashes = valueSets.stream().map(ValueSetItem::getHash).collect(Collectors.toList());
84101
List<String> alreadyStoredValueSets = getValueSetsHashList();

src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/BusinessRuleControllerIntegrationTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package eu.europa.ec.dgc.businessrule.restapi.controller;
22

33
import eu.europa.ec.dgc.businessrule.repository.BusinessRuleRepository;
4+
import eu.europa.ec.dgc.businessrule.service.BusinessRuleService;
45
import eu.europa.ec.dgc.businessrule.testdata.BusinessRulesTestHelper;
56
import eu.europa.ec.dgc.gateway.connector.DgcGatewayCountryListDownloadConnector;
67
import eu.europa.ec.dgc.gateway.connector.DgcGatewayValidationRuleDownloadConnector;
@@ -11,6 +12,7 @@
1112
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
1213
import org.springframework.boot.test.context.SpringBootTest;
1314
import org.springframework.boot.test.mock.mockito.MockBean;
15+
import org.springframework.cache.CacheManager;
1416
import org.springframework.http.MediaType;
1517
import org.springframework.test.web.servlet.MockMvc;
1618
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -35,16 +37,24 @@ class BusinessRuleControllerIntegrationTest {
3537
@Autowired
3638
BusinessRuleRepository businessRuleRepository;
3739

40+
@Autowired
41+
BusinessRuleService businessRuleService;
42+
3843
@Autowired
3944
BusinessRulesTestHelper businessRulesTestHelper;
4045

4146
@Autowired
4247
private MockMvc mockMvc;
4348

49+
@Autowired
50+
CacheManager cacheManager;
4451

4552
@BeforeEach
4653
void clearRepositoryData() {
54+
4755
businessRuleRepository.deleteAll();
56+
cacheManager.getCache("business_rules").clear();
57+
businessRuleService.businessRuleServiceInit();
4858
}
4959

5060
@Test

src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/CountryListControllerIntegrationTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
3232
import org.springframework.boot.test.context.SpringBootTest;
3333
import org.springframework.boot.test.mock.mockito.MockBean;
34+
import org.springframework.cache.CacheManager;
3435
import org.springframework.http.MediaType;
3536
import org.springframework.test.web.servlet.MockMvc;
3637
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -62,11 +63,14 @@ class CountryListControllerIntegrationTest {
6263
@BeforeEach
6364
void clearRepositoryData() {
6465
countryListRepository.deleteAll();
66+
cacheManager.getCache("country_list").clear();
6567
}
6668

6769
@Autowired
6870
private MockMvc mockMvc;
6971

72+
@Autowired
73+
CacheManager cacheManager;
7074

7175
@Test
7276
void getEmptyCountryList() throws Exception {

src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/ValueSetControllerIntegrationTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
3939
import org.springframework.boot.test.context.SpringBootTest;
4040
import org.springframework.boot.test.mock.mockito.MockBean;
41+
import org.springframework.cache.CacheManager;
4142
import org.springframework.http.MediaType;
4243
import org.springframework.test.web.servlet.MockMvc;
4344
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -78,10 +79,15 @@ class ValueSetControllerIntegrationTest {
7879
@Autowired
7980
private SignedListRepository signedListRepository;
8081

82+
@Autowired
83+
CacheManager cacheManager;
84+
8185
@BeforeEach
8286
void clearRepositoryData() {
8387
valueSetRepository.deleteAll();
8488
signedListRepository.deleteAll();
89+
cacheManager.getCache( "value_sets").clear();
90+
valueSetService.valueSetServiceInit();
8591
}
8692

8793
@Test
@@ -110,7 +116,7 @@ void getValueSetList() throws Exception {
110116
BusinessRulesTestHelper.VALUESET_IDENTIFIER_2,
111117
BusinessRulesTestHelper.VALUESET_DATA_2);
112118

113-
listSigningService.updateSignedList(valueSetService.getValueSetsList(), ListType.ValueSets);
119+
114120

115121
mockMvc.perform(get("/valuesets").header(API_VERSION_HEADER, "1.0"))
116122
.andExpect(status().isOk())

src/test/java/eu/europa/ec/dgc/businessrule/testdata/BusinessRulesTestHelper.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import eu.europa.ec.dgc.businessrule.entity.ValueSetEntity;
55
import eu.europa.ec.dgc.businessrule.repository.BusinessRuleRepository;
66
import eu.europa.ec.dgc.businessrule.repository.ValueSetRepository;
7+
import eu.europa.ec.dgc.businessrule.service.BusinessRuleService;
8+
import eu.europa.ec.dgc.businessrule.service.ValueSetService;
79
import lombok.RequiredArgsConstructor;
810
import org.springframework.stereotype.Service;
911

@@ -163,6 +165,10 @@ public class BusinessRulesTestHelper {
163165

164166
private final BusinessRuleRepository businessRuleRepository;
165167

168+
private final BusinessRuleService businessRuleService;
169+
170+
private final ValueSetService valueSetService;
171+
166172
public void insertBusinessRule(String hash, String identifier, String country, String version, String data) {
167173
BusinessRuleEntity bre = new BusinessRuleEntity();
168174
bre.setHash(hash);
@@ -172,6 +178,7 @@ public void insertBusinessRule(String hash, String identifier, String country, S
172178
bre.setRawData(data);
173179

174180
businessRuleRepository.save(bre);
181+
businessRuleService.businessRuleServiceInit();
175182
}
176183

177184

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

184191
valueSetRepository.save(vse);
192+
valueSetService.valueSetServiceInit();
185193

186194
}
187195
}

0 commit comments

Comments
 (0)