diff --git a/disconf-client/pom.xml b/disconf-client/pom.xml
index 524931042..e36ccec2f 100644
--- a/disconf-client/pom.xml
+++ b/disconf-client/pom.xml
@@ -145,6 +145,20 @@
test
+
+
+ com.netflix.curator
+ curator-test
+ 1.0.20
+ test
+
+
+ com.netflix.curator
+ curator-framework
+ 1.0.20
+ test
+
+
diff --git a/disconf-client/src/main/java/com/baidu/disconf/client/store/processor/impl/DisconfStoreFileProcessorImpl.java b/disconf-client/src/main/java/com/baidu/disconf/client/store/processor/impl/DisconfStoreFileProcessorImpl.java
index 2eed72c01..dbb133008 100644
--- a/disconf-client/src/main/java/com/baidu/disconf/client/store/processor/impl/DisconfStoreFileProcessorImpl.java
+++ b/disconf-client/src/main/java/com/baidu/disconf/client/store/processor/impl/DisconfStoreFileProcessorImpl.java
@@ -213,6 +213,13 @@ public void inject2Store(String fileName, DisconfValue disconfValue) {
Object value = keMap.get(fileItem).getFieldValueByType(object);
keMap.get(fileItem).setValue(value);
+ /** 在first scan的时候就给static的属性赋值,这样在所有的类的static块里也能正确获取到这些static属性的值,
+ * 如果放到second scan才给static的属性赋值,因为那时所有的类都加载结束了,init()的时候才会执行second scan,
+ * 那时类的static块也已经执行完了,就会出现static块里取不到相应的值
+ * */
+ if (keMap.get(fileItem).isStatic()) {
+ keMap.get(fileItem).setValue4StaticFileItem(value);
+ }
} catch (Exception e) {
LOGGER.error("inject2Store filename: " + fileName + " " + e.toString(), e);
diff --git a/disconf-client/src/main/java/com/baidu/disconf/client/store/processor/impl/DisconfStoreItemProcessorImpl.java b/disconf-client/src/main/java/com/baidu/disconf/client/store/processor/impl/DisconfStoreItemProcessorImpl.java
index 0dfd1ef6b..c9f7d3b34 100644
--- a/disconf-client/src/main/java/com/baidu/disconf/client/store/processor/impl/DisconfStoreItemProcessorImpl.java
+++ b/disconf-client/src/main/java/com/baidu/disconf/client/store/processor/impl/DisconfStoreItemProcessorImpl.java
@@ -184,6 +184,13 @@ public void inject2Store(String key, DisconfValue disconfValue) {
Object newValue = disconfCenterItem.getFieldValueByType(disconfValue.getValue());
disconfCenterItem.setValue(newValue);
+ /** 在first scan的时候就给static的属性赋值,这样在所有的类的static块里也能正确获取到这些static属性的值,
+ * 如果放到second scan才给static的属性赋值,因为那时所有的类都加载结束了,init()的时候才会执行second scan,
+ * 那时类的static块也已经执行完了,就会出现static块里取不到相应的值
+ * */
+ if (disconfCenterItem.isStatic()) {
+ disconfCenterItem.setValue4StaticFileItem(newValue);
+ }
} catch (Exception e) {
LOGGER.error("key: " + key + " " + e.toString(), e);
diff --git a/disconf-client/src/test/java/com/baidu/disconf/client/test/DisconfMgrTestCase.java b/disconf-client/src/test/java/com/baidu/disconf/client/test/DisconfMgrTestCase.java
index 38a35ebcf..3db82fb90 100644
--- a/disconf-client/src/test/java/com/baidu/disconf/client/test/DisconfMgrTestCase.java
+++ b/disconf-client/src/test/java/com/baidu/disconf/client/test/DisconfMgrTestCase.java
@@ -1,38 +1,40 @@
package com.baidu.disconf.client.test;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-
import com.baidu.disconf.client.DisconfMgr;
import com.baidu.disconf.client.DisconfMgrBean;
-import com.baidu.disconf.client.core.DisconfCoreFactory;
-import com.baidu.disconf.client.core.DisconfCoreMgr;
-import com.baidu.disconf.client.core.impl.DisconfCoreMgrImpl;
-import com.baidu.disconf.client.fetcher.FetcherFactory;
-import com.baidu.disconf.client.fetcher.FetcherMgr;
import com.baidu.disconf.client.store.DisconfStoreProcessorFactory;
import com.baidu.disconf.client.store.inner.DisconfCenterHostFilesStore;
-import com.baidu.disconf.client.support.registry.Registry;
import com.baidu.disconf.client.support.utils.StringUtil;
import com.baidu.disconf.client.test.common.BaseSpringMockTestCase;
import com.baidu.disconf.client.test.model.ConfA;
import com.baidu.disconf.client.test.model.ServiceA;
import com.baidu.disconf.client.test.model.StaticConf;
import com.baidu.disconf.client.test.scan.inner.ScanPackTestCase;
-import com.baidu.disconf.client.test.watch.mock.WatchMgrMock;
import com.baidu.disconf.client.usertools.DisconfDataGetter;
-import com.baidu.disconf.client.watch.WatchMgr;
+import com.baidu.disconf.core.common.constants.Constants;
+import com.baidu.disconf.core.common.json.ValueVo;
+import com.baidu.disconf.core.common.utils.GsonUtils;
+import com.baidu.disconf.core.common.zookeeper.ZookeeperMgr;
+import com.baidu.disconf.core.test.restful.RemoteMockServer;
+import com.netflix.curator.framework.CuratorFramework;
+import com.netflix.curator.framework.CuratorFrameworkFactory;
+import com.netflix.curator.framework.state.ConnectionState;
+import com.netflix.curator.framework.state.ConnectionStateListener;
+import com.netflix.curator.retry.ExponentialBackoffRetry;
+import com.netflix.curator.test.TestingServer;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
-import mockit.Mock;
-import mockit.MockUp;
+import java.util.HashSet;
+import java.util.Set;
+
+import static com.baidu.disconf.core.test.restful.RemoteMockServer.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.*;
/**
* 一个Demo示例, 远程的下载服务器使用WireMOck, Watch模块使用Jmockit
@@ -55,28 +57,20 @@ public class DisconfMgrTestCase extends BaseSpringMockTestCase implements Applic
@Test
public void demo() {
-
- //
- // mock up factory method
- //
- new MockUp() {
-
- @Mock
- public DisconfCoreMgr getDisconfCoreMgr(Registry registry) throws Exception {
-
- FetcherMgr fetcherMgr = FetcherFactory.getFetcherMgr();
-
- // Watch 模块
- final WatchMgr watchMgr = new WatchMgrMock().getMockInstance();
- watchMgr.init("", "", true);
-
- // registry
- DisconfCoreMgr disconfCoreMgr = new DisconfCoreMgrImpl(watchMgr, fetcherMgr,
- registry);
-
- return disconfCoreMgr;
- }
- };
+ try {
+ // 使用curator模拟zk
+ TestingServer server = new TestingServer(ZOO_PORT);
+ CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(1000, 3));
+ client.getConnectionStateListenable().addListener(new ConnectionStateListener() {
+ @Override
+ public void stateChanged(CuratorFramework curatorFramework, ConnectionState connectionState) {
+ System.out.println("连接状态:" + connectionState.name());
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ Assert.assertTrue(false);
+ }
//
// 正式测试
@@ -89,6 +83,7 @@ public DisconfCoreMgr getDisconfCoreMgr(Registry registry) throws Exception {
LOGGER.info(String.valueOf("varA: " + confA.getVarA()));
LOGGER.info(String.valueOf("varA2: " + confA.getVarA2()));
LOGGER.info(String.valueOf("varAA: " + serviceA.getVarAA()));
+ LOGGER.info(String.valueOf("varAAStatic: " + serviceA.getVarAAStatic()));
LOGGER.info("================ BEFORE DISCONF ==============================");
@@ -115,15 +110,56 @@ public DisconfCoreMgr getDisconfCoreMgr(Registry registry) throws Exception {
LOGGER.info(String.valueOf("varA: " + confA.getVarA()));
Assert.assertEquals(new Long(1000), confA.getVarA());
+ // 修改配置文件的值
+ stubFor(get(urlEqualTo(RemoteMockServer.FILE_URL))
+ .willReturn(aResponse().withHeader("Content-Type", "text/html;charset=UTF-8")
+ .withHeader("Content-Disposition",
+ "attachment; filename=" + RemoteMockServer.FILE_NAME).withStatus(200)
+ .withBody(FILE_CONTENT_NEW.getBytes())));
+ // 通知zk
+ ZookeeperMgr.getInstance().writePersistentUrl(ZOO_FILE_UPDATE_PATH, GsonUtils.toJson(FILE_CONTENT_NEW));
+
+ Thread.sleep(1000);
+
+ // 获取修改后的值
+ LOGGER.info(String.valueOf("varA new: " + confA.getVarA()));
+ Assert.assertEquals(new Long(9999), confA.getVarA());
+
LOGGER.info(String.valueOf("varA2: " + confA.getVarA2()));
Assert.assertEquals(new Long(2000), confA.getVarA2());
LOGGER.info(String.valueOf("varAA: " + serviceA.getVarAA()));
Assert.assertEquals(new Integer(1000).intValue(), serviceA.getVarAA());
+ // 修改配置项的值
+ ValueVo valueVo = new ValueVo();
+ valueVo.setMessage("");
+ valueVo.setStatus(Constants.OK);
+ valueVo.setValue(RemoteMockServer.DEFAULT_ITEM_VALUE_NEW);
+ stubFor(get(urlEqualTo(RemoteMockServer.ITEM_URL))
+ .willReturn(aResponse().withHeader("Content-Type", RemoteMockServer.CONTENT_TYPE).withStatus(200)
+ .withBody(GsonUtils.toJson(valueVo))));
+ // 通知zk
+ ZookeeperMgr.getInstance().writePersistentUrl(ZOO_ITEM_UPDATE_PATH, RemoteMockServer.DEFAULT_ITEM_VALUE_NEW);
+
+ Thread.sleep(1000);
+
+ // 获取修改后的值
+ LOGGER.info(String.valueOf("varAA new: " + serviceA.getVarAA()));
+ Assert.assertEquals(new Integer(8888).intValue(), serviceA.getVarAA());
+
+ LOGGER.info(String.valueOf("varAAStatic: " + serviceA.getVarAAStatic()));
+ Assert.assertEquals(new Integer(2001).intValue(), serviceA.getVarAAStatic());
+
+ LOGGER.info(String.valueOf("varBBStatic: " + serviceA.getVarBBStatic()));
+ Assert.assertEquals(new Integer(3001).intValue(), serviceA.getVarBBStatic());
+
LOGGER.info(String.valueOf("static var: " + StaticConf.getStaticvar()));
Assert.assertEquals(new Integer(50).intValue(), StaticConf.getStaticvar());
+ LOGGER.info(String.valueOf("static var: " + StaticConf.getStaticvar3()));
+ Assert.assertEquals(new Integer(4001).intValue(), StaticConf.getStaticvar3());
+
testDynamicGetter();
LOGGER.info("================ AFTER DISCONF ==============================");
@@ -138,13 +174,13 @@ public DisconfCoreMgr getDisconfCoreMgr(Registry registry) throws Exception {
private void testDynamicGetter() {
Assert.assertEquals(DisconfDataGetter.getByFile("confA.properties").get("confa.varA").toString(),
- "1000");
+ "9999");
Assert.assertEquals(DisconfDataGetter.getByItem("keyA").toString(),
- "1000");
+ "8888");
Assert.assertEquals(DisconfDataGetter.getByFileItem("confA.properties", "confa.varA").toString(),
- "1000");
+ "9999");
}
public ApplicationContext getApplicationContext() {
diff --git a/disconf-client/src/test/java/com/baidu/disconf/client/test/model/ServiceA.java b/disconf-client/src/test/java/com/baidu/disconf/client/test/model/ServiceA.java
index 3fdd3c35f..35b884fd1 100644
--- a/disconf-client/src/test/java/com/baidu/disconf/client/test/model/ServiceA.java
+++ b/disconf-client/src/test/java/com/baidu/disconf/client/test/model/ServiceA.java
@@ -23,6 +23,20 @@ public class ServiceA {
public static final String keyA = "keyA";
+ /**
+ * 2. 用于静态方式获取的分布式配置项
+ */
+ private static int varAAStatic = 20;
+
+ public static final String staticKeyA = "staticKeyA";
+
+ /**
+ * 3. 用于静态方式获取的分布式配置项,且没有setter方法,用于测试反射
+ */
+ private static int varBBStatic = 30;
+
+ public static final String staticKeyB = "staticKeyB";
+
@Autowired
private ConfA confA;
@@ -43,4 +57,17 @@ public void setVarAA(int varAA) {
this.varAA = varAA;
}
+ @DisconfItem(key = ServiceA.staticKeyA)
+ public static int getVarAAStatic() {
+ return varAAStatic;
+ }
+
+ public static void setVarAAStatic(int varAAStatic) {
+ ServiceA.varAAStatic = varAAStatic;
+ }
+
+ @DisconfItem(key = ServiceA.staticKeyB)
+ public static int getVarBBStatic() {
+ return varBBStatic;
+ }
}
diff --git a/disconf-client/src/test/java/com/baidu/disconf/client/test/model/StaticConf.java b/disconf-client/src/test/java/com/baidu/disconf/client/test/model/StaticConf.java
index 13c5aef90..2d006769a 100644
--- a/disconf-client/src/test/java/com/baidu/disconf/client/test/model/StaticConf.java
+++ b/disconf-client/src/test/java/com/baidu/disconf/client/test/model/StaticConf.java
@@ -16,6 +16,9 @@ public class StaticConf {
private static double staticvar2 = 50;
+ // 用于测试没有setter方法的静态配置文件
+ private static int staticvar3 = 60;
+
@DisconfFileItem(name = "staticvar", associateField = "staticvar")
public static int getStaticVar() {
return staticvar;
@@ -41,4 +44,9 @@ public static double getStaticvar2() {
public static void setStaticvar2(double staticvar2) {
StaticConf.staticvar2 = staticvar2;
}
+
+ @DisconfFileItem(name = "staticvar3", associateField = "staticvar3")
+ public static int getStaticvar3() {
+ return staticvar3;
+ }
}
diff --git a/disconf-client/src/test/java/com/baidu/disconf/client/test/scan/inner/ScanPackTestCase.java b/disconf-client/src/test/java/com/baidu/disconf/client/test/scan/inner/ScanPackTestCase.java
index abfc2b03e..973595068 100644
--- a/disconf-client/src/test/java/com/baidu/disconf/client/test/scan/inner/ScanPackTestCase.java
+++ b/disconf-client/src/test/java/com/baidu/disconf/client/test/scan/inner/ScanPackTestCase.java
@@ -48,7 +48,7 @@ public void scan() {
LOGGER.info("=============DISCONF FILE ITEM===================");
Set methods = scanModel.getDisconfFileItemMethodSet();
ScanPrinterUtils.printFileItemMethod(methods);
- Assert.assertEquals(6, methods.size());
+ Assert.assertEquals(7, methods.size());
Assert.assertEquals(4, scanModel.getDisconfFileClassSet().size());
// disconf file item
@@ -60,7 +60,7 @@ public void scan() {
LOGGER.info("=============DISCONF ITEM===================");
methods = scanModel.getDisconfItemMethodSet();
ScanPrinterUtils.printFileItemMethod(methods);
- Assert.assertEquals(1, methods.size());
+ Assert.assertEquals(3, methods.size());
// Active backup
LOGGER.info("=============DISCONF ACTIVE BACKUP===================");
diff --git a/disconf-core/src/test/java/com/baidu/disconf/core/test/common/BaseCoreTestCase.java b/disconf-core/src/test/java/com/baidu/disconf/core/test/common/BaseCoreTestCase.java
index 195e98384..f4c9ad01f 100644
--- a/disconf-core/src/test/java/com/baidu/disconf/core/test/common/BaseCoreTestCase.java
+++ b/disconf-core/src/test/java/com/baidu/disconf/core/test/common/BaseCoreTestCase.java
@@ -59,6 +59,28 @@ private static void setupRemoteData() {
.willReturn(aResponse().withHeader("Content-Type", RemoteMockServer.CONTENT_TYPE).withStatus(200)
.withBody(GsonUtils.toJson(valueVo))));
+ //
+ // 静态配置项
+ //
+ ValueVo valueVoStatic = new ValueVo();
+ valueVoStatic.setMessage("");
+ valueVoStatic.setStatus(Constants.OK);
+ valueVoStatic.setValue(RemoteMockServer.DEFAULT_STATIC_ITEM_VALUE);
+ stubFor(get(urlEqualTo(RemoteMockServer.STATIC_ITEM_URL))
+ .willReturn(aResponse().withHeader("Content-Type", RemoteMockServer.CONTENT_TYPE).withStatus(200)
+ .withBody(GsonUtils.toJson(valueVoStatic))));
+
+ //
+ // 静态配置项2,用于测试没有setter方法的配置项
+ //
+ ValueVo valueVoStatic2 = new ValueVo();
+ valueVoStatic2.setMessage("");
+ valueVoStatic2.setStatus(Constants.OK);
+ valueVoStatic2.setValue(RemoteMockServer.DEFAULT_STATIC_ITEM_VALUE_2);
+ stubFor(get(urlEqualTo(RemoteMockServer.STATIC_ITEM_URL_2))
+ .willReturn(aResponse().withHeader("Content-Type", RemoteMockServer.CONTENT_TYPE).withStatus(200)
+ .withBody(GsonUtils.toJson(valueVoStatic2))));
+
//
// 配置文件
//
diff --git a/disconf-core/src/test/java/com/baidu/disconf/core/test/restful/RemoteMockServer.java b/disconf-core/src/test/java/com/baidu/disconf/core/test/restful/RemoteMockServer.java
index 19b9d942f..0ec6df27b 100644
--- a/disconf-core/src/test/java/com/baidu/disconf/core/test/restful/RemoteMockServer.java
+++ b/disconf-core/src/test/java/com/baidu/disconf/core/test/restful/RemoteMockServer.java
@@ -23,6 +23,7 @@ public class RemoteMockServer {
"/api/config/file?version=1_0_0_0&app=disconf_testcase&env=rd&key=confA.properties&type=0";
public static final String FILE_NAME = "confA.properties";
public static final String FILE_CONTENT = "confa.varA=1000\r\nconfa.varA2=2000";
+ public static final String FILE_CONTENT_NEW = "confa.varA=9999\r\nconfa.varA2=2000";
//
// 空配置文件
@@ -37,7 +38,7 @@ public class RemoteMockServer {
public static final String STATIC_FILE_URL =
"/api/config/file?version=1_0_0_0&app=disconf_testcase&env=rd&key=staticConf.properties&type=0";
public static final String STATIC_FILE_NAME = "staticConf.properties";
- public static final String STATIC_FILE_CONTENT = "staticvar=50\r\nstaticvar2=100";
+ public static final String STATIC_FILE_CONTENT = "staticvar=50\r\nstaticvar2=100\r\nstaticvar3=4001";
//
// 非注解 方式1
@@ -64,6 +65,21 @@ public class RemoteMockServer {
"/api/config/item?version=1_0_0_0&app=disconf_testcase&env=rd&key=keyA&type=1";
public static final String CONTENT_TYPE = "application/json";
public static final String DEFAULT_ITEM_VALUE = "1000";
+ public static final String DEFAULT_ITEM_VALUE_NEW = "8888";
+
+ //
+ // 静态配置项
+ //
+ public static final String STATIC_ITEM_URL =
+ "/api/config/item?version=1_0_0_0&app=disconf_testcase&env=rd&key=staticKeyA&type=1";
+ public static final String DEFAULT_STATIC_ITEM_VALUE = "2001";
+
+ //
+ // 静态配置项
+ //
+ public static final String STATIC_ITEM_URL_2 =
+ "/api/config/item?version=1_0_0_0&app=disconf_testcase&env=rd&key=staticKeyB&type=1";
+ public static final String DEFAULT_STATIC_ITEM_VALUE_2 = "3001";
//
public static final String LOCAL_DOWNLOAD_DIR = "./disconf/download";
@@ -74,7 +90,11 @@ public class RemoteMockServer {
// zoo
//
public static final String ZOO_URL = "/api/zoo/hosts";
- public static final String ZOO_HOSTS = "127.0.0.1:8581,127.0.0.1:8582,127.0.0.1:8583";
+ public static final int ZOO_PORT = 8581;
+ public static final String ZOO_HOSTS = "127.0.0.1:" + ZOO_PORT;
public static final String ZOO_PREFIX_URL = "/api/zoo/prefix";
public static final String ZOO_PREFIX_VALUE = "/disconf";
+
+ public static final String ZOO_FILE_UPDATE_PATH = ZOO_PREFIX_VALUE + "/disconf_testcase_1_0_0_0_rd/file/confA.properties";
+ public static final String ZOO_ITEM_UPDATE_PATH = ZOO_PREFIX_VALUE + "/disconf_testcase_1_0_0_0_rd/item/keyA";
}