Commit d68cae0c authored by lepdou's avatar lepdou

refactor project config

parent 7e4f6bcc
package com.ctrip.framework.apollo.adminservice.aop; package com.ctrip.framework.apollo.adminservice.aop;
import com.ctrip.framework.apollo.biz.config.BizConfig;
import com.ctrip.framework.apollo.biz.entity.Item; import com.ctrip.framework.apollo.biz.entity.Item;
import com.ctrip.framework.apollo.biz.entity.Namespace; import com.ctrip.framework.apollo.biz.entity.Namespace;
import com.ctrip.framework.apollo.biz.entity.NamespaceLock; import com.ctrip.framework.apollo.biz.entity.NamespaceLock;
import com.ctrip.framework.apollo.biz.service.ItemService; import com.ctrip.framework.apollo.biz.service.ItemService;
import com.ctrip.framework.apollo.biz.service.NamespaceLockService; import com.ctrip.framework.apollo.biz.service.NamespaceLockService;
import com.ctrip.framework.apollo.biz.service.NamespaceService; import com.ctrip.framework.apollo.biz.service.NamespaceService;
import com.ctrip.framework.apollo.biz.utils.ApolloSwitcher;
import com.ctrip.framework.apollo.common.dto.ItemChangeSets; import com.ctrip.framework.apollo.common.dto.ItemChangeSets;
import com.ctrip.framework.apollo.common.dto.ItemDTO; import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
...@@ -39,7 +39,7 @@ public class NamespaceLockAspect { ...@@ -39,7 +39,7 @@ public class NamespaceLockAspect {
@Autowired @Autowired
private ItemService itemService; private ItemService itemService;
@Autowired @Autowired
private ApolloSwitcher apolloSwitcher; private BizConfig bizConfig;
//create item //create item
...@@ -75,7 +75,7 @@ public class NamespaceLockAspect { ...@@ -75,7 +75,7 @@ public class NamespaceLockAspect {
void acquireLock(String appId, String clusterName, String namespaceName, void acquireLock(String appId, String clusterName, String namespaceName,
String currentUser) { String currentUser) {
if (apolloSwitcher.isNamespaceLockSwitchOff()) { if (bizConfig.isNamespaceLockSwitchOff()) {
return; return;
} }
...@@ -85,7 +85,7 @@ public class NamespaceLockAspect { ...@@ -85,7 +85,7 @@ public class NamespaceLockAspect {
} }
void acquireLock(long namespaceId, String currentUser) { void acquireLock(long namespaceId, String currentUser) {
if (apolloSwitcher.isNamespaceLockSwitchOff()) { if (bizConfig.isNamespaceLockSwitchOff()) {
return; return;
} }
......
package com.ctrip.framework.apollo.adminservice.controller; package com.ctrip.framework.apollo.adminservice.controller;
import com.ctrip.framework.apollo.biz.config.BizConfig;
import com.ctrip.framework.apollo.biz.entity.Namespace; import com.ctrip.framework.apollo.biz.entity.Namespace;
import com.ctrip.framework.apollo.biz.entity.NamespaceLock; import com.ctrip.framework.apollo.biz.entity.NamespaceLock;
import com.ctrip.framework.apollo.biz.service.NamespaceLockService; import com.ctrip.framework.apollo.biz.service.NamespaceLockService;
import com.ctrip.framework.apollo.biz.service.NamespaceService; import com.ctrip.framework.apollo.biz.service.NamespaceService;
import com.ctrip.framework.apollo.biz.utils.ApolloSwitcher;
import com.ctrip.framework.apollo.common.dto.NamespaceLockDTO; import com.ctrip.framework.apollo.common.dto.NamespaceLockDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.utils.BeanUtils; import com.ctrip.framework.apollo.common.utils.BeanUtils;
...@@ -23,7 +23,7 @@ public class NamespaceLockController { ...@@ -23,7 +23,7 @@ public class NamespaceLockController {
@Autowired @Autowired
private NamespaceService namespaceService; private NamespaceService namespaceService;
@Autowired @Autowired
private ApolloSwitcher apolloSwitcher; private BizConfig bizConfig;
@RequestMapping("/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/lock") @RequestMapping("/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/lock")
public NamespaceLockDTO getNamespaceLockOwner(@PathVariable String appId, @PathVariable String clusterName, public NamespaceLockDTO getNamespaceLockOwner(@PathVariable String appId, @PathVariable String clusterName,
...@@ -33,7 +33,7 @@ public class NamespaceLockController { ...@@ -33,7 +33,7 @@ public class NamespaceLockController {
throw new BadRequestException("namespace not exist."); throw new BadRequestException("namespace not exist.");
} }
if (apolloSwitcher.isNamespaceLockSwitchOff()) { if (bizConfig.isNamespaceLockSwitchOff()) {
return null; return null;
} }
......
package com.ctrip.framework.apollo.adminservice.aop; package com.ctrip.framework.apollo.adminservice.aop;
import com.ctrip.framework.apollo.biz.config.BizConfig;
import com.ctrip.framework.apollo.biz.entity.Namespace; import com.ctrip.framework.apollo.biz.entity.Namespace;
import com.ctrip.framework.apollo.biz.entity.NamespaceLock; import com.ctrip.framework.apollo.biz.entity.NamespaceLock;
import com.ctrip.framework.apollo.biz.service.ItemService; import com.ctrip.framework.apollo.biz.service.ItemService;
import com.ctrip.framework.apollo.biz.service.NamespaceLockService; import com.ctrip.framework.apollo.biz.service.NamespaceLockService;
import com.ctrip.framework.apollo.biz.service.NamespaceService; import com.ctrip.framework.apollo.biz.service.NamespaceService;
import com.ctrip.framework.apollo.biz.utils.ApolloSwitcher;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.exception.ServiceException; import com.ctrip.framework.apollo.common.exception.ServiceException;
...@@ -40,14 +40,14 @@ public class NamespaceLockTest { ...@@ -40,14 +40,14 @@ public class NamespaceLockTest {
@Mock @Mock
private ItemService itemService; private ItemService itemService;
@Mock @Mock
private ApolloSwitcher apolloSwitcher; private BizConfig bizConfig;
@InjectMocks @InjectMocks
NamespaceLockAspect namespaceLockAspect; NamespaceLockAspect namespaceLockAspect;
@Test @Test
public void acquireLockWithNotLockedAndSwitchON() { public void acquireLockWithNotLockedAndSwitchON() {
when(apolloSwitcher.isNamespaceLockSwitchOff()).thenReturn(true); when(bizConfig.isNamespaceLockSwitchOff()).thenReturn(true);
namespaceLockAspect.acquireLock(APP, CLUSTER, NAMESPACE, CURRENT_USER); namespaceLockAspect.acquireLock(APP, CLUSTER, NAMESPACE, CURRENT_USER);
...@@ -57,13 +57,13 @@ public class NamespaceLockTest { ...@@ -57,13 +57,13 @@ public class NamespaceLockTest {
@Test @Test
public void acquireLockWithNotLockedAndSwitchOFF() { public void acquireLockWithNotLockedAndSwitchOFF() {
when(apolloSwitcher.isNamespaceLockSwitchOff()).thenReturn(false); when(bizConfig.isNamespaceLockSwitchOff()).thenReturn(false);
when(namespaceService.findOne(APP, CLUSTER, NAMESPACE)).thenReturn(mockNamespace()); when(namespaceService.findOne(APP, CLUSTER, NAMESPACE)).thenReturn(mockNamespace());
when(namespaceLockService.findLock(anyLong())).thenReturn(null); when(namespaceLockService.findLock(anyLong())).thenReturn(null);
namespaceLockAspect.acquireLock(APP, CLUSTER, NAMESPACE, CURRENT_USER); namespaceLockAspect.acquireLock(APP, CLUSTER, NAMESPACE, CURRENT_USER);
verify(apolloSwitcher).isNamespaceLockSwitchOff(); verify(bizConfig).isNamespaceLockSwitchOff();
verify(namespaceService).findOne(APP, CLUSTER, NAMESPACE); verify(namespaceService).findOne(APP, CLUSTER, NAMESPACE);
verify(namespaceLockService).findLock(anyLong()); verify(namespaceLockService).findLock(anyLong());
verify(namespaceLockService).tryLock(any()); verify(namespaceLockService).tryLock(any());
...@@ -73,13 +73,13 @@ public class NamespaceLockTest { ...@@ -73,13 +73,13 @@ public class NamespaceLockTest {
@Test(expected = BadRequestException.class) @Test(expected = BadRequestException.class)
public void acquireLockWithAlreadyLockedByOtherGuy() { public void acquireLockWithAlreadyLockedByOtherGuy() {
when(apolloSwitcher.isNamespaceLockSwitchOff()).thenReturn(false); when(bizConfig.isNamespaceLockSwitchOff()).thenReturn(false);
when(namespaceService.findOne(APP, CLUSTER, NAMESPACE)).thenReturn(mockNamespace()); when(namespaceService.findOne(APP, CLUSTER, NAMESPACE)).thenReturn(mockNamespace());
when(namespaceLockService.findLock(NAMESPACE_ID)).thenReturn(mockNamespaceLock(ANOTHER_USER)); when(namespaceLockService.findLock(NAMESPACE_ID)).thenReturn(mockNamespaceLock(ANOTHER_USER));
namespaceLockAspect.acquireLock(APP, CLUSTER, NAMESPACE, CURRENT_USER); namespaceLockAspect.acquireLock(APP, CLUSTER, NAMESPACE, CURRENT_USER);
verify(apolloSwitcher).isNamespaceLockSwitchOff(); verify(bizConfig).isNamespaceLockSwitchOff();
verify(namespaceService).findOne(APP, CLUSTER, NAMESPACE); verify(namespaceService).findOne(APP, CLUSTER, NAMESPACE);
verify(namespaceLockService).findLock(NAMESPACE_ID); verify(namespaceLockService).findLock(NAMESPACE_ID);
} }
...@@ -87,13 +87,13 @@ public class NamespaceLockTest { ...@@ -87,13 +87,13 @@ public class NamespaceLockTest {
@Test @Test
public void acquireLockWithAlreadyLockedBySelf() { public void acquireLockWithAlreadyLockedBySelf() {
when(apolloSwitcher.isNamespaceLockSwitchOff()).thenReturn(false); when(bizConfig.isNamespaceLockSwitchOff()).thenReturn(false);
when(namespaceService.findOne(APP, CLUSTER, NAMESPACE)).thenReturn(mockNamespace()); when(namespaceService.findOne(APP, CLUSTER, NAMESPACE)).thenReturn(mockNamespace());
when(namespaceLockService.findLock(NAMESPACE_ID)).thenReturn(mockNamespaceLock(CURRENT_USER)); when(namespaceLockService.findLock(NAMESPACE_ID)).thenReturn(mockNamespaceLock(CURRENT_USER));
namespaceLockAspect.acquireLock(APP, CLUSTER, NAMESPACE, CURRENT_USER); namespaceLockAspect.acquireLock(APP, CLUSTER, NAMESPACE, CURRENT_USER);
verify(apolloSwitcher).isNamespaceLockSwitchOff(); verify(bizConfig).isNamespaceLockSwitchOff();
verify(namespaceService).findOne(APP, CLUSTER, NAMESPACE); verify(namespaceService).findOne(APP, CLUSTER, NAMESPACE);
verify(namespaceLockService).findLock(NAMESPACE_ID); verify(namespaceLockService).findLock(NAMESPACE_ID);
} }
...@@ -101,13 +101,13 @@ public class NamespaceLockTest { ...@@ -101,13 +101,13 @@ public class NamespaceLockTest {
@Test @Test
public void acquireLockWithNamespaceIdSwitchOn(){ public void acquireLockWithNamespaceIdSwitchOn(){
when(apolloSwitcher.isNamespaceLockSwitchOff()).thenReturn(false); when(bizConfig.isNamespaceLockSwitchOff()).thenReturn(false);
when(namespaceService.findOne(NAMESPACE_ID)).thenReturn(mockNamespace()); when(namespaceService.findOne(NAMESPACE_ID)).thenReturn(mockNamespace());
when(namespaceLockService.findLock(NAMESPACE_ID)).thenReturn(null); when(namespaceLockService.findLock(NAMESPACE_ID)).thenReturn(null);
namespaceLockAspect.acquireLock(NAMESPACE_ID, CURRENT_USER); namespaceLockAspect.acquireLock(NAMESPACE_ID, CURRENT_USER);
verify(apolloSwitcher).isNamespaceLockSwitchOff(); verify(bizConfig).isNamespaceLockSwitchOff();
verify(namespaceService).findOne(NAMESPACE_ID); verify(namespaceService).findOne(NAMESPACE_ID);
verify(namespaceLockService).findLock(NAMESPACE_ID); verify(namespaceLockService).findLock(NAMESPACE_ID);
verify(namespaceLockService).tryLock(any()); verify(namespaceLockService).tryLock(any());
...@@ -116,14 +116,14 @@ public class NamespaceLockTest { ...@@ -116,14 +116,14 @@ public class NamespaceLockTest {
@Test(expected = ServiceException.class) @Test(expected = ServiceException.class)
public void testDuplicateLock(){ public void testDuplicateLock(){
when(apolloSwitcher.isNamespaceLockSwitchOff()).thenReturn(false); when(bizConfig.isNamespaceLockSwitchOff()).thenReturn(false);
when(namespaceService.findOne(NAMESPACE_ID)).thenReturn(mockNamespace()); when(namespaceService.findOne(NAMESPACE_ID)).thenReturn(mockNamespace());
when(namespaceLockService.findLock(NAMESPACE_ID)).thenReturn(null); when(namespaceLockService.findLock(NAMESPACE_ID)).thenReturn(null);
when(namespaceLockService.tryLock(any())).thenThrow(DataIntegrityViolationException.class); when(namespaceLockService.tryLock(any())).thenThrow(DataIntegrityViolationException.class);
namespaceLockAspect.acquireLock(NAMESPACE_ID, CURRENT_USER); namespaceLockAspect.acquireLock(NAMESPACE_ID, CURRENT_USER);
verify(apolloSwitcher).isNamespaceLockSwitchOff(); verify(bizConfig).isNamespaceLockSwitchOff();
verify(namespaceService).findOne(NAMESPACE_ID); verify(namespaceService).findOne(NAMESPACE_ID);
verify(namespaceLockService, times(2)).findLock(NAMESPACE_ID); verify(namespaceLockService, times(2)).findLock(NAMESPACE_ID);
verify(namespaceLockService).tryLock(any()); verify(namespaceLockService).tryLock(any());
......
package com.ctrip.framework.apollo.biz.config;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ctrip.framework.apollo.biz.service.BizDBPropertySource;
import com.ctrip.framework.apollo.common.config.RefreshableConfig;
import com.ctrip.framework.apollo.common.config.RefreshablePropertySource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@Component
public class BizConfig extends RefreshableConfig {
private Gson gson = new Gson();
private static final Type namespaceValueLengthOverrideTypeReference =
new TypeToken<Map<Long, Integer>>() {
}.getType();
@Autowired
private BizDBPropertySource propertySource;
@Override
protected List<RefreshablePropertySource> getRefreshablePropertySources() {
return Collections.singletonList(propertySource);
}
public List<String> eurekaServiceUrls() {
String configuration = getValue("eureka.service.url", "");
if (Strings.isNullOrEmpty(configuration)) {
return Collections.emptyList();
}
return splitter.splitToList(configuration);
}
public int grayReleaseRuleScanInterval() {
return getIntProperty("apollo.gray-release-rule-scan.interval", 60);
}
public int itemKeyLengthLimit() {
return getIntProperty("item.key.length.limit", 128);
}
public int itemValueLengthLimit() {
return getIntProperty("item.value.length.limit", 20000);
}
public Map<Long, Integer> namespaceValueLengthLimitOverride() {
String namespaceValueLengthOverrideString = getValue("namespace.value.length.limit.override");
Map<Long, Integer> namespaceValueLengthOverride = Maps.newHashMap();
if (!Strings.isNullOrEmpty(namespaceValueLengthOverrideString)) {
namespaceValueLengthOverride =
gson.fromJson(namespaceValueLengthOverrideString, namespaceValueLengthOverrideTypeReference);
}
return namespaceValueLengthOverride;
}
public boolean isNamespaceLockSwitchOff() {
return !getBooleanProperty("namespace.lock.switch", false);
}
/**
* ctrip config
**/
public String cloggingUrl() {
return getValue("clogging.server.url");
}
public String cloggingPort() {
return getValue("clogging.server.port");
}
}
package com.ctrip.framework.apollo.biz.customize; package com.ctrip.framework.apollo.biz.customize;
import com.ctrip.framework.apollo.biz.service.ServerConfigService; import com.ctrip.framework.apollo.biz.config.BizConfig;
import com.ctrip.framework.apollo.common.customize.LoggingCustomizer; import com.ctrip.framework.apollo.common.customize.LoggingCustomizer;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -11,28 +11,18 @@ import org.springframework.stereotype.Component; ...@@ -11,28 +11,18 @@ import org.springframework.stereotype.Component;
@Profile("ctrip") @Profile("ctrip")
public class BizLoggingCustomizer extends LoggingCustomizer{ public class BizLoggingCustomizer extends LoggingCustomizer{
private static final String CLOGGING_SERVER_URL_KEY = "clogging.server.url";
private static final String CLOGGING_SERVER_PORT_KEY = "clogging.server.port";
@Autowired @Autowired
private ServerConfigService serverConfigService; private BizConfig bizConfig;
private String cloggingUrl;
private String cloggingPort;
@Override @Override
protected String cloggingUrl() { protected String cloggingUrl() {
if (cloggingUrl == null){ return bizConfig.cloggingUrl();
cloggingUrl = serverConfigService.getValue(CLOGGING_SERVER_URL_KEY);
}
return cloggingUrl;
} }
@Override @Override
protected String cloggingPort() { protected String cloggingPort() {
if (cloggingPort == null){ return bizConfig.cloggingPort();
cloggingPort = serverConfigService.getValue(CLOGGING_SERVER_PORT_KEY);
}
return cloggingPort;
} }
} }
package com.ctrip.framework.apollo.biz.eureka; package com.ctrip.framework.apollo.biz.eureka;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.ctrip.framework.apollo.biz.service.ServerConfigService; import com.ctrip.framework.apollo.biz.config.BizConfig;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean; import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List; import java.util.List;
@Component @Component
@Primary @Primary
public class ApolloEurekaClientConfig extends EurekaClientConfigBean { public class ApolloEurekaClientConfig extends EurekaClientConfigBean {
static final String EUREKA_URL_CONFIG = "eureka.service.url";
private static final Splitter URL_SPLITTER = Splitter.on(",").omitEmptyStrings();
@Autowired @Autowired
private ServerConfigService serverConfigService; private BizConfig bizConfig;
@Autowired
private Environment environment;
/** /**
* Assert only one zone: defaultZone, but multiple environments. * Assert only one zone: defaultZone, but multiple environments.
*/ */
public List<String> getEurekaServerServiceUrls(String myZone) { public List<String> getEurekaServerServiceUrls(String myZone) {
//First check if there is any system property override List<String> urls = bizConfig.eurekaServiceUrls();
if (!Strings.isNullOrEmpty(environment.getProperty(EUREKA_URL_CONFIG))) { return CollectionUtils.isEmpty(urls) ? super.getEurekaServerServiceUrls(myZone) : urls;
return URL_SPLITTER.splitToList(environment.getProperty(EUREKA_URL_CONFIG));
}
//Second check if it is configured in database
String eurekaUrl = serverConfigService.getValue(EUREKA_URL_CONFIG);
if (!Strings.isNullOrEmpty(eurekaUrl)) {
return URL_SPLITTER.splitToList(eurekaUrl);
}
//fallback to default
return super.getEurekaServerServiceUrls(myZone);
} }
@Override @Override
......
...@@ -9,12 +9,12 @@ import com.google.common.collect.Multimap; ...@@ -9,12 +9,12 @@ import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps; import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.ctrip.framework.apollo.biz.config.BizConfig;
import com.ctrip.framework.apollo.biz.entity.GrayReleaseRule; import com.ctrip.framework.apollo.biz.entity.GrayReleaseRule;
import com.ctrip.framework.apollo.biz.entity.ReleaseMessage; import com.ctrip.framework.apollo.biz.entity.ReleaseMessage;
import com.ctrip.framework.apollo.biz.message.ReleaseMessageListener; import com.ctrip.framework.apollo.biz.message.ReleaseMessageListener;
import com.ctrip.framework.apollo.biz.message.Topics; import com.ctrip.framework.apollo.biz.message.Topics;
import com.ctrip.framework.apollo.biz.repository.GrayReleaseRuleRepository; import com.ctrip.framework.apollo.biz.repository.GrayReleaseRuleRepository;
import com.ctrip.framework.apollo.biz.service.ServerConfigService;
import com.ctrip.framework.apollo.common.constants.NamespaceBranchStatus; import com.ctrip.framework.apollo.common.constants.NamespaceBranchStatus;
import com.ctrip.framework.apollo.common.dto.GrayReleaseRuleItemDTO; import com.ctrip.framework.apollo.common.dto.GrayReleaseRuleItemDTO;
import com.ctrip.framework.apollo.common.utils.GrayReleaseRuleItemTransformer; import com.ctrip.framework.apollo.common.utils.GrayReleaseRuleItemTransformer;
...@@ -45,11 +45,12 @@ public class GrayReleaseRulesHolder implements ReleaseMessageListener, Initializ ...@@ -45,11 +45,12 @@ public class GrayReleaseRulesHolder implements ReleaseMessageListener, Initializ
private static final Joiner STRING_JOINER = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR); private static final Joiner STRING_JOINER = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR);
private static final Splitter STRING_SPLITTER = private static final Splitter STRING_SPLITTER =
Splitter.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR).omitEmptyStrings(); Splitter.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR).omitEmptyStrings();
private static final int DEFAULT_SCAN_INTERVAL_IN_SECONDS = 60;
@Autowired
private ServerConfigService serverConfigService;
@Autowired @Autowired
private GrayReleaseRuleRepository grayReleaseRuleRepository; private GrayReleaseRuleRepository grayReleaseRuleRepository;
@Autowired
private BizConfig bizConfig;
private int databaseScanInterval; private int databaseScanInterval;
private ScheduledExecutorService executorService; private ScheduledExecutorService executorService;
//store configAppId+configCluster+configNamespace -> GrayReleaseRuleCache map //store configAppId+configCluster+configNamespace -> GrayReleaseRuleCache map
...@@ -249,12 +250,8 @@ public class GrayReleaseRulesHolder implements ReleaseMessageListener, Initializ ...@@ -249,12 +250,8 @@ public class GrayReleaseRulesHolder implements ReleaseMessageListener, Initializ
} }
private void populateDataBaseInterval() { private void populateDataBaseInterval() {
databaseScanInterval = DEFAULT_SCAN_INTERVAL_IN_SECONDS;
try { try {
String interval = serverConfigService.getValue("apollo.gray-release-rule-scan.interval"); databaseScanInterval = bizConfig.grayReleaseRuleScanInterval();
if (!Objects.isNull(interval)) {
databaseScanInterval = Integer.parseInt(interval);
}
} catch (Throwable ex) { } catch (Throwable ex) {
Tracer.logError(ex); Tracer.logError(ex);
logger.error("Load apollo gray release rule scan interval from server config failed", ex); logger.error("Load apollo gray release rule scan interval from server config failed", ex);
......
package com.ctrip.framework.apollo.biz.service;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.ctrip.framework.apollo.biz.entity.ServerConfig;
import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository;
import com.ctrip.framework.apollo.common.config.RefreshablePropertySource;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.foundation.Foundation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Objects;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Component
public class BizDBPropertySource extends RefreshablePropertySource {
private static final Logger logger = LoggerFactory.getLogger(BizDBPropertySource.class);
@Autowired
private ServerConfigRepository serverConfigRepository;
public BizDBPropertySource(String name, Map<String, Object> source) {
super(name, source);
}
public BizDBPropertySource() {
super("DBConfig", Maps.newConcurrentMap());
}
String getCurrentDataCenter() {
return Foundation.server().getDataCenter();
}
@Override
protected void refresh() {
Iterable<ServerConfig> dbConfigs = serverConfigRepository.findAll();
Map<String, Object> newConfigs = Maps.newHashMap();
//default cluster's configs
for (ServerConfig config : dbConfigs) {
if (Objects.equals(ConfigConsts.CLUSTER_NAME_DEFAULT, config.getCluster())) {
newConfigs.put(config.getKey(), config.getValue());
}
}
//data center's configs
String dataCenter = getCurrentDataCenter();
for (ServerConfig config : dbConfigs) {
if (Objects.equals(dataCenter, config.getCluster())) {
newConfigs.put(config.getKey(), config.getValue());
}
}
//cluster's config
if (!Strings.isNullOrEmpty(System.getProperty(ConfigConsts.APOLLO_CLUSTER_KEY))) {
String cluster = System.getProperty(ConfigConsts.APOLLO_CLUSTER_KEY);
for (ServerConfig config : dbConfigs) {
if (Objects.equals(cluster, config.getCluster())) {
newConfigs.put(config.getKey(), config.getValue());
}
}
}
//put to environment
for (Map.Entry<String, Object> config: newConfigs.entrySet()){
String key = config.getKey();
Object value = config.getValue();
if (this.source.get(key) == null) {
logger.info("Load config from DB : {} = {}", key, value);
} else if (!Objects.equals(this.source.get(key), value)) {
logger.info("Load config from DB : {} = {}. Old value = {}", key,
value, this.source.get(key));
}
this.source.put(key, value);
}
}
}
package com.ctrip.framework.apollo.biz.service; package com.ctrip.framework.apollo.biz.service;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ctrip.framework.apollo.biz.config.BizConfig;
import com.ctrip.framework.apollo.biz.entity.Audit; import com.ctrip.framework.apollo.biz.entity.Audit;
import com.ctrip.framework.apollo.biz.entity.Item; import com.ctrip.framework.apollo.biz.entity.Item;
import com.ctrip.framework.apollo.biz.entity.Namespace; import com.ctrip.framework.apollo.biz.entity.Namespace;
...@@ -11,29 +9,18 @@ import com.ctrip.framework.apollo.biz.repository.ItemRepository; ...@@ -11,29 +9,18 @@ import com.ctrip.framework.apollo.biz.repository.ItemRepository;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.exception.NotFoundException; import com.ctrip.framework.apollo.common.exception.NotFoundException;
import com.ctrip.framework.apollo.common.utils.BeanUtils; import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.tracer.Tracer;
import com.ctrip.framework.apollo.tracer.spi.Transaction;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.lang.reflect.Type;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
@Service @Service
public class ItemService implements InitializingBean { public class ItemService {
private static final int DEFAULT_LIMIT_UPDATE_INTERVAL_IN_SECONDS = 60;
@Autowired @Autowired
private ItemRepository itemRepository; private ItemRepository itemRepository;
...@@ -45,62 +32,8 @@ public class ItemService implements InitializingBean { ...@@ -45,62 +32,8 @@ public class ItemService implements InitializingBean {
private AuditService auditService; private AuditService auditService;
@Autowired @Autowired
private ServerConfigService serverConfigService; private BizConfig bizConfig;
private AtomicInteger globalKeyLengthLimit;
private AtomicInteger globalValueLengthLimit;
private AtomicReference<Map<Long, Integer>> namespaceValueLengthOverride;
private Gson gson;
private ScheduledExecutorService executorService;
private static final Type namespaceValueLengthOverrideTypeReference =
new TypeToken<Map<Long, Integer>>() {
}.getType();
public ItemService() {
gson = new Gson();
globalKeyLengthLimit = new AtomicInteger(128);
globalValueLengthLimit = new AtomicInteger(20000);
namespaceValueLengthOverride = new AtomicReference<>();
executorService = Executors.newScheduledThreadPool(1, ApolloThreadFactory
.create("ItemServiceLimitUpdater", true));
}
@Override
public void afterPropertiesSet() throws Exception {
executorService.scheduleWithFixedDelay(() -> {
Transaction transaction = Tracer.newTransaction("Apollo.ItemServiceLimitUpdater", "updateLimit");
try {
updateLimits();
transaction.setStatus(Transaction.SUCCESS);
} catch (Throwable ex) {
transaction.setStatus(ex);
} finally {
transaction.complete();
}
}, 0, getLimitUpdateIntervalInSeconds(), TimeUnit.SECONDS);
}
private void updateLimits() {
String keyLengthLimit = serverConfigService.getValue("item.key.length.limit", null);
if (!Strings.isNullOrEmpty(keyLengthLimit)) {
globalKeyLengthLimit.set(Integer.valueOf(keyLengthLimit));
}
String valueLengthLimit = serverConfigService.getValue("item.value.length.limit", null);
if (!Strings.isNullOrEmpty(valueLengthLimit)) {
globalValueLengthLimit.set(Integer.valueOf(valueLengthLimit));
}
String namespaceValueLengthOverrideString =
serverConfigService.getValue("namespace.value.length.limit.override", null);
if (!Strings.isNullOrEmpty(namespaceValueLengthOverrideString)) {
namespaceValueLengthOverride.set(gson.fromJson(
namespaceValueLengthOverrideString, namespaceValueLengthOverrideTypeReference));
}
}
@Transactional @Transactional
public Item delete(long id, String operator) { public Item delete(long id, String operator) {
...@@ -211,21 +144,18 @@ public class ItemService implements InitializingBean { ...@@ -211,21 +144,18 @@ public class ItemService implements InitializingBean {
} }
private boolean checkItemKeyLength(String key) { private boolean checkItemKeyLength(String key) {
if (!StringUtils.isEmpty(key) && key.length() > globalKeyLengthLimit.get()) { if (!StringUtils.isEmpty(key) && key.length() > bizConfig.itemKeyLengthLimit()) {
throw new BadRequestException("key too long. length limit:" + globalKeyLengthLimit.get()); throw new BadRequestException("key too long. length limit:" + bizConfig.itemKeyLengthLimit());
} }
return true; return true;
} }
private int getItemValueLengthLimit(long namespaceId) { private int getItemValueLengthLimit(long namespaceId) {
if (namespaceValueLengthOverride.get() != null && namespaceValueLengthOverride.get() Map<Long, Integer> namespaceValueLengthOverride = bizConfig.namespaceValueLengthLimitOverride();
.containsKey(namespaceId)) { if (namespaceValueLengthOverride != null && namespaceValueLengthOverride.containsKey(namespaceId)) {
return namespaceValueLengthOverride.get().get(namespaceId); return namespaceValueLengthOverride.get(namespaceId);
} }
return globalValueLengthLimit.get(); return bizConfig.itemValueLengthLimit();
} }
private int getLimitUpdateIntervalInSeconds() {
return DEFAULT_LIMIT_UPDATE_INTERVAL_IN_SECONDS;
}
} }
package com.ctrip.framework.apollo.biz.service;
import com.google.common.base.Strings;
import com.ctrip.framework.apollo.biz.entity.ServerConfig;
import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.foundation.Foundation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Service
public class ServerConfigService {
@Autowired
private ServerConfigRepository serverConfigRepository;
public String getValue(String key) {
ServerConfig serverConfig = null;
//1. Load from cluster config
if (!Strings.isNullOrEmpty(System.getProperty(ConfigConsts.APOLLO_CLUSTER_KEY))) {
serverConfig =
serverConfigRepository.findTopByKeyAndCluster(key, System.getProperty(ConfigConsts.APOLLO_CLUSTER_KEY));
}
//2. Fall back to data center config
if (serverConfig == null && !Strings.isNullOrEmpty(getDataCenter())) {
serverConfig = serverConfigRepository.findTopByKeyAndCluster(key, getDataCenter());
}
//3. Fall back to default cluster config
if (serverConfig == null) {
serverConfig =
serverConfigRepository.findTopByKeyAndCluster(key, ConfigConsts.CLUSTER_NAME_DEFAULT);
}
return serverConfig == null ? null : serverConfig.getValue();
}
public String getValue(String key, String defaultValue) {
String value = getValue(key);
return value == null ? defaultValue : value;
}
String getDataCenter() {
return Foundation.server().getDataCenter();
}
}
package com.ctrip.framework.apollo.biz.utils;
import com.ctrip.framework.apollo.biz.service.ServerConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ApolloSwitcher {
private static final String NAMESPACE_LOCK_SWITCH_CONFIG_KEY = "namespace.lock.switch";
@Autowired
private ServerConfigService serverConfigService;
public boolean isNamespaceLockSwitchOff() {
return !"true".equals(serverConfigService.getValue(NAMESPACE_LOCK_SWITCH_CONFIG_KEY, "false"));
}
}
package com.ctrip.framework.apollo.biz; package com.ctrip.framework.apollo.biz;
import com.ctrip.framework.apollo.biz.eureka.ApolloEurekaClientConfigTest;
import com.ctrip.framework.apollo.biz.grayReleaseRule.GrayReleaseRulesHolderTest; import com.ctrip.framework.apollo.biz.grayReleaseRule.GrayReleaseRulesHolderTest;
import com.ctrip.framework.apollo.biz.message.DatabaseMessageSenderTest; import com.ctrip.framework.apollo.biz.message.DatabaseMessageSenderTest;
import com.ctrip.framework.apollo.biz.message.ReleaseMessageScannerTest; import com.ctrip.framework.apollo.biz.message.ReleaseMessageScannerTest;
...@@ -14,7 +13,7 @@ import com.ctrip.framework.apollo.biz.service.NamespaceBranchServiceTest; ...@@ -14,7 +13,7 @@ import com.ctrip.framework.apollo.biz.service.NamespaceBranchServiceTest;
import com.ctrip.framework.apollo.biz.service.PrivilegeServiceTest; import com.ctrip.framework.apollo.biz.service.PrivilegeServiceTest;
import com.ctrip.framework.apollo.biz.service.ReleaseCreationTest; import com.ctrip.framework.apollo.biz.service.ReleaseCreationTest;
import com.ctrip.framework.apollo.biz.service.ReleaseServiceTest; import com.ctrip.framework.apollo.biz.service.ReleaseServiceTest;
import com.ctrip.framework.apollo.biz.service.ServerConfigServiceTest; import com.ctrip.framework.apollo.biz.service.BizDBPropertySourceTest;
import com.ctrip.framework.apollo.biz.utils.ReleaseKeyGeneratorTest; import com.ctrip.framework.apollo.biz.utils.ReleaseKeyGeneratorTest;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
...@@ -29,8 +28,7 @@ import org.junit.runners.Suite.SuiteClasses; ...@@ -29,8 +28,7 @@ import org.junit.runners.Suite.SuiteClasses;
PrivilegeServiceTest.class, PrivilegeServiceTest.class,
AdminServiceTransactionTest.class, AdminServiceTransactionTest.class,
DatabaseMessageSenderTest.class, DatabaseMessageSenderTest.class,
ServerConfigServiceTest.class, BizDBPropertySourceTest.class,
ApolloEurekaClientConfigTest.class,
ReleaseServiceTest.class, ReleaseServiceTest.class,
ReleaseMessageScannerTest.class, ReleaseMessageScannerTest.class,
ClusterServiceTest.class, ClusterServiceTest.class,
......
package com.ctrip.framework.apollo.biz.eureka;
import com.ctrip.framework.apollo.biz.AbstractUnitTest;
import com.ctrip.framework.apollo.biz.service.ServerConfigService;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.springframework.core.env.Environment;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class ApolloEurekaClientConfigTest extends AbstractUnitTest {
private ApolloEurekaClientConfig eurekaClientConfig;
@Mock
private ServerConfigService serverConfigService;
@Mock
private Environment environment;
@Before
public void setUp() throws Exception {
eurekaClientConfig = new ApolloEurekaClientConfig();
ReflectionTestUtils.setField(eurekaClientConfig, "serverConfigService", serverConfigService);
ReflectionTestUtils.setField(eurekaClientConfig, "environment", environment);
}
@Test
public void testGetEurekaServerServiceUrlsFromDB() throws Exception {
String someEurekaUrl = "http://xxx,http://yyy";
String myZone = "xx";
when(serverConfigService.getValue(ApolloEurekaClientConfig.EUREKA_URL_CONFIG))
.thenReturn(someEurekaUrl);
List<String> eurekaUrls = eurekaClientConfig.getEurekaServerServiceUrls(myZone);
String[] expected = someEurekaUrl.split(",");
assertEquals(expected.length, eurekaUrls.size());
for (String url : expected) {
assertTrue(eurekaUrls.contains(url));
}
}
@Test
public void testGetEurekaServiceUrlsFromSystemProperty() throws Exception {
String someEurekaUrl = "http://xxx,http://yyy";
String myZone = "xx";
String someEurekaUrlFromSystemProperty = "http://zzz";
when(environment.getProperty(ApolloEurekaClientConfig.EUREKA_URL_CONFIG))
.thenReturn(someEurekaUrlFromSystemProperty);
when(serverConfigService.getValue(ApolloEurekaClientConfig.EUREKA_URL_CONFIG))
.thenReturn(someEurekaUrl);
List<String> eurekaUrls = eurekaClientConfig.getEurekaServerServiceUrls(myZone);
String[] expected = someEurekaUrlFromSystemProperty.split(",");
assertEquals(expected.length, eurekaUrls.size());
for (String url : expected) {
assertTrue(eurekaUrls.contains(url));
}
}
}
...@@ -5,11 +5,11 @@ import com.google.common.collect.Lists; ...@@ -5,11 +5,11 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.ctrip.framework.apollo.biz.config.BizConfig;
import com.ctrip.framework.apollo.biz.entity.GrayReleaseRule; import com.ctrip.framework.apollo.biz.entity.GrayReleaseRule;
import com.ctrip.framework.apollo.biz.entity.ReleaseMessage; import com.ctrip.framework.apollo.biz.entity.ReleaseMessage;
import com.ctrip.framework.apollo.biz.message.Topics; import com.ctrip.framework.apollo.biz.message.Topics;
import com.ctrip.framework.apollo.biz.repository.GrayReleaseRuleRepository; import com.ctrip.framework.apollo.biz.repository.GrayReleaseRuleRepository;
import com.ctrip.framework.apollo.biz.service.ServerConfigService;
import com.ctrip.framework.apollo.common.constants.NamespaceBranchStatus; import com.ctrip.framework.apollo.common.constants.NamespaceBranchStatus;
import com.ctrip.framework.apollo.common.dto.GrayReleaseRuleItemDTO; import com.ctrip.framework.apollo.common.dto.GrayReleaseRuleItemDTO;
import com.ctrip.framework.apollo.core.ConfigConsts; import com.ctrip.framework.apollo.core.ConfigConsts;
...@@ -40,7 +40,7 @@ public class GrayReleaseRulesHolderTest { ...@@ -40,7 +40,7 @@ public class GrayReleaseRulesHolderTest {
private static final Joiner STRING_JOINER = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR); private static final Joiner STRING_JOINER = Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR);
private GrayReleaseRulesHolder grayReleaseRulesHolder; private GrayReleaseRulesHolder grayReleaseRulesHolder;
@Mock @Mock
private ServerConfigService serverConfigService; private BizConfig bizConfig;
@Mock @Mock
private GrayReleaseRuleRepository grayReleaseRuleRepository; private GrayReleaseRuleRepository grayReleaseRuleRepository;
private Gson gson = new Gson(); private Gson gson = new Gson();
...@@ -49,8 +49,8 @@ public class GrayReleaseRulesHolderTest { ...@@ -49,8 +49,8 @@ public class GrayReleaseRulesHolderTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
grayReleaseRulesHolder = spy(new GrayReleaseRulesHolder()); grayReleaseRulesHolder = spy(new GrayReleaseRulesHolder());
ReflectionTestUtils.setField(grayReleaseRulesHolder, "serverConfigService", ReflectionTestUtils.setField(grayReleaseRulesHolder, "bizConfig",
serverConfigService); bizConfig);
ReflectionTestUtils.setField(grayReleaseRulesHolder, "grayReleaseRuleRepository", ReflectionTestUtils.setField(grayReleaseRulesHolder, "grayReleaseRuleRepository",
grayReleaseRuleRepository); grayReleaseRuleRepository);
idCounter = new AtomicLong(); idCounter = new AtomicLong();
...@@ -75,6 +75,7 @@ public class GrayReleaseRulesHolderTest { ...@@ -75,6 +75,7 @@ public class GrayReleaseRulesHolderTest {
someNamespaceName, Lists.newArrayList(assembleRuleItem(someClientAppId, Sets.newHashSet someNamespaceName, Lists.newArrayList(assembleRuleItem(someClientAppId, Sets.newHashSet
(someClientIp))), someReleaseId, activeBranchStatus); (someClientIp))), someReleaseId, activeBranchStatus);
when(bizConfig.grayReleaseRuleScanInterval()).thenReturn(30);
when(grayReleaseRuleRepository.findFirst500ByIdGreaterThanOrderByIdAsc(0L)).thenReturn(Lists when(grayReleaseRuleRepository.findFirst500ByIdGreaterThanOrderByIdAsc(0L)).thenReturn(Lists
.newArrayList(someRule)); .newArrayList(someRule));
......
package com.ctrip.framework.apollo.biz.service;
import com.google.common.collect.Lists;
import com.ctrip.framework.apollo.biz.AbstractUnitTest;
import com.ctrip.framework.apollo.biz.entity.ServerConfig;
import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository;
import com.ctrip.framework.apollo.core.ConfigConsts;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class BizDBPropertySourceTest extends AbstractUnitTest {
@Mock
private ServerConfigRepository serverConfigRepository;
private BizDBPropertySource propertySource;
private String clusterConfigKey = "clusterKey";
private String clusterConfigValue = "clusterValue";
private String dcConfigKey = "dcKey";
private String dcConfigValue = "dcValue";
private String defaultKey = "defaultKey";
private String defaultValue = "defaultValue";
@Before
public void initTestData() {
propertySource = spy(new BizDBPropertySource());
ReflectionTestUtils.setField(propertySource, "serverConfigRepository", serverConfigRepository);
List<ServerConfig> configs = Lists.newLinkedList();
//cluster config
String cluster = "cluster";
configs.add(createServerConfig(clusterConfigKey, clusterConfigValue, cluster));
String dc = "dc";
configs.add(createServerConfig(clusterConfigKey, clusterConfigValue + "dc", dc));
configs.add(createServerConfig(clusterConfigKey, clusterConfigValue + ConfigConsts.CLUSTER_NAME_DEFAULT,
ConfigConsts.CLUSTER_NAME_DEFAULT));
//dc config
configs.add(createServerConfig(dcConfigKey, dcConfigValue, dc));
configs.add(createServerConfig(dcConfigKey, dcConfigValue + ConfigConsts.CLUSTER_NAME_DEFAULT,
ConfigConsts.CLUSTER_NAME_DEFAULT));
//default config
configs.add(createServerConfig(defaultKey, defaultValue, ConfigConsts.CLUSTER_NAME_DEFAULT));
System.setProperty(ConfigConsts.APOLLO_CLUSTER_KEY, cluster);
when(propertySource.getCurrentDataCenter()).thenReturn(dc);
when(serverConfigRepository.findAll()).thenReturn(configs);
}
@After
public void clear() {
System.clearProperty(ConfigConsts.APOLLO_CLUSTER_KEY);
}
@Test
public void testGetClusterConfig() {
propertySource.refresh();
assertEquals(propertySource.getProperty(clusterConfigKey), clusterConfigValue);
}
@Test
public void testGetDcConfig() {
propertySource.refresh();
assertEquals(propertySource.getProperty(dcConfigKey), dcConfigValue);
}
@Test
public void testGetDefaultConfig() {
propertySource.refresh();
assertEquals(propertySource.getProperty(defaultKey), defaultValue);
}
@Test
public void testGetNull() {
propertySource.refresh();
assertNull(propertySource.getProperty("noKey"));
}
private ServerConfig createServerConfig(String key, String value, String cluster) {
ServerConfig config = new ServerConfig();
config.setKey(key);
config.setValue(value);
config.setCluster(cluster);
return config;
}
}
package com.ctrip.framework.apollo.biz.service;
import com.ctrip.framework.apollo.biz.AbstractUnitTest;
import com.ctrip.framework.apollo.biz.entity.ServerConfig;
import com.ctrip.framework.apollo.biz.repository.ServerConfigRepository;
import com.ctrip.framework.apollo.core.ConfigConsts;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.springframework.test.util.ReflectionTestUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
/**
* @author Jason Song(song_s@ctrip.com)
*/
public class ServerConfigServiceTest extends AbstractUnitTest{
private ServerConfigService serverConfigService;
@Mock
private ServerConfigRepository serverConfigRepository;
private String someCluster;
private String someDC;
private String someKey;
private String someClusterValue;
private String someDCValue;
private String defaultClusterValue;
@Before
public void setUp() throws Exception {
serverConfigService = spy(new ServerConfigService());
ReflectionTestUtils.setField(serverConfigService, "serverConfigRepository", serverConfigRepository);
someCluster = "someCluster";
someDC = "someDC";
someKey = "someKey";
someClusterValue = "someClusterValue";
someDCValue = "someDCValue";
defaultClusterValue = "defaultClusterValue";
when(serverConfigRepository.findTopByKeyAndCluster(someKey, someCluster))
.thenReturn(assembleServerConfig(someKey, someClusterValue));
when(serverConfigRepository.findTopByKeyAndCluster(someKey, someDC))
.thenReturn(assembleServerConfig(someKey, someDCValue));
when(serverConfigRepository.findTopByKeyAndCluster(someKey, ConfigConsts.CLUSTER_NAME_DEFAULT))
.thenReturn(assembleServerConfig(someKey, defaultClusterValue));
}
@After
public void tearDown() throws Exception {
System.clearProperty(ConfigConsts.APOLLO_CLUSTER_KEY);
}
@Test
public void testGetValueWithNoCluster() throws Exception {
when(serverConfigService.getDataCenter()).thenReturn(null);
assertEquals(defaultClusterValue, serverConfigService.getValue(someKey));
}
@Test
public void testGetValueWithCluster() throws Exception {
System.setProperty(ConfigConsts.APOLLO_CLUSTER_KEY, someCluster);
assertEquals(someClusterValue, serverConfigService.getValue(someKey));
}
@Test
public void testGetValueWithDataCenter() throws Exception {
when(serverConfigService.getDataCenter()).thenReturn(someDC);
assertEquals(someDCValue, serverConfigService.getValue(someKey));
}
@Test
public void testGetValueWithKeyNotExists() throws Exception {
String someKeyNotExists = "someKeyNotExists";
System.setProperty(ConfigConsts.APOLLO_CLUSTER_KEY, someCluster);
when(serverConfigService.getDataCenter()).thenReturn(someDC);
assertNull(serverConfigService.getValue(someKeyNotExists));
}
@Test
public void testGetValueWithClusterNotExists() throws Exception {
String someClusterNotExists = "someClusterNotExists";
System.setProperty(ConfigConsts.APOLLO_CLUSTER_KEY, someClusterNotExists);
assertEquals(defaultClusterValue, serverConfigService.getValue(someKey));
}
@Test
public void testGetValueWithDCNotExists() throws Exception {
String someDCNotExists = "someDCNotExists";
when(serverConfigService.getDataCenter()).thenReturn(someDCNotExists);
assertEquals(defaultClusterValue, serverConfigService.getValue(someKey));
}
private ServerConfig assembleServerConfig(String key, String value) {
ServerConfig serverConfig = new ServerConfig();
serverConfig.setKey(key);
serverConfig.setValue(value);
return serverConfig;
}
}
package com.ctrip.framework.apollo.common.config;
import com.google.common.base.Splitter;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.tracer.Tracer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
public abstract class RefreshableConfig {
private static final Logger logger = LoggerFactory.getLogger(RefreshableConfig.class);
private static final String LIST_SEPARATOR = ",";
//TimeUnit: second
private static final int CONFIG_REFRESH_INTERVAL = 60;
protected Splitter splitter = Splitter.on(LIST_SEPARATOR).omitEmptyStrings().trimResults();
@Autowired
private ConfigurableEnvironment environment;
private List<RefreshablePropertySource> propertySources;
/**
* register refreshable property source.
* Notice: The front property source has higher priority.
*/
protected abstract List<RefreshablePropertySource> getRefreshablePropertySources();
@PostConstruct
public void setup() {
propertySources = getRefreshablePropertySources();
if (CollectionUtils.isEmpty(propertySources)) {
throw new IllegalStateException("Property sources can not be empty.");
}
//add property source to environment
for (RefreshablePropertySource propertySource : propertySources) {
propertySource.refresh();
environment.getPropertySources().addLast(propertySource);
}
//task to update configs
ScheduledExecutorService
executorService =
Executors.newScheduledThreadPool(1, ApolloThreadFactory.create("ConfigRefresher", false));
executorService
.scheduleWithFixedDelay(() -> {
try {
propertySources.forEach(RefreshablePropertySource::refresh);
} catch (Throwable t) {
logger.error("Refresh configs failed.", t);
Tracer.logError("Refresh configs failed.", t);
}
}, CONFIG_REFRESH_INTERVAL, CONFIG_REFRESH_INTERVAL, TimeUnit.SECONDS);
}
public int getIntProperty(String key, int defaultValue) {
try {
String value = getValue(key);
return value == null ? defaultValue : Integer.parseInt(value);
} catch (Exception e) {
Tracer.logError("Get int property failed.", e);
return defaultValue;
}
}
public boolean getBooleanProperty(String key, boolean defaultValue) {
try {
String value = getValue(key);
return value == null ? defaultValue : "true".equals(value);
} catch (Exception e) {
Tracer.logError("Get boolean property failed.", e);
return defaultValue;
}
}
public String[] getArrayProperty(String key, String defaultValue) {
try {
String configuration = getValue(key, defaultValue);
return configuration.split(LIST_SEPARATOR);
} catch (Exception e) {
Tracer.logError("Get array property failed.", e);
return defaultValue.split(LIST_SEPARATOR);
}
}
public String getValue(String key, String defaultValue) {
try {
return environment.getProperty(key, defaultValue);
} catch (Exception e) {
Tracer.logError("Get value failed.", e);
return defaultValue;
}
}
public String getValue(String key) {
return environment.getProperty(key);
}
}
package com.ctrip.framework.apollo.common.config;
import org.springframework.core.env.MapPropertySource;
import java.util.Map;
public abstract class RefreshablePropertySource extends MapPropertySource {
public RefreshablePropertySource(String name, Map<String, Object> source) {
super(name, source);
}
@Override
public Object getProperty(String name) {
return this.source.get(name);
}
/**
* refresh property
*/
protected abstract void refresh();
}
...@@ -8,7 +8,7 @@ public final class EnvUtils { ...@@ -8,7 +8,7 @@ public final class EnvUtils {
if (StringUtils.isBlank(envName)) { if (StringUtils.isBlank(envName)) {
return null; return null;
} }
switch (envName.toUpperCase()) { switch (envName.trim().toUpperCase()) {
case "LPT": case "LPT":
return Env.LPT; return Env.LPT;
case "FAT": case "FAT":
......
...@@ -12,10 +12,9 @@ import com.ctrip.framework.apollo.openapi.entity.ConsumerToken; ...@@ -12,10 +12,9 @@ import com.ctrip.framework.apollo.openapi.entity.ConsumerToken;
import com.ctrip.framework.apollo.openapi.repository.ConsumerAuditRepository; import com.ctrip.framework.apollo.openapi.repository.ConsumerAuditRepository;
import com.ctrip.framework.apollo.openapi.repository.ConsumerRepository; import com.ctrip.framework.apollo.openapi.repository.ConsumerRepository;
import com.ctrip.framework.apollo.openapi.repository.ConsumerTokenRepository; import com.ctrip.framework.apollo.openapi.repository.ConsumerTokenRepository;
import com.ctrip.framework.apollo.portal.service.ServerConfigService; import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import org.apache.commons.lang.time.FastDateFormat; import org.apache.commons.lang.time.FastDateFormat;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -26,7 +25,7 @@ import java.util.Date; ...@@ -26,7 +25,7 @@ import java.util.Date;
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
@Service @Service
public class ConsumerService implements InitializingBean { public class ConsumerService {
static final String TOKEN_SALT_KEY = "consumer.token.salt"; static final String TOKEN_SALT_KEY = "consumer.token.salt";
private static final FastDateFormat TIMESTAMP_FORMAT = FastDateFormat.getInstance private static final FastDateFormat TIMESTAMP_FORMAT = FastDateFormat.getInstance
("yyyyMMddHHmmss"); ("yyyyMMddHHmmss");
...@@ -38,9 +37,7 @@ public class ConsumerService implements InitializingBean { ...@@ -38,9 +37,7 @@ public class ConsumerService implements InitializingBean {
@Autowired @Autowired
private ConsumerAuditRepository consumerAuditRepository; private ConsumerAuditRepository consumerAuditRepository;
@Autowired @Autowired
private ServerConfigService serverConfigService; private PortalConfig portalConfig;
private String consumerTokenSalt;
public Long getConsumerIdByToken(String token) { public Long getConsumerIdByToken(String token) {
if (Strings.isNullOrEmpty(token)) { if (Strings.isNullOrEmpty(token)) {
...@@ -65,7 +62,7 @@ public class ConsumerService implements InitializingBean { ...@@ -65,7 +62,7 @@ public class ConsumerService implements InitializingBean {
consumerToken.setDataChangeCreatedTime(new Date()); consumerToken.setDataChangeCreatedTime(new Date());
} }
consumerToken.setToken(generateConsumerToken(consumer.getAppId(), consumerToken consumerToken.setToken(generateConsumerToken(consumer.getAppId(), consumerToken
.getDataChangeCreatedTime(), consumerTokenSalt)); .getDataChangeCreatedTime(), portalConfig.consumerTokenSalt()));
} }
@Transactional @Transactional
...@@ -86,8 +83,4 @@ public class ConsumerService implements InitializingBean { ...@@ -86,8 +83,4 @@ public class ConsumerService implements InitializingBean {
(generationTime), consumerTokenSalt), Charsets.UTF_8).toString(); (generationTime), consumerTokenSalt), Charsets.UTF_8).toString();
} }
@Override
public void afterPropertiesSet() throws Exception {
consumerTokenSalt = serverConfigService.getValue(TOKEN_SALT_KEY, "apollo-portal");
}
} }
...@@ -83,7 +83,7 @@ public class AdminServiceAddressLocator { ...@@ -83,7 +83,7 @@ public class AdminServiceAddressLocator {
return randomConfigServices; return randomConfigServices;
} }
//Maintain admin server address //maintain admin server address
private class RefreshAdminServerAddressTask implements Runnable { private class RefreshAdminServerAddressTask implements Runnable {
@Override @Override
......
...@@ -5,7 +5,7 @@ import com.ctrip.framework.apollo.core.MetaDomainConsts; ...@@ -5,7 +5,7 @@ import com.ctrip.framework.apollo.core.MetaDomainConsts;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory; import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.service.ServerConfigService; import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -15,7 +15,6 @@ import org.springframework.context.ApplicationContext; ...@@ -15,7 +15,6 @@ import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
...@@ -32,14 +31,12 @@ public class PortalSettings { ...@@ -32,14 +31,12 @@ public class PortalSettings {
private static final Logger logger = LoggerFactory.getLogger(PortalSettings.class); private static final Logger logger = LoggerFactory.getLogger(PortalSettings.class);
private static final int HEALTH_CHECK_INTERVAL = 10 * 1000; private static final int HEALTH_CHECK_INTERVAL = 10 * 1000;
private static final String DEFAULT_SUPPORT_ENV_LIST = "FAT,UAT,PRO";
@Autowired @Autowired
ApplicationContext applicationContext; ApplicationContext applicationContext;
@Autowired @Autowired
private ServerConfigService serverConfigService; private PortalConfig portalConfig;
private List<Env> allEnvs = new ArrayList<>(); private List<Env> allEnvs = new ArrayList<>();
...@@ -49,12 +46,7 @@ public class PortalSettings { ...@@ -49,12 +46,7 @@ public class PortalSettings {
@PostConstruct @PostConstruct
private void postConstruct() { private void postConstruct() {
String serverConfig = serverConfigService.getValue("apollo.portal.envs", DEFAULT_SUPPORT_ENV_LIST); allEnvs = portalConfig.portalSupportedEnvs();
String[] configedEnvs = serverConfig.split(",");
List<String> allStrEnvs = Arrays.asList(configedEnvs);
for (String e : allStrEnvs) {
allEnvs.add(Env.valueOf(e.toUpperCase()));
}
for (Env env : allEnvs) { for (Env env : allEnvs) {
envStatusMark.put(env, true); envStatusMark.put(env, true);
......
...@@ -2,7 +2,8 @@ package com.ctrip.framework.apollo.portal.components; ...@@ -2,7 +2,8 @@ package com.ctrip.framework.apollo.portal.components;
import com.google.common.io.BaseEncoding; import com.google.common.io.BaseEncoding;
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthScope;
...@@ -25,11 +26,11 @@ import java.util.Collection; ...@@ -25,11 +26,11 @@ import java.util.Collection;
@Component @Component
public class RestTemplateFactory implements FactoryBean<RestTemplate>, InitializingBean { public class RestTemplateFactory implements FactoryBean<RestTemplate>, InitializingBean {
@Autowired @Autowired
private HttpMessageConverters httpMessageConverters; private HttpMessageConverters httpMessageConverters;
@Autowired @Autowired
private ServerConfigService serverConfigService; private PortalConfig portalConfig;
private RestTemplate restTemplate; private RestTemplate restTemplate;
...@@ -62,23 +63,11 @@ public class RestTemplateFactory implements FactoryBean<RestTemplate>, Initializ ...@@ -62,23 +63,11 @@ public class RestTemplateFactory implements FactoryBean<RestTemplate>, Initializ
restTemplate = new RestTemplate(httpMessageConverters.getConverters()); restTemplate = new RestTemplate(httpMessageConverters.getConverters());
HttpComponentsClientHttpRequestFactory requestFactory = HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory(httpClient); new HttpComponentsClientHttpRequestFactory(httpClient);
requestFactory.setConnectTimeout(getConnectTimeout()); requestFactory.setConnectTimeout(portalConfig.connectTimeout());
requestFactory.setReadTimeout(getReadTimeout()); requestFactory.setReadTimeout(portalConfig.readTimeout());
restTemplate.setRequestFactory(requestFactory); restTemplate.setRequestFactory(requestFactory);
} }
private int getConnectTimeout() {
String connectTimeout = serverConfigService.getValue("api.connectTimeout", "3000");
return Integer.parseInt(connectTimeout);
}
private int getReadTimeout() {
String readTimeout = serverConfigService.getValue("api.readTimeout", "10000");
return Integer.parseInt(readTimeout);
}
} }
package com.ctrip.framework.apollo.portal.components.config;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ctrip.framework.apollo.common.config.RefreshableConfig;
import com.ctrip.framework.apollo.common.config.RefreshablePropertySource;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.entity.vo.Organization;
import com.ctrip.framework.apollo.portal.service.PortalDBPropertySource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@Component
public class PortalConfig extends RefreshableConfig {
private Gson gson = new Gson();
private static final Type ORGANIZATION = new TypeToken<List<Organization>>() {
}.getType();
@Autowired
private PortalDBPropertySource portalDBPropertySource;
@Override
public List<RefreshablePropertySource> getRefreshablePropertySources() {
return Collections.singletonList(portalDBPropertySource);
}
/***
* Level: important
**/
public List<Env> portalSupportedEnvs() {
String[] configuration = getArrayProperty("apollo.portal.envs", "FAT,UAT,PRO");
List<Env> envs = Lists.newLinkedList();
for (String env : configuration) {
envs.add(Env.fromString(env));
}
return envs;
}
public List<String> superAdmins() {
String superAdminConfig = getValue("superAdmin", "");
if (Strings.isNullOrEmpty(superAdminConfig)) {
return Collections.emptyList();
}
return splitter.splitToList(superAdminConfig);
}
public Set<Env> emailSupportedEnvs() {
String[] configurations = getArrayProperty("email.supported.envs", "");
Set<Env> result = Sets.newHashSet();
if (StringUtils.isEmpty(configurations)) {
return result;
}
for (String env : configurations) {
result.add(Env.fromString(env));
}
return result;
}
/***
* Level: normal
**/
public int connectTimeout() {
return getIntProperty("api.connectTimeout", 3000);
}
public int readTimeout() {
return getIntProperty("api.readTimeout", 10000);
}
public List<Organization> organizations() {
String organizations = getValue("organizations");
return organizations == null ? Collections.emptyList() : gson.fromJson(organizations, ORGANIZATION);
}
public String portalAddress() {
return getValue("apollo.portal.address");
}
/***
* Level: low
**/
public String consumerTokenSalt() {
return getValue("consumer.token.salt", "apollo-portal");
}
public String emailSender() {
return getValue("email.sender");
}
public String publishEmailBodyTemplate() {
return getValue("email.template.release", "");
}
public String rollbackEmailBodyTemplate() {
return getValue("email.template.rollback", "");
}
/***
* The following configurations are used in ctrip profile
**/
public int appId() {
return getIntProperty("ctrip.appid", 0);
}
//send code & template id. apply from ewatch
public String sendCode() {
return getValue("ctrip.email.send.code");
}
public int templateId() {
return getIntProperty("ctrip.email.template.id", 0);
}
//email retention time in email server queue.TimeUnit: hour
public int survivalDuration() {
return getIntProperty("ctrip.email.survival.duration", 5);
}
public String portalServerName() {
return getValue("serverName");
}
public String casServerLoginUrl() {
return getValue("casServerLoginUrl");
}
public String casServerUrlPrefix() {
return getValue("casServerUrlPrefix");
}
public String credisServiceUrl() {
return getValue("credisServiceUrl");
}
public String userServiceUrl() {
return getValue("userService.url");
}
public String userServiceAccessToken() {
return getValue("userService.accessToken");
}
public String soaServerAddress() {
return getValue("soa.server.address");
}
public String cloggingUrl() {
return getValue("clogging.server.url");
}
public String cloggingPort() {
return getValue("clogging.server.port");
}
}
...@@ -8,6 +8,7 @@ import com.ctrip.framework.apollo.common.dto.ReleaseDTO; ...@@ -8,6 +8,7 @@ import com.ctrip.framework.apollo.common.dto.ReleaseDTO;
import com.ctrip.framework.apollo.common.entity.AppNamespace; import com.ctrip.framework.apollo.common.entity.AppNamespace;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat; import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import com.ctrip.framework.apollo.portal.constant.RoleType; import com.ctrip.framework.apollo.portal.constant.RoleType;
import com.ctrip.framework.apollo.portal.entity.bo.Email; import com.ctrip.framework.apollo.portal.entity.bo.Email;
import com.ctrip.framework.apollo.portal.entity.bo.ReleaseHistoryBO; import com.ctrip.framework.apollo.portal.entity.bo.ReleaseHistoryBO;
...@@ -17,7 +18,6 @@ import com.ctrip.framework.apollo.portal.entity.vo.ReleaseCompareResult; ...@@ -17,7 +18,6 @@ import com.ctrip.framework.apollo.portal.entity.vo.ReleaseCompareResult;
import com.ctrip.framework.apollo.portal.service.AppNamespaceService; import com.ctrip.framework.apollo.portal.service.AppNamespaceService;
import com.ctrip.framework.apollo.portal.service.ReleaseService; import com.ctrip.framework.apollo.portal.service.ReleaseService;
import com.ctrip.framework.apollo.portal.service.RolePermissionService; import com.ctrip.framework.apollo.portal.service.RolePermissionService;
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import com.ctrip.framework.apollo.portal.spi.UserService; import com.ctrip.framework.apollo.portal.spi.UserService;
import com.ctrip.framework.apollo.portal.util.RoleUtils; import com.ctrip.framework.apollo.portal.util.RoleUtils;
...@@ -32,8 +32,6 @@ import java.util.List; ...@@ -32,8 +32,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import javax.annotation.PostConstruct;
public abstract class ConfigPublishEmailBuilder { public abstract class ConfigPublishEmailBuilder {
...@@ -62,17 +60,9 @@ public abstract class ConfigPublishEmailBuilder { ...@@ -62,17 +60,9 @@ public abstract class ConfigPublishEmailBuilder {
//set config's value max length to protect email. //set config's value max length to protect email.
protected static final int VALUE_MAX_LENGTH = 100; protected static final int VALUE_MAX_LENGTH = 100;
//email body template. config in db, so we can dynamic reject email content.
private static final String EMAIL_TEMPLATE__RELEASE = "email.template.release";
private static final String EMAIL_TEMPLATE__ROLLBACK = "email.template.rollback";
private FastDateFormat dateFormat = FastDateFormat.getInstance("yyyy-MM-dd hh:mm:ss"); private FastDateFormat dateFormat = FastDateFormat.getInstance("yyyy-MM-dd hh:mm:ss");
private String emailSender;
@Autowired
private ServerConfigService serverConfigService;
@Autowired @Autowired
private RolePermissionService rolePermissionService; private RolePermissionService rolePermissionService;
@Autowired @Autowired
...@@ -81,18 +71,16 @@ public abstract class ConfigPublishEmailBuilder { ...@@ -81,18 +71,16 @@ public abstract class ConfigPublishEmailBuilder {
private AppNamespaceService appNamespaceService; private AppNamespaceService appNamespaceService;
@Autowired @Autowired
private UserService userService; private UserService userService;
@Autowired
private PortalConfig portalConfig;
@PostConstruct
public void init() {
emailSender = serverConfigService.getValue("email.sender");
}
public Email build(Env env, ReleaseHistoryBO releaseHistory) { public Email build(Env env, ReleaseHistoryBO releaseHistory) {
Email email = new Email(); Email email = new Email();
email.setSubject(subject()); email.setSubject(subject());
email.setSenderEmailAddress(emailSender); email.setSenderEmailAddress(portalConfig.emailSender());
email.setBody(emailContent(env, releaseHistory)); email.setBody(emailContent(env, releaseHistory));
email.setRecipients(recipients(releaseHistory.getAppId(), releaseHistory.getNamespaceName())); email.setRecipients(recipients(releaseHistory.getAppId(), releaseHistory.getNamespaceName()));
...@@ -223,15 +211,15 @@ public abstract class ConfigPublishEmailBuilder { ...@@ -223,15 +211,15 @@ public abstract class ConfigPublishEmailBuilder {
protected String getReleaseTemplate() { protected String getReleaseTemplate() {
return serverConfigService.getValue(EMAIL_TEMPLATE__RELEASE); return portalConfig.publishEmailBodyTemplate();
} }
protected String getRollbackTemplate() { protected String getRollbackTemplate() {
return serverConfigService.getValue(EMAIL_TEMPLATE__ROLLBACK); return portalConfig.rollbackEmailBodyTemplate();
} }
protected String getApolloPortalAddress() { protected String getApolloPortalAddress() {
return serverConfigService.getValue("apollo.portal.address"); return portalConfig.portalAddress();
} }
private String cutOffString(String source) { private String cutOffString(String source) {
......
package com.ctrip.framework.apollo.portal.controller; package com.ctrip.framework.apollo.portal.controller;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import com.ctrip.framework.apollo.portal.entity.vo.Organization; import com.ctrip.framework.apollo.portal.entity.vo.Organization;
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
...@@ -21,22 +16,13 @@ import java.util.List; ...@@ -21,22 +16,13 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/organizations") @RequestMapping("/organizations")
public class OrganizationController { public class OrganizationController {
@Autowired
private ServerConfigService serverConfigService;
@Autowired @Autowired
private Gson gson; private PortalConfig portalConfig;
private Type responseType = new TypeToken<List<Organization>>() {
}.getType();
@RequestMapping @RequestMapping
public List<Organization> loadOrganization() { public List<Organization> loadOrganization() {
String organizations = serverConfigService.getValue("organizations"); return portalConfig.organizations();
if (Strings.isNullOrEmpty(organizations)) {
return Collections.emptyList();
}
return gson.fromJson(organizations, responseType);
} }
} }
...@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.portal.listener; ...@@ -2,6 +2,7 @@ package com.ctrip.framework.apollo.portal.listener;
import com.ctrip.framework.apollo.common.constants.ReleaseOperation; import com.ctrip.framework.apollo.common.constants.ReleaseOperation;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import com.ctrip.framework.apollo.portal.components.emailbuilder.GrayPublishEmailBuilder; import com.ctrip.framework.apollo.portal.components.emailbuilder.GrayPublishEmailBuilder;
import com.ctrip.framework.apollo.portal.components.emailbuilder.MergeEmailBuilder; import com.ctrip.framework.apollo.portal.components.emailbuilder.MergeEmailBuilder;
import com.ctrip.framework.apollo.portal.components.emailbuilder.NormalPublishEmailBuilder; import com.ctrip.framework.apollo.portal.components.emailbuilder.NormalPublishEmailBuilder;
...@@ -9,28 +10,16 @@ import com.ctrip.framework.apollo.portal.components.emailbuilder.RollbackEmailBu ...@@ -9,28 +10,16 @@ import com.ctrip.framework.apollo.portal.components.emailbuilder.RollbackEmailBu
import com.ctrip.framework.apollo.portal.entity.bo.Email; import com.ctrip.framework.apollo.portal.entity.bo.Email;
import com.ctrip.framework.apollo.portal.entity.bo.ReleaseHistoryBO; import com.ctrip.framework.apollo.portal.entity.bo.ReleaseHistoryBO;
import com.ctrip.framework.apollo.portal.service.ReleaseHistoryService; import com.ctrip.framework.apollo.portal.service.ReleaseHistoryService;
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import com.ctrip.framework.apollo.portal.spi.EmailService; import com.ctrip.framework.apollo.portal.spi.EmailService;
import com.ctrip.framework.apollo.tracer.Tracer; import com.ctrip.framework.apollo.tracer.Tracer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.PostConstruct;
@Component @Component
public class ConfigPublishListener { public class ConfigPublishListener {
private static final Logger logger = LoggerFactory.getLogger(ConfigPublishListener.class);
@Autowired
private ServerConfigService serverConfigService;
@Autowired @Autowired
private ReleaseHistoryService releaseHistoryService; private ReleaseHistoryService releaseHistoryService;
@Autowired @Autowired
...@@ -43,38 +32,14 @@ public class ConfigPublishListener { ...@@ -43,38 +32,14 @@ public class ConfigPublishListener {
private RollbackEmailBuilder rollbackEmailBuilder; private RollbackEmailBuilder rollbackEmailBuilder;
@Autowired @Autowired
private MergeEmailBuilder mergeEmailBuilder; private MergeEmailBuilder mergeEmailBuilder;
@Autowired
private Set<Env> emailSupportedEnvs = new HashSet<>(); private PortalConfig portalConfig;
@PostConstruct
public void init() {
initEmailSupportedEnvs();
}
private void initEmailSupportedEnvs() {
try {
String sendEmailSwitchConfig =
serverConfigService.getValue("email.supported.envs", "");
if (StringUtils.isEmpty(sendEmailSwitchConfig)) {
return;
}
String[] supportedEnvs = sendEmailSwitchConfig.split(",");
for (String env : supportedEnvs) {
emailSupportedEnvs.add(Env.fromString(env.trim()));
}
} catch (Exception e) {
logger.error("init email supported envs failed.", e);
Tracer.logError("init email supported envs failed.", e);
}
}
@EventListener @EventListener
public void onConfigPublish(ConfigPublishEvent event) { public void onConfigPublish(ConfigPublishEvent event) {
Env env = event.getConfigPublishInfo().getEnv(); Env env = event.getConfigPublishInfo().getEnv();
if (!emailSupportedEnvs.contains(env)) { if (!portalConfig.emailSupportedEnvs().contains(env)) {
return; return;
} }
......
package com.ctrip.framework.apollo.portal.service;
import com.google.common.collect.Maps;
import com.ctrip.framework.apollo.common.config.RefreshablePropertySource;
import com.ctrip.framework.apollo.portal.entity.po.ServerConfig;
import com.ctrip.framework.apollo.portal.repository.ServerConfigRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Objects;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Component
public class PortalDBPropertySource extends RefreshablePropertySource {
private static final Logger logger = LoggerFactory.getLogger(PortalDBPropertySource.class);
@Autowired
private ServerConfigRepository serverConfigRepository;
public PortalDBPropertySource(String name, Map<String, Object> source) {
super(name, source);
}
public PortalDBPropertySource() {
super("DBConfig", Maps.newConcurrentMap());
}
@Override
protected void refresh() {
Iterable<ServerConfig> dbConfigs = serverConfigRepository.findAll();
for (ServerConfig config: dbConfigs) {
String key = config.getKey();
Object value = config.getValue();
if (this.source.isEmpty()) {
logger.info("Load config from DB : {} = {}", key, value);
} else if (!Objects.equals(this.source.get(key), value)) {
logger.info("Load config from DB : {} = {}. Old value = {}", key,
value, this.source.get(key));
}
this.source.put(key, value);
}
}
}
package com.ctrip.framework.apollo.portal.service; package com.ctrip.framework.apollo.portal.service;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.FluentIterable; import com.google.common.collect.FluentIterable;
import com.google.common.collect.HashMultimap; import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import com.ctrip.framework.apollo.portal.entity.po.Permission; import com.ctrip.framework.apollo.portal.entity.po.Permission;
import com.ctrip.framework.apollo.portal.entity.po.Role; import com.ctrip.framework.apollo.portal.entity.po.Role;
import com.ctrip.framework.apollo.portal.entity.po.RolePermission; import com.ctrip.framework.apollo.portal.entity.po.RolePermission;
...@@ -19,7 +17,6 @@ import com.ctrip.framework.apollo.portal.repository.RolePermissionRepository; ...@@ -19,7 +17,6 @@ import com.ctrip.framework.apollo.portal.repository.RolePermissionRepository;
import com.ctrip.framework.apollo.portal.repository.RoleRepository; import com.ctrip.framework.apollo.portal.repository.RoleRepository;
import com.ctrip.framework.apollo.portal.repository.UserRoleRepository; import com.ctrip.framework.apollo.portal.repository.UserRoleRepository;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -35,7 +32,7 @@ import java.util.Set; ...@@ -35,7 +32,7 @@ import java.util.Set;
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
@Service @Service
public class RolePermissionService implements InitializingBean { public class RolePermissionService {
@Autowired @Autowired
private RoleRepository roleRepository; private RoleRepository roleRepository;
...@@ -46,17 +43,9 @@ public class RolePermissionService implements InitializingBean { ...@@ -46,17 +43,9 @@ public class RolePermissionService implements InitializingBean {
@Autowired @Autowired
private PermissionRepository permissionRepository; private PermissionRepository permissionRepository;
@Autowired @Autowired
private ServerConfigService serverConfigService; private PortalConfig portalConfig;
private List<String> superAdminUsers;
private Splitter configSplitter;
public RolePermissionService() {
superAdminUsers = Lists.newArrayList();
configSplitter = Splitter.on(",").omitEmptyStrings().trimResults();
}
/** /**
* Create role with permissions, note that role name should be unique * Create role with permissions, note that role name should be unique
*/ */
...@@ -198,7 +187,7 @@ public class RolePermissionService implements InitializingBean { ...@@ -198,7 +187,7 @@ public class RolePermissionService implements InitializingBean {
} }
public boolean isSuperAdmin(String userId) { public boolean isSuperAdmin(String userId) {
return superAdminUsers.contains(userId); return portalConfig.superAdmins().contains(userId);
} }
/** /**
...@@ -239,12 +228,4 @@ public class RolePermissionService implements InitializingBean { ...@@ -239,12 +228,4 @@ public class RolePermissionService implements InitializingBean {
return FluentIterable.from(results).toSet(); return FluentIterable.from(results).toSet();
} }
@Override
public void afterPropertiesSet() throws Exception {
String superAdminConfig = serverConfigService.getValue("superAdmin");
if (Strings.isNullOrEmpty(superAdminConfig)) {
return;
}
superAdminUsers = configSplitter.splitToList(superAdminConfig);
}
} }
package com.ctrip.framework.apollo.portal.service;
import com.ctrip.framework.apollo.portal.entity.po.ServerConfig;
import com.ctrip.framework.apollo.portal.repository.ServerConfigRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
/**
* @author Jason Song(song_s@ctrip.com)
*/
@Service
public class ServerConfigService {
@Autowired
private ServerConfigRepository serverConfigRepository;
@Autowired
private Environment environment;
public String getValue(String key) {
if (environment.containsProperty(key)) {
return environment.getProperty(key);
}
ServerConfig serverConfig = serverConfigRepository.findByKey(key);
return serverConfig == null ? null : serverConfig.getValue();
}
public String getValue(String key, String defaultValue) {
String value = getValue(key);
return value == null ? defaultValue : value;
}
}
...@@ -2,10 +2,7 @@ package com.ctrip.framework.apollo.portal.spi.configuration; ...@@ -2,10 +2,7 @@ package com.ctrip.framework.apollo.portal.spi.configuration;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.ctrip.framework.apollo.openapi.filter.ConsumerAuthenticationFilter; import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import com.ctrip.framework.apollo.openapi.util.ConsumerAuditUtil;
import com.ctrip.framework.apollo.openapi.util.ConsumerAuthUtil;
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import com.ctrip.framework.apollo.portal.spi.LogoutHandler; import com.ctrip.framework.apollo.portal.spi.LogoutHandler;
import com.ctrip.framework.apollo.portal.spi.SsoHeartbeatHandler; import com.ctrip.framework.apollo.portal.spi.SsoHeartbeatHandler;
import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; import com.ctrip.framework.apollo.portal.spi.UserInfoHolder;
...@@ -44,7 +41,7 @@ public class AuthConfiguration { ...@@ -44,7 +41,7 @@ public class AuthConfiguration {
static class CtripAuthAutoConfiguration { static class CtripAuthAutoConfiguration {
@Autowired @Autowired
private ServerConfigService serverConfigService; private PortalConfig portalConfig;
@Bean @Bean
public ServletListenerRegistrationBean redisAppSettingListner() { public ServletListenerRegistrationBean redisAppSettingListner() {
...@@ -76,8 +73,8 @@ public class AuthConfiguration { ...@@ -76,8 +73,8 @@ public class AuthConfiguration {
Map<String, String> filterInitParam = Maps.newHashMap(); Map<String, String> filterInitParam = Maps.newHashMap();
filterInitParam.put("redisClusterName", "casClientPrincipal"); filterInitParam.put("redisClusterName", "casClientPrincipal");
filterInitParam.put("serverName", serverConfigService.getValue("serverName")); filterInitParam.put("serverName", portalConfig.portalServerName());
filterInitParam.put("casServerLoginUrl", serverConfigService.getValue("casServerLoginUrl")); filterInitParam.put("casServerLoginUrl", portalConfig.casServerLoginUrl());
//we don't want to use session to store login information, since we will be deployed to a cluster, not a single instance //we don't want to use session to store login information, since we will be deployed to a cluster, not a single instance
filterInitParam.put("useSession", "false"); filterInitParam.put("useSession", "false");
filterInitParam.put("/openapi.*", "exclude"); filterInitParam.put("/openapi.*", "exclude");
...@@ -94,8 +91,8 @@ public class AuthConfiguration { ...@@ -94,8 +91,8 @@ public class AuthConfiguration {
public FilterRegistrationBean casValidationFilter() { public FilterRegistrationBean casValidationFilter() {
FilterRegistrationBean casValidationFilter = new FilterRegistrationBean(); FilterRegistrationBean casValidationFilter = new FilterRegistrationBean();
Map<String, String> filterInitParam = Maps.newHashMap(); Map<String, String> filterInitParam = Maps.newHashMap();
filterInitParam.put("casServerUrlPrefix", serverConfigService.getValue("casServerUrlPrefix")); filterInitParam.put("casServerUrlPrefix", portalConfig.casServerUrlPrefix());
filterInitParam.put("serverName", serverConfigService.getValue("serverName")); filterInitParam.put("serverName", portalConfig.portalServerName());
filterInitParam.put("encoding", "UTF-8"); filterInitParam.put("encoding", "UTF-8");
//we don't want to use session to store login information, since we will be deployed to a cluster, not a single instance //we don't want to use session to store login information, since we will be deployed to a cluster, not a single instance
filterInitParam.put("useSession", "false"); filterInitParam.put("useSession", "false");
...@@ -163,8 +160,8 @@ public class AuthConfiguration { ...@@ -163,8 +160,8 @@ public class AuthConfiguration {
} }
@Bean @Bean
public UserService ctripUserService(ServerConfigService serverConfigService) { public UserService ctripUserService(PortalConfig portalConfig) {
return new CtripUserService(serverConfigService); return new CtripUserService(portalConfig);
} }
@Bean @Bean
......
package com.ctrip.framework.apollo.portal.spi.ctrip; package com.ctrip.framework.apollo.portal.spi.ctrip;
import com.ctrip.framework.apollo.common.customize.LoggingCustomizer; import com.ctrip.framework.apollo.common.customize.LoggingCustomizer;
import com.ctrip.framework.apollo.portal.service.ServerConfigService; import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
...@@ -11,28 +11,16 @@ import org.springframework.stereotype.Component; ...@@ -11,28 +11,16 @@ import org.springframework.stereotype.Component;
@Profile("ctrip") @Profile("ctrip")
public class BizLoggingCustomizer extends LoggingCustomizer { public class BizLoggingCustomizer extends LoggingCustomizer {
private static final String CLOGGING_SERVER_URL_KEY = "clogging.server.url";
private static final String CLOGGING_SERVER_PORT_KEY = "clogging.server.port";
@Autowired @Autowired
private ServerConfigService serverConfigService; private PortalConfig portalConfig;
private String cloggingUrl;
private String cloggingPort;
@Override @Override
protected String cloggingUrl() { protected String cloggingUrl() {
if (cloggingUrl == null) { return portalConfig.cloggingUrl();
cloggingUrl = serverConfigService.getValue(CLOGGING_SERVER_URL_KEY);
}
return cloggingUrl;
} }
@Override @Override
protected String cloggingPort() { protected String cloggingPort() {
if (cloggingPort == null) { return portalConfig.cloggingPort();
cloggingPort = serverConfigService.getValue(CLOGGING_SERVER_PORT_KEY);
}
return cloggingPort;
} }
} }
package com.ctrip.framework.apollo.portal.spi.ctrip; package com.ctrip.framework.apollo.portal.spi.ctrip;
import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import com.ctrip.framework.apollo.portal.entity.bo.Email; import com.ctrip.framework.apollo.portal.entity.bo.Email;
import com.ctrip.framework.apollo.tracer.Tracer; import com.ctrip.framework.apollo.tracer.Tracer;
import org.apache.commons.lang.time.DateUtils; import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import java.lang.reflect.Method; import java.lang.reflect.Method;
...@@ -31,16 +33,8 @@ public class CtripEmailRequestBuilder { ...@@ -31,16 +33,8 @@ public class CtripEmailRequestBuilder {
private static Method setExpiredTime; private static Method setExpiredTime;
private static Method setAppID; private static Method setAppID;
@Value("${ctrip.appid}") @Autowired
private int appId; private PortalConfig portalConfig;
//send code & template id. apply from ewatch
@Value("${ctrip.email.send.code}")
private String sendCode;
@Value("${ctrip.email.template.id}")
private int templateId;
//email retention time in email server queue.TimeUnit: hour
@Value("${ctrip.email.survival.duration}")
private int survivalDuration;
@PostConstruct @PostConstruct
...@@ -81,12 +75,12 @@ public class CtripEmailRequestBuilder { ...@@ -81,12 +75,12 @@ public class CtripEmailRequestBuilder {
private Object createBasicEmailRequest() throws Exception { private Object createBasicEmailRequest() throws Exception {
Object request = sendEmailRequestClazz.newInstance(); Object request = sendEmailRequestClazz.newInstance();
setSendCode.invoke(request, sendCode); setSendCode.invoke(request, portalConfig.sendCode());
setBodyTemplateID.invoke(request, templateId); setBodyTemplateID.invoke(request, portalConfig.templateId());
setIsBodyHtml.invoke(request, true); setIsBodyHtml.invoke(request, true);
setCharset.invoke(request, "UTF-8"); setCharset.invoke(request, "UTF-8");
setExpiredTime.invoke(request, calExpiredTime()); setExpiredTime.invoke(request, calExpiredTime());
setAppID.invoke(request, appId); setAppID.invoke(request, portalConfig.appId());
return request; return request;
} }
...@@ -95,7 +89,7 @@ public class CtripEmailRequestBuilder { ...@@ -95,7 +89,7 @@ public class CtripEmailRequestBuilder {
private Calendar calExpiredTime() { private Calendar calExpiredTime() {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTime(DateUtils.addHours(new Date(), survivalDuration)); calendar.setTime(DateUtils.addHours(new Date(), portalConfig.survivalDuration()));
return calendar; return calendar;
} }
......
package com.ctrip.framework.apollo.portal.spi.ctrip; package com.ctrip.framework.apollo.portal.spi.ctrip;
import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import com.ctrip.framework.apollo.portal.entity.bo.Email; import com.ctrip.framework.apollo.portal.entity.bo.Email;
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import com.ctrip.framework.apollo.portal.spi.EmailService; import com.ctrip.framework.apollo.portal.spi.EmailService;
import com.ctrip.framework.apollo.tracer.Tracer; import com.ctrip.framework.apollo.tracer.Tracer;
...@@ -25,7 +25,7 @@ public class CtripEmailService implements EmailService { ...@@ -25,7 +25,7 @@ public class CtripEmailService implements EmailService {
@Autowired @Autowired
private CtripEmailRequestBuilder emailRequestBuilder; private CtripEmailRequestBuilder emailRequestBuilder;
@Autowired @Autowired
private ServerConfigService serverConfigService; private PortalConfig portalConfig;
@PostConstruct @PostConstruct
public void init() { public void init() {
...@@ -52,8 +52,7 @@ public class CtripEmailService implements EmailService { ...@@ -52,8 +52,7 @@ public class CtripEmailService implements EmailService {
Object serviceClientConfig = serviceClientConfigClazz.newInstance(); Object serviceClientConfig = serviceClientConfigClazz.newInstance();
Method setFxConfigServiceUrlMethod = serviceClientConfigClazz.getMethod("setFxConfigServiceUrl", String.class); Method setFxConfigServiceUrlMethod = serviceClientConfigClazz.getMethod("setFxConfigServiceUrl", String.class);
String soaServerAddress = serverConfigService.getValue("soa.server.address"); setFxConfigServiceUrlMethod.invoke(serviceClientConfig, portalConfig.soaServerAddress());
setFxConfigServiceUrlMethod.invoke(serviceClientConfig, soaServerAddress);
Class serviceClientBaseClazz = Class.forName("com.ctriposs.baiji.rpc.client.ServiceClientBase"); Class serviceClientBaseClazz = Class.forName("com.ctriposs.baiji.rpc.client.ServiceClientBase");
Method initializeMethod = serviceClientBaseClazz.getMethod("initialize", serviceClientConfigClazz); Method initializeMethod = serviceClientBaseClazz.getMethod("initialize", serviceClientConfigClazz);
......
package com.ctrip.framework.apollo.portal.spi.ctrip; package com.ctrip.framework.apollo.portal.spi.ctrip;
import com.ctrip.framework.apollo.portal.service.ServerConfigService; import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import com.ctrip.framework.apollo.portal.spi.LogoutHandler; import com.ctrip.framework.apollo.portal.spi.LogoutHandler;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -15,7 +15,7 @@ import javax.servlet.http.HttpSession; ...@@ -15,7 +15,7 @@ import javax.servlet.http.HttpSession;
public class CtripLogoutHandler implements LogoutHandler { public class CtripLogoutHandler implements LogoutHandler {
@Autowired @Autowired
private ServerConfigService serverConfigService; private PortalConfig portalConfig;
@Override @Override
public void logout(HttpServletRequest request, HttpServletResponse response) { public void logout(HttpServletRequest request, HttpServletResponse response) {
...@@ -32,8 +32,8 @@ public class CtripLogoutHandler implements LogoutHandler { ...@@ -32,8 +32,8 @@ public class CtripLogoutHandler implements LogoutHandler {
response.addCookie(cookie); response.addCookie(cookie);
//重定向到SSO的logout地址 //重定向到SSO的logout地址
String casServerUrl = serverConfigService.getValue("casServerUrlPrefix"); String casServerUrl = portalConfig.casServerUrlPrefix();
String serverName = serverConfigService.getValue("serverName"); String serverName = portalConfig.portalServerName();
try { try {
response.sendRedirect(casServerUrl + "/logout?service=" + serverName); response.sendRedirect(casServerUrl + "/logout?service=" + serverName);
......
...@@ -4,8 +4,8 @@ import com.google.common.collect.ImmutableMap; ...@@ -4,8 +4,8 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; import com.ctrip.framework.apollo.portal.entity.bo.UserInfo;
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import com.ctrip.framework.apollo.portal.spi.UserService; import com.ctrip.framework.apollo.portal.spi.UserService;
import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ParameterizedTypeReference;
...@@ -18,24 +18,21 @@ import org.springframework.util.CollectionUtils; ...@@ -18,24 +18,21 @@ import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* @author Jason Song(song_s@ctrip.com) * @author Jason Song(song_s@ctrip.com)
*/ */
public class CtripUserService implements UserService { public class CtripUserService implements UserService {
private ServerConfigService serverConfigService;
private RestTemplate restTemplate; private RestTemplate restTemplate;
private List<String> searchUserMatchFields; private List<String> searchUserMatchFields;
private ParameterizedTypeReference<Map<String, List<UserServiceResponse>>> responseType; private ParameterizedTypeReference<Map<String, List<UserServiceResponse>>> responseType;
private PortalConfig portalConfig;
public CtripUserService(PortalConfig portalConfig) {
public CtripUserService(ServerConfigService serverConfigService) { this.portalConfig = portalConfig;
this.serverConfigService = serverConfigService;
this.restTemplate = new RestTemplate(clientHttpRequestFactory()); this.restTemplate = new RestTemplate(clientHttpRequestFactory());
this.searchUserMatchFields = this.searchUserMatchFields =
Lists.newArrayList("empcode", "empaccount", "displayname", "c_name", "pinyin"); Lists.newArrayList("empcode", "empaccount", "displayname", "c_name", "pinyin");
...@@ -45,31 +42,19 @@ public class CtripUserService implements UserService { ...@@ -45,31 +42,19 @@ public class CtripUserService implements UserService {
private ClientHttpRequestFactory clientHttpRequestFactory() { private ClientHttpRequestFactory clientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(getConnectTimeout()); factory.setConnectTimeout(portalConfig.connectTimeout());
factory.setReadTimeout(getReadTimeout()); factory.setReadTimeout(portalConfig.readTimeout());
return factory; return factory;
} }
private int getConnectTimeout() {
String connectTimeout = serverConfigService.getValue("api.connectTimeout", "3000");
return Integer.parseInt(connectTimeout);
}
private int getReadTimeout() {
String readTimeout = serverConfigService.getValue("api.readTimeout", "3000");
return Integer.parseInt(readTimeout);
}
@Override @Override
public List<UserInfo> searchUsers(String keyword, int offset, int limit) { public List<UserInfo> searchUsers(String keyword, int offset, int limit) {
UserServiceRequest request = assembleSearchUserRequest(keyword, offset, limit); UserServiceRequest request = assembleSearchUserRequest(keyword, offset, limit);
HttpEntity<UserServiceRequest> entity = new HttpEntity<>(request); HttpEntity<UserServiceRequest> entity = new HttpEntity<>(request);
ResponseEntity<Map<String, List<UserServiceResponse>>> response = ResponseEntity<Map<String, List<UserServiceResponse>>> response =
restTemplate.exchange(getUserServiceUrl(), HttpMethod.POST, entity, responseType); restTemplate.exchange(portalConfig.userServiceUrl(), HttpMethod.POST, entity, responseType);
if (!response.getBody().containsKey("result")) { if (!response.getBody().containsKey("result")) {
return Collections.emptyList(); return Collections.emptyList();
...@@ -97,7 +82,7 @@ public class CtripUserService implements UserService { ...@@ -97,7 +82,7 @@ public class CtripUserService implements UserService {
HttpEntity<UserServiceRequest> entity = new HttpEntity<>(request); HttpEntity<UserServiceRequest> entity = new HttpEntity<>(request);
ResponseEntity<Map<String, List<UserServiceResponse>>> response = ResponseEntity<Map<String, List<UserServiceResponse>>> response =
restTemplate.exchange(getUserServiceUrl(), HttpMethod.POST, entity, responseType); restTemplate.exchange(portalConfig.userServiceUrl(), HttpMethod.POST, entity, responseType);
if (!response.getBody().containsKey("result")) { if (!response.getBody().containsKey("result")) {
return Collections.emptyList(); return Collections.emptyList();
...@@ -143,7 +128,7 @@ public class CtripUserService implements UserService { ...@@ -143,7 +128,7 @@ public class CtripUserService implements UserService {
private UserServiceRequest assembleUserServiceRequest(Map<String, Object> query, int offset, private UserServiceRequest assembleUserServiceRequest(Map<String, Object> query, int offset,
int limit) { int limit) {
UserServiceRequest request = new UserServiceRequest(); UserServiceRequest request = new UserServiceRequest();
request.setAccess_token(getUserServiceAccessToken()); request.setAccess_token(portalConfig.userServiceAccessToken());
UserServiceRequestBody requestBody = new UserServiceRequestBody(); UserServiceRequestBody requestBody = new UserServiceRequestBody();
requestBody.setIndexAlias("itdb_emloyee"); requestBody.setIndexAlias("itdb_emloyee");
...@@ -162,14 +147,6 @@ public class CtripUserService implements UserService { ...@@ -162,14 +147,6 @@ public class CtripUserService implements UserService {
} }
private String getUserServiceUrl() {
return serverConfigService.getValue("userService.url");
}
private String getUserServiceAccessToken() {
return serverConfigService.getValue("userService.accessToken");
}
static class UserServiceRequest { static class UserServiceRequest {
private String access_token; private String access_token;
private UserServiceRequestBody request_body; private UserServiceRequestBody request_body;
......
...@@ -2,7 +2,7 @@ package com.ctrip.framework.apollo.portal.spi.ctrip; ...@@ -2,7 +2,7 @@ package com.ctrip.framework.apollo.portal.spi.ctrip;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.ctrip.framework.apollo.portal.service.ServerConfigService; import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; import com.ctrip.framework.apollo.portal.spi.UserInfoHolder;
import com.ctrip.framework.apollo.portal.spi.ctrip.filters.RecordAccessUserFilter; import com.ctrip.framework.apollo.portal.spi.ctrip.filters.RecordAccessUserFilter;
...@@ -21,7 +21,7 @@ import javax.servlet.ServletException; ...@@ -21,7 +21,7 @@ import javax.servlet.ServletException;
public class WebContextConfiguration { public class WebContextConfiguration {
@Autowired @Autowired
private ServerConfigService serverConfigService; private PortalConfig portalConfig;
@Autowired @Autowired
private UserInfoHolder userInfoHolder; private UserInfoHolder userInfoHolder;
...@@ -32,9 +32,10 @@ public class WebContextConfiguration { ...@@ -32,9 +32,10 @@ public class WebContextConfiguration {
@Override @Override
public void onStartup(ServletContext servletContext) throws ServletException { public void onStartup(ServletContext servletContext) throws ServletException {
String loggingServerIP = serverConfigService.getValue("clogging.server.url"); String loggingServerIP = portalConfig.cloggingUrl();
String loggingServerPort = serverConfigService.getValue("clogging.server.port"); String loggingServerPort = portalConfig.cloggingUrl();
String credisServiceUrl = serverConfigService.getValue("credisServiceUrl"); String credisServiceUrl = portalConfig.credisServiceUrl();
servletContext.setInitParameter("loggingServerIP", servletContext.setInitParameter("loggingServerIP",
Strings.isNullOrEmpty(loggingServerIP) ? "" : loggingServerIP); Strings.isNullOrEmpty(loggingServerIP) ? "" : loggingServerIP);
servletContext.setInitParameter("loggingServerPort", servletContext.setInitParameter("loggingServerPort",
......
...@@ -19,3 +19,5 @@ management: ...@@ -19,3 +19,5 @@ management:
health: health:
status: status:
order: DOWN, OUT_OF_SERVICE, UNKNOWN, UP order: DOWN, OUT_OF_SERVICE, UNKNOWN, UP
...@@ -4,7 +4,7 @@ import com.ctrip.framework.apollo.openapi.entity.Consumer; ...@@ -4,7 +4,7 @@ import com.ctrip.framework.apollo.openapi.entity.Consumer;
import com.ctrip.framework.apollo.openapi.entity.ConsumerToken; import com.ctrip.framework.apollo.openapi.entity.ConsumerToken;
import com.ctrip.framework.apollo.openapi.repository.ConsumerRepository; import com.ctrip.framework.apollo.openapi.repository.ConsumerRepository;
import com.ctrip.framework.apollo.openapi.repository.ConsumerTokenRepository; import com.ctrip.framework.apollo.openapi.repository.ConsumerTokenRepository;
import com.ctrip.framework.apollo.portal.service.ServerConfigService; import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
...@@ -40,7 +40,7 @@ public class ConsumerServiceTest { ...@@ -40,7 +40,7 @@ public class ConsumerServiceTest {
@Mock @Mock
private ConsumerRepository consumerRepository; private ConsumerRepository consumerRepository;
@Mock @Mock
private ServerConfigService serverConfigService; private PortalConfig portalConfig;
private String someTokenSalt; private String someTokenSalt;
@Before @Before
...@@ -50,12 +50,11 @@ public class ConsumerServiceTest { ...@@ -50,12 +50,11 @@ public class ConsumerServiceTest {
consumerTokenRepository); consumerTokenRepository);
ReflectionTestUtils.setField(consumerService, "consumerRepository", ReflectionTestUtils.setField(consumerService, "consumerRepository",
consumerRepository); consumerRepository);
ReflectionTestUtils.setField(consumerService, "serverConfigService", ReflectionTestUtils.setField(consumerService, "portalConfig",
serverConfigService); portalConfig);
someTokenSalt = "someTokenSalt"; someTokenSalt = "someTokenSalt";
when(serverConfigService.getValue(eq(ConsumerService.TOKEN_SALT_KEY), anyString())).thenReturn(someTokenSalt); when(portalConfig.consumerTokenSalt()).thenReturn(someTokenSalt);
consumerService.afterPropertiesSet();
} }
@Test @Test
......
package com.ctrip.framework.apollo.portal.config;
import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.core.env.ConfigurableEnvironment;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class ConfigTest {
@Mock
private ConfigurableEnvironment environment;
@InjectMocks
private PortalConfig config;
@Test
public void testGetNotExistValue() {
String testKey = "key";
String testDefaultValue = "value";
when(environment.getProperty(testKey)).thenReturn(null);
Assert.assertEquals(testDefaultValue, config.getValue(testKey, testDefaultValue));
}
@Test
public void testGetArrayProperty() {
String testKey = "key";
String testValue = "a,b,c";
when(environment.getProperty(testKey)).thenReturn(testValue);
String[] result = config.getArrayProperty(testKey, "");
Assert.assertEquals(3, result.length);
Assert.assertEquals("a", result[0]);
Assert.assertEquals("b", result[1]);
Assert.assertEquals("c", result[2]);
}
@Test
public void testGetBooleanProperty() {
String testKey = "key";
String testValue = "true";
when(environment.getProperty(testKey)).thenReturn(testValue);
boolean result = config.getBooleanProperty(testKey, false);
Assert.assertTrue(result);
}
@Test
public void testGetIntProperty() {
String testKey = "key";
String testValue = "1024";
when(environment.getProperty(testKey)).thenReturn(testValue);
int result = config.getIntProperty(testKey, 0);
Assert.assertEquals(1024, result);
}
}
...@@ -4,8 +4,8 @@ import com.google.common.collect.ImmutableMap; ...@@ -4,8 +4,8 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.ctrip.framework.apollo.portal.AbstractUnitTest; import com.ctrip.framework.apollo.portal.AbstractUnitTest;
import com.ctrip.framework.apollo.portal.components.config.PortalConfig;
import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; import com.ctrip.framework.apollo.portal.entity.bo.UserInfo;
import com.ctrip.framework.apollo.portal.service.ServerConfigService;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
...@@ -39,16 +39,16 @@ public class CtripUserServiceTest extends AbstractUnitTest{ ...@@ -39,16 +39,16 @@ public class CtripUserServiceTest extends AbstractUnitTest{
someResponseType; someResponseType;
@Mock @Mock
private ServerConfigService serverConfigService; private PortalConfig portalConfig;
@Mock @Mock
private RestTemplate restTemplate; private RestTemplate restTemplate;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
when(serverConfigService.getValue("api.connectTimeout", "3000")).thenReturn("3000"); when(portalConfig.connectTimeout()).thenReturn(3000);
when(serverConfigService.getValue("api.readTimeout", "3000")).thenReturn("3000"); when(portalConfig.readTimeout()).thenReturn(3000);
ctripUserService = new CtripUserService(serverConfigService); ctripUserService = new CtripUserService(portalConfig);
ReflectionTestUtils.setField(ctripUserService, "restTemplate", restTemplate); ReflectionTestUtils.setField(ctripUserService, "restTemplate", restTemplate);
someResponseType = someResponseType =
(ParameterizedTypeReference<Map<String, List<CtripUserService.UserServiceResponse>>>) ReflectionTestUtils (ParameterizedTypeReference<Map<String, List<CtripUserService.UserServiceResponse>>>) ReflectionTestUtils
...@@ -56,8 +56,8 @@ public class CtripUserServiceTest extends AbstractUnitTest{ ...@@ -56,8 +56,8 @@ public class CtripUserServiceTest extends AbstractUnitTest{
someUserServiceUrl = "http://someurl"; someUserServiceUrl = "http://someurl";
someUserServiceToken = "someToken"; someUserServiceToken = "someToken";
when(serverConfigService.getValue("userService.url")).thenReturn(someUserServiceUrl); when(portalConfig.userServiceUrl()).thenReturn(someUserServiceUrl);
when(serverConfigService.getValue("userService.accessToken")).thenReturn(someUserServiceToken); when(portalConfig.userServiceAccessToken()).thenReturn(someUserServiceToken);
} }
......
...@@ -4,3 +4,4 @@ delete from RolePermission; ...@@ -4,3 +4,4 @@ delete from RolePermission;
delete from UserRole; delete from UserRole;
delete from AppNamespace; delete from AppNamespace;
DELETE FROM Favorite; DELETE FROM Favorite;
DELETE FROM ServerConfig;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment