Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix - 在类的static块里取不到static类型的分布式配置值 #314

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
14 changes: 14 additions & 0 deletions disconf-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,20 @@
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/com.netflix.curator/curator-test -->
<dependency>
<groupId>com.netflix.curator</groupId>
<artifactId>curator-test</artifactId>
<version>1.0.20</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.netflix.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>1.0.20</version>
<scope>test</scope>
</dependency>

<!-- ================ provided ================ -->

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -55,28 +57,20 @@ public class DisconfMgrTestCase extends BaseSpringMockTestCase implements Applic

@Test
public void demo() {

//
// mock up factory method
//
new MockUp<DisconfCoreFactory>() {

@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);
}

//
// 正式测试
Expand All @@ -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 ==============================");

Expand All @@ -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 ==============================");
Expand All @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ public class ServiceA {

public static final String keyA = "keyA";

/**
* 2. 用于静态方式获取的分布式配置项<br/>
*/
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;

Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void scan() {
LOGGER.info("=============DISCONF FILE ITEM===================");
Set<Method> 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
Expand All @@ -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===================");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))));

//
// 配置文件
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";

//
// 空配置文件
Expand All @@ -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
Expand All @@ -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";
Expand All @@ -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";
}