Skip to content

Commit 31b0ed0

Browse files
authored
framework/config,server: configkey caching (#9628)
Added caching for ConfigKey value retrievals based on the Caffeine in-memory caching library. https://github.com/ben-manes/caffeine Currently, expire time for a cache is 30s and each update of the config key invalidates the cache. On any update or reset of the configuration, cache automatically invalidates for it. Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 787acfd commit 31b0ed0

File tree

19 files changed

+255
-125
lines changed

19 files changed

+255
-125
lines changed

engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
import org.apache.cloudstack.context.CallContext;
4444
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
4545
import org.apache.cloudstack.framework.config.ConfigKey;
46-
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
4746
import org.apache.cloudstack.framework.config.impl.ConfigDepotImpl;
4847
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
4948
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
@@ -1256,12 +1255,10 @@ private void overrideVmMetadataConfigValue(final String manufacturer, final Stri
12561255
ConfigKey configKey = VirtualMachineManager.VmMetadataManufacturer;
12571256
this.configDepotImpl = (ConfigDepotImpl)ReflectionTestUtils.getField(configKey, "s_depot");
12581257
ConfigDepotImpl configDepot = Mockito.mock(ConfigDepotImpl.class);
1259-
ScopedConfigStorage storage = Mockito.mock(ScopedConfigStorage.class);
1260-
Mockito.when(storage.getConfigValue(Mockito.anyLong(), Mockito.eq(configKey))).thenReturn(manufacturer);
1261-
Mockito.when(storage.getConfigValue(Mockito.anyLong(), Mockito.eq(VirtualMachineManager.VmMetadataProductName)))
1262-
.thenReturn(product);
1263-
Mockito.when(configDepot.findScopedConfigStorage(configKey)).thenReturn(storage);
1264-
Mockito.when(configDepot.findScopedConfigStorage(VirtualMachineManager.VmMetadataProductName)).thenReturn(storage);
1258+
Mockito.when(configDepot.getConfigStringValue(Mockito.eq(configKey.key()),
1259+
Mockito.eq(ConfigKey.Scope.Zone), Mockito.anyLong())).thenReturn(manufacturer);
1260+
Mockito.when(configDepot.getConfigStringValue(Mockito.eq(VirtualMachineManager.VmMetadataProductName.key()),
1261+
Mockito.eq(ConfigKey.Scope.Zone), Mockito.anyLong())).thenReturn(product);
12651262
ReflectionTestUtils.setField(configKey, "s_depot", configDepot);
12661263
updatedConfigKeyDepot = true;
12671264
}

engine/schema/src/main/java/com/cloud/dc/ClusterDetailsDaoImpl.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.List;
2121
import java.util.Map;
2222

23-
2423
import org.apache.cloudstack.framework.config.ConfigKey;
2524
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
2625
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
@@ -136,8 +135,8 @@ public Scope getScope() {
136135
}
137136

138137
@Override
139-
public String getConfigValue(long id, ConfigKey<?> key) {
140-
ClusterDetailsVO vo = findDetail(id, key.key());
138+
public String getConfigValue(long id, String key) {
139+
ClusterDetailsVO vo = findDetail(id, key);
141140
return vo == null ? null : vo.getValue();
142141
}
143142

engine/schema/src/main/java/com/cloud/dc/dao/DataCenterDetailsDaoImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ public Scope getScope() {
4444
}
4545

4646
@Override
47-
public String getConfigValue(long id, ConfigKey<?> key) {
48-
ResourceDetail vo = findDetail(id, key.key());
47+
public String getConfigValue(long id, String key) {
48+
ResourceDetail vo = findDetail(id, key);
4949
return vo == null ? null : vo.getValue();
5050
}
5151

engine/schema/src/main/java/com/cloud/domain/dao/DomainDetailsDaoImpl.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222

2323
import javax.inject.Inject;
2424

25+
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
26+
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
27+
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
28+
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
29+
2530
import com.cloud.domain.DomainDetailVO;
2631
import com.cloud.domain.DomainVO;
2732
import com.cloud.utils.crypt.DBEncryptionUtil;
@@ -31,11 +36,6 @@
3136
import com.cloud.utils.db.SearchCriteria;
3237
import com.cloud.utils.db.SearchCriteria.Op;
3338
import com.cloud.utils.db.TransactionLegacy;
34-
import org.apache.cloudstack.framework.config.ConfigKey;
35-
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
36-
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
37-
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
38-
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
3939

4040
public class DomainDetailsDaoImpl extends GenericDaoBase<DomainDetailVO, Long> implements DomainDetailsDao, ScopedConfigStorage {
4141
protected final SearchBuilder<DomainDetailVO> domainSearch;
@@ -108,17 +108,17 @@ public Scope getScope() {
108108
}
109109

110110
@Override
111-
public String getConfigValue(long id, ConfigKey<?> key) {
111+
public String getConfigValue(long id, String key) {
112112
DomainDetailVO vo = null;
113113
String enableDomainSettingsForChildDomain = _configDao.getValue("enable.domain.settings.for.child.domain");
114114
if (!Boolean.parseBoolean(enableDomainSettingsForChildDomain)) {
115-
vo = findDetail(id, key.key());
115+
vo = findDetail(id, key);
116116
return vo == null ? null : getActualValue(vo);
117117
}
118118
DomainVO domain = _domainDao.findById(id);
119119
// if value is not configured in domain then check its parent domain till ROOT
120120
while (domain != null) {
121-
vo = findDetail(domain.getId(), key.key());
121+
vo = findDetail(domain.getId(), key);
122122
if (vo != null) {
123123
break;
124124
} else if (domain.getParent() != null) {

engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
package com.cloud.storage.dao;
1818

1919

20+
import java.util.List;
21+
22+
import javax.inject.Inject;
23+
2024
import org.apache.cloudstack.framework.config.ConfigKey;
2125
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
2226
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
@@ -26,9 +30,6 @@
2630
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
2731
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
2832

29-
import javax.inject.Inject;
30-
import java.util.List;
31-
3233
public class StoragePoolDetailsDaoImpl extends ResourceDetailsDaoBase<StoragePoolDetailVO> implements StoragePoolDetailsDao, ScopedConfigStorage {
3334

3435
@Inject
@@ -43,8 +44,8 @@ public Scope getScope() {
4344
}
4445

4546
@Override
46-
public String getConfigValue(long id, ConfigKey<?> key) {
47-
StoragePoolDetailVO vo = findDetail(id, key.key());
47+
public String getConfigValue(long id, String key) {
48+
StoragePoolDetailVO vo = findDetail(id, key);
4849
return vo == null ? null : vo.getValue();
4950
}
5051

engine/schema/src/main/java/com/cloud/user/AccountDetailsDaoImpl.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,24 @@
2323

2424
import javax.inject.Inject;
2525

26-
import com.cloud.utils.crypt.DBEncryptionUtil;
2726
import org.apache.cloudstack.framework.config.ConfigKey;
2827
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
2928
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
29+
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
30+
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
3031

3132
import com.cloud.domain.DomainDetailVO;
3233
import com.cloud.domain.DomainVO;
33-
import com.cloud.domain.dao.DomainDetailsDao;
3434
import com.cloud.domain.dao.DomainDao;
35+
import com.cloud.domain.dao.DomainDetailsDao;
3536
import com.cloud.user.dao.AccountDao;
36-
37+
import com.cloud.utils.crypt.DBEncryptionUtil;
3738
import com.cloud.utils.db.GenericDaoBase;
3839
import com.cloud.utils.db.QueryBuilder;
3940
import com.cloud.utils.db.SearchBuilder;
4041
import com.cloud.utils.db.SearchCriteria;
4142
import com.cloud.utils.db.SearchCriteria.Op;
4243
import com.cloud.utils.db.TransactionLegacy;
43-
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
44-
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
4544

4645
public class AccountDetailsDaoImpl extends GenericDaoBase<AccountDetailVO, Long> implements AccountDetailsDao, ScopedConfigStorage {
4746
protected final SearchBuilder<AccountDetailVO> accountSearch;
@@ -118,9 +117,9 @@ public Scope getScope() {
118117
}
119118

120119
@Override
121-
public String getConfigValue(long id, ConfigKey<?> key) {
120+
public String getConfigValue(long id, String key) {
122121
// check if account level setting is configured
123-
AccountDetailVO vo = findDetail(id, key.key());
122+
AccountDetailVO vo = findDetail(id, key);
124123
String value = vo == null ? null : getActualValue(vo);
125124
if (value != null) {
126125
return value;
@@ -140,7 +139,7 @@ public String getConfigValue(long id, ConfigKey<?> key) {
140139
if (account.isPresent()) {
141140
DomainVO domain = _domainDao.findById(account.get().getDomainId());
142141
while (domain != null) {
143-
DomainDetailVO domainVO = _domainDetailsDao.findDetail(domain.getId(), key.key());
142+
DomainDetailVO domainVO = _domainDetailsDao.findDetail(domain.getId(), key);
144143
if (domainVO != null) {
145144
value = _domainDetailsDao.getActualValue(domainVO);
146145
break;

engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDaoImpl.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020
import java.util.List;
2121
import java.util.Map;
2222

23+
import org.apache.cloudstack.api.ApiConstants;
24+
import org.apache.cloudstack.framework.config.ConfigKey;
25+
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
26+
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
27+
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
2328
import org.springframework.stereotype.Component;
2429

2530
import com.cloud.utils.crypt.DBEncryptionUtil;
@@ -29,12 +34,6 @@
2934
import com.cloud.utils.db.SearchCriteria.Op;
3035
import com.cloud.utils.db.TransactionLegacy;
3136

32-
import org.apache.cloudstack.api.ApiConstants;
33-
import org.apache.cloudstack.framework.config.ConfigKey;
34-
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
35-
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
36-
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
37-
3837
@Component
3938
public class ImageStoreDetailsDaoImpl extends ResourceDetailsDaoBase<ImageStoreDetailVO> implements ImageStoreDetailsDao, ScopedConfigStorage {
4039

@@ -106,8 +105,8 @@ public ImageStoreDetailVO findDetail(long storeId, String name) {
106105
}
107106

108107
@Override
109-
public String getConfigValue(long id, ConfigKey<?> key) {
110-
ImageStoreDetailVO vo = findDetail(id, key.key());
108+
public String getConfigValue(long id, String key) {
109+
ImageStoreDetailVO vo = findDetail(id, key);
111110
return vo == null ? null : vo.getValue();
112111
}
113112

framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigDepot.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ public interface ConfigDepot {
3232

3333
<T> void createOrUpdateConfigObject(String componentName, ConfigKey<T> key, String value);
3434
boolean isNewConfig(ConfigKey<?> configKey);
35+
String getConfigStringValue(String key, ConfigKey.Scope scope, Long scopeId);
36+
void invalidateConfigCache(String key, ConfigKey.Scope scope, Long scopeId);
3537
}

framework/config/src/main/java/org/apache/cloudstack/framework/config/ConfigKey.java

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.sql.Date;
2020

2121
import org.apache.cloudstack.framework.config.impl.ConfigDepotImpl;
22-
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
2322

2423
import com.cloud.utils.Pair;
2524
import com.cloud.utils.Ternary;
@@ -215,42 +214,38 @@ public boolean isSameKeyAs(Object obj) {
215214

216215
public T value() {
217216
if (_value == null || isDynamic()) {
218-
ConfigurationVO vo = (s_depot != null && s_depot.global() != null) ? s_depot.global().findById(key()) : null;
219-
final String value = (vo != null && vo.getValue() != null) ? vo.getValue() : defaultValue();
220-
_value = ((value == null) ? (T)defaultValue() : valueOf(value));
217+
String value = s_depot != null ? s_depot.getConfigStringValue(_name, Scope.Global, null) : null;
218+
_value = valueOf((value == null) ? defaultValue() : value);
221219
}
222220

223221
return _value;
224222
}
225223

226-
public T valueIn(Long id) {
224+
protected T valueInScope(Scope scope, Long id) {
227225
if (id == null) {
228226
return value();
229227
}
230228

231-
String value = s_depot != null ? s_depot.findScopedConfigStorage(this).getConfigValue(id, this) : null;
229+
String value = s_depot != null ? s_depot.getConfigStringValue(_name, scope, id) : null;
232230
if (value == null) {
233231
return value();
234-
} else {
235-
return valueOf(value);
236232
}
233+
return valueOf(value);
237234
}
238235

239-
public T valueInDomain(Long domainId) {
240-
if (domainId == null) {
241-
return value();
242-
}
236+
public T valueIn(Long id) {
237+
return valueInScope(_scope, id);
238+
}
243239

244-
String value = s_depot != null ? s_depot.getDomainScope(this).getConfigValue(domainId, this) : null;
245-
if (value == null) {
246-
return value();
247-
} else {
248-
return valueOf(value);
249-
}
240+
public T valueInDomain(Long domainId) {
241+
return valueInScope(Scope.Domain, domainId);
250242
}
251243

252244
@SuppressWarnings("unchecked")
253245
protected T valueOf(String value) {
246+
if (value == null) {
247+
return null;
248+
}
254249
Number multiplier = 1;
255250
if (multiplier() != null) {
256251
multiplier = (Number)multiplier();

framework/config/src/main/java/org/apache/cloudstack/framework/config/ScopedConfigStorage.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,9 @@
2626
public interface ScopedConfigStorage {
2727
Scope getScope();
2828

29-
String getConfigValue(long id, ConfigKey<?> key);
29+
String getConfigValue(long id, String key);
30+
31+
default String getConfigValue(long id, ConfigKey<?> key) {
32+
return getConfigValue(id, key.key());
33+
}
3034
}

0 commit comments

Comments
 (0)