改了单元测试. 可以正式上线
This commit is contained in:
parent
866c7b4850
commit
d97b088117
|
@ -3,5 +3,10 @@
|
|||
"name": "yame.gateway.config",
|
||||
"type": "java.lang.String",
|
||||
"description": "用于配置网关的路径, 如果不填.默认: gateway.yml, gateway.yaml, Gateway.yml, Gateway.yaml"
|
||||
},
|
||||
{
|
||||
"name": "apollo.namespace",
|
||||
"type": "java.lang.String",
|
||||
"description": "默认gateway.yml和gateway.yaml"
|
||||
}
|
||||
]}
|
|
@ -1,7 +1,10 @@
|
|||
package cn.ecpark.service.usergw.biz.filters.bean;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.utils.ReferenceConfigCache;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
|
||||
/**
|
||||
|
@ -9,17 +12,47 @@ import org.apache.dubbo.rpc.service.GenericService;
|
|||
*/
|
||||
public class GenericServicePool {
|
||||
|
||||
HashMap<String, GenericService> gsDictionary;
|
||||
private class ReferenceConfigStore {
|
||||
private ReferenceConfig<GenericService> ref;
|
||||
private GenericService gs;
|
||||
|
||||
public ReferenceConfigStore(ReferenceConfig<GenericService> refValue) {
|
||||
this.ref = refValue;
|
||||
this.gs = ref.get();
|
||||
}
|
||||
|
||||
public GenericService get() {
|
||||
return gs;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
this.ref.destroy();
|
||||
this.ref = null;
|
||||
this.gs = null ;
|
||||
}
|
||||
}
|
||||
|
||||
HashMap<String, ReferenceConfigStore> gsDictionary;
|
||||
|
||||
public GenericServicePool() {
|
||||
gsDictionary = new HashMap<String, GenericService>();
|
||||
gsDictionary = new HashMap<String, ReferenceConfigStore>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
|
||||
for(Entry<String, ReferenceConfigStore> entry : gsDictionary.entrySet()) {
|
||||
entry.getValue(). destroy();
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
public GenericService get(String key) {
|
||||
return gsDictionary.get(key);
|
||||
return gsDictionary.get(key).get();
|
||||
}
|
||||
|
||||
public void put(String key, GenericService genericService) {
|
||||
gsDictionary.put(key, genericService);
|
||||
public void put(String key, ReferenceConfig<GenericService> ref) {
|
||||
ReferenceConfigStore refStore = new ReferenceConfigStore(ref);
|
||||
gsDictionary.put(key, refStore);
|
||||
}
|
||||
}
|
|
@ -3,23 +3,25 @@ package cn.ecpark.service.usergw.config;
|
|||
import com.ctrip.framework.apollo.Config;
|
||||
import com.ctrip.framework.apollo.ConfigChangeListener;
|
||||
import com.ctrip.framework.apollo.ConfigService;
|
||||
import com.ctrip.framework.apollo.enums.ConfigSourceType;
|
||||
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import cn.ecpark.service.usergw.biz.events.ConfigRefresh;
|
||||
|
||||
|
||||
|
||||
// @EnableApolloConfig("gateway.yml")
|
||||
// @ConditionalOnProperty(prefix="app", value="id", matchIfMissing=true)
|
||||
// @Configurable
|
||||
|
||||
public class ConfigApollo implements ConfigChangeListener {
|
||||
|
||||
// private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ConfigApollo.class);
|
||||
|
||||
private static final org.slf4j.Logger log =
|
||||
org.slf4j.LoggerFactory.getLogger(ConfigApollo.class);
|
||||
|
||||
// @ApolloConfig("gateway.yml")
|
||||
private Config config;
|
||||
|
@ -32,6 +34,9 @@ public class ConfigApollo implements ConfigChangeListener {
|
|||
@Value("${app.id:}")
|
||||
private String appID;
|
||||
|
||||
@Value("${apollo.namespace:}")
|
||||
private String apolloNamespace;
|
||||
|
||||
private int tryConnect;
|
||||
|
||||
public ConfigApollo() {
|
||||
|
@ -39,15 +44,37 @@ public class ConfigApollo implements ConfigChangeListener {
|
|||
}
|
||||
|
||||
public void Connect() {
|
||||
if(this.isConnected() && this.tryConnect > 0) {
|
||||
this.tryConnect --;
|
||||
config = ConfigService.getConfig("gateway.yml");
|
||||
config.addChangeListener(this);
|
||||
if (this.isConnected() && this.tryConnect > 0) {
|
||||
this.tryConnect--;
|
||||
ConfigSourceType stype = null;
|
||||
if (apolloNamespace.equals("")) {
|
||||
String[] tryExamples = { "gateway.yml", "gateway.yaml", "Gateway.yml", "Gateway.yaml" };
|
||||
for (String ns : tryExamples) {
|
||||
apolloNamespace = ns;
|
||||
config = ConfigService.getConfig(apolloNamespace);
|
||||
stype = config.getSourceType();
|
||||
if (!stype.name().equals("None")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
config = ConfigService.getConfig(apolloNamespace);
|
||||
stype = config.getSourceType();
|
||||
}
|
||||
|
||||
if(stype.name().equals("None") || stype == null) {
|
||||
log.error("getSourceType = {} is error, please check apollo server, or check apollo properties", stype.name());
|
||||
((ConfigurableApplicationContext)this.appContext).close();
|
||||
}
|
||||
|
||||
if (config != null) {
|
||||
config.addChangeListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
if(!this.appID.equals("") && !this.apolloMeta.equals("") ) {
|
||||
if (!this.appID.equals("") && !this.apolloMeta.equals("")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -60,11 +87,11 @@ public class ConfigApollo implements ConfigChangeListener {
|
|||
|
||||
@Override
|
||||
public void onChange(ConfigChangeEvent changeEvent) {
|
||||
ConfigRefresh change = (ConfigRefresh)appContext.getBean(ConfigRefresh.class);
|
||||
ConfigRefresh change = (ConfigRefresh) appContext.getBean(ConfigRefresh.class);
|
||||
change.notifyChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @return Config return the config
|
||||
*/
|
||||
public Config getConfig() {
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.function.BiConsumer;
|
|||
import com.ctrip.framework.apollo.internals.ConfigRepository;
|
||||
import com.ctrip.framework.apollo.internals.DefaultConfig;
|
||||
import com.ctrip.framework.apollo.internals.PropertiesCompatibleFileConfigRepository;
|
||||
import com.ctrip.framework.apollo.internals.YamlConfigFile;
|
||||
import com.ctrip.framework.apollo.internals.YmlConfigFile;
|
||||
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
|
@ -160,15 +161,22 @@ public class ConfigGateway implements RouteDefinitionLocator {
|
|||
private InputStream loadApolloConfig(ConfigApollo configApollo) {
|
||||
DefaultConfig config = (DefaultConfig) configApollo.getConfig();
|
||||
try {
|
||||
Field m_configRepository = DefaultConfig.class.getDeclaredField("m_configRepository");
|
||||
m_configRepository.setAccessible(true);
|
||||
ConfigRepository cr = (ConfigRepository) m_configRepository.get(config);
|
||||
Field configFile = PropertiesCompatibleFileConfigRepository.class.getDeclaredField("configFile");
|
||||
configFile.setAccessible(true);
|
||||
YmlConfigFile ymlConfigFile = (YmlConfigFile) configFile.get(cr);
|
||||
String content = ymlConfigFile.getContent();
|
||||
log.info("Load Apollo YAML Config: \n{}", content);
|
||||
return new ByteArrayInputStream(content.getBytes());
|
||||
String content = null ;
|
||||
for(int i = 0; i < 3; i++) {
|
||||
Field m_configRepository = DefaultConfig.class.getDeclaredField("m_configRepository");
|
||||
m_configRepository.setAccessible(true);
|
||||
ConfigRepository cr = (ConfigRepository) m_configRepository.get(config);
|
||||
Field configFile = PropertiesCompatibleFileConfigRepository.class.getDeclaredField("configFile");
|
||||
configFile.setAccessible(true);
|
||||
YamlConfigFile ymlConfigFile = (YamlConfigFile) configFile.get(cr);
|
||||
content = ymlConfigFile.getContent();
|
||||
if(content == null) {
|
||||
log.error("eson:debug {}", config.toString());
|
||||
continue;
|
||||
}
|
||||
log.info("Load Apollo YAML Config: \n{}", content);
|
||||
return new ByteArrayInputStream(content.getBytes());
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SecurityException e) {
|
||||
|
@ -394,7 +402,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
|
|||
UriString += Extract.getReferenceConfigKey(reference);
|
||||
GenericServicePool gsPool = appContext.getBean(GenericServicePool.class);
|
||||
reference.setGeneric(true);
|
||||
gsPool.put(UriString, reference.get());
|
||||
gsPool.put(UriString, reference);
|
||||
|
||||
return UriString;
|
||||
}
|
||||
|
|
|
@ -11,9 +11,10 @@ import reactor.core.publisher.Mono;
|
|||
|
||||
@Component
|
||||
public class ConfigBean {
|
||||
|
||||
@Bean
|
||||
ConfigApollo configApollo() {
|
||||
return new ConfigApollo();
|
||||
KeyResolver ipResolver() {
|
||||
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostString());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -22,14 +23,12 @@ public class ConfigBean {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public DubboGatewayFilterFactory dubboFilterFactory() {
|
||||
return new DubboGatewayFilterFactory();
|
||||
ConfigApollo configApollo() {
|
||||
return new ConfigApollo();
|
||||
}
|
||||
|
||||
@Bean
|
||||
KeyResolver ipResolver() {
|
||||
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostString());
|
||||
public DubboGatewayFilterFactory dubboFilterFactory() {
|
||||
return new DubboGatewayFilterFactory();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
spring.application.name=gateway
|
||||
|
||||
# app.id=gateway
|
||||
# apollo.meta=http://localhost:8180
|
||||
apollo.namespace=gateway.yml
|
||||
app.id=gateway
|
||||
apollo.meta=http://localhost:8180
|
||||
# local.meta=http://localhost:8180
|
||||
# dev.meta=http://localhost:8180
|
||||
# fat.meta=http://localhost:8180
|
||||
|
|
|
@ -46,8 +46,8 @@ dubbo:
|
|||
- name: RequestRateLimiter
|
||||
args:
|
||||
key-resolver: '#{@ipResolver}' #SPEL表达式去的对应的bean
|
||||
redis-rate-limiter.replenishRate: 40 # 令牌桶的容积
|
||||
redis-rate-limiter.burstCapacity: 80 # 流速 每秒
|
||||
redis-rate-limiter.replenishRate: 30 # 令牌桶的容积
|
||||
redis-rate-limiter.burstCapacity: 60 # 流速 每秒
|
||||
|
||||
# - name: RequestRateLimiter1
|
||||
# args:
|
||||
|
|
19
usergw-service/src/main/resources/test-gateway5.yaml
Normal file
19
usergw-service/src/main/resources/test-gateway5.yaml
Normal file
|
@ -0,0 +1,19 @@
|
|||
dubbo:
|
||||
routes:
|
||||
- id: test
|
||||
order: 0
|
||||
application: dubbo-exchange
|
||||
methods: # 如果没填就从 request拿 意味着所有接口都可以使用
|
||||
- name: Say
|
||||
param-types:
|
||||
- java.lang.String
|
||||
- name: Hello
|
||||
|
||||
connections: 4
|
||||
group: test
|
||||
# registry: zookeeper://127.0.0.1:2181
|
||||
interface: ocean.demo.api.IExchange
|
||||
version: 1.0.0
|
||||
predicates:
|
||||
- Path=/dubbo/hello
|
||||
|
|
@ -7,6 +7,7 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import org.junit.runner.RunWith;
|
|||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.junit.runner.RunWith;
|
|||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
package cn.ecpark.service.usergw;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
@ -6,6 +11,7 @@ import org.junit.runner.RunWith;
|
|||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
|
@ -23,7 +29,7 @@ public class TestHttp2DubboConfig4 {
|
|||
private int serverPort;
|
||||
|
||||
@Test
|
||||
public void Test1RequestHttp2DubboSetHeader() {
|
||||
public void Test1RedisLimit() {
|
||||
// Test Base Url
|
||||
for(int i = 0; i < 50;i++) {
|
||||
HttpClient client = HttpClient.create();
|
||||
|
@ -47,13 +53,4 @@ public class TestHttp2DubboConfig4 {
|
|||
|
||||
}
|
||||
|
||||
|
||||
// @Test
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public void Test3RestfulFilters() {
|
||||
|
||||
|
||||
// }
|
||||
|
||||
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
package cn.ecpark.service.usergw;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
|
@ -16,44 +18,41 @@ import reactor.netty.http.client.HttpClientResponse;
|
|||
// TODO: 添加附加Dubbo Service for Test启动进程
|
||||
@SpringBootTest(classes = App.class, webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@RunWith(SpringRunner.class)
|
||||
@TestPropertySource(locations = "classpath:/resources/test4.properties", properties = {"apollo.meta=", "app.id="})
|
||||
@TestPropertySource(locations = "classpath:/resources/test5.properties")
|
||||
@Ignore
|
||||
public class TestHttp2DubboConfig5 {
|
||||
|
||||
@LocalServerPort
|
||||
private int serverPort;
|
||||
|
||||
@Test
|
||||
public void Test1RequestHttp2DubboSetHeader() {
|
||||
public void Test1LoadApolloConfig() {
|
||||
// Test Base Url
|
||||
for(int i = 0; i < 50;i++) {
|
||||
HttpClient client = HttpClient.create();
|
||||
ResponseReceiver<?> receiver;
|
||||
String content;
|
||||
|
||||
receiver = client.baseUrl("http://localhost:" + serverPort + "/dubbo/hello")
|
||||
.headers(h -> h.set("method", "Hello")).get();
|
||||
HttpClient client = HttpClient.create();
|
||||
ResponseReceiver<?> receiver;
|
||||
String content;
|
||||
|
||||
HttpClientResponse response = receiver.response().block();
|
||||
Assert.assertNotNull(response);
|
||||
receiver = client.baseUrl("http://localhost:" + serverPort + "/dubbo/gateway/test5")
|
||||
.headers(h -> h.set("method", "Hello")).get();
|
||||
|
||||
if(response.status().code() == 200) {
|
||||
content = receiver.responseContent().asString().blockLast();
|
||||
Assert.assertNotNull(content);
|
||||
Assert.assertEquals(content, "Hello Dubbo");
|
||||
} else {
|
||||
Assert.assertEquals(response.status().code(), 429);
|
||||
}
|
||||
HttpClientResponse response = receiver.response().block();
|
||||
Assert.assertNotNull(response);
|
||||
|
||||
if(response.status().code() == 200) {
|
||||
content = receiver.responseContent().asString().blockLast();
|
||||
Assert.assertNotNull(content);
|
||||
Assert.assertEquals("Hello Dubbo", content);
|
||||
} else {
|
||||
Assert.assertEquals(429, response.status().code());
|
||||
}
|
||||
|
||||
|
||||
receiver = client.baseUrl("http://localhost:" + serverPort + "/dubbo/hello")
|
||||
.headers(h -> h.set("method", "Hello")).get();
|
||||
|
||||
response = receiver.response().block();
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertNotEquals(200, response.status().code());
|
||||
}
|
||||
|
||||
|
||||
// @Test
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public void Test3RestfulFilters() {
|
||||
|
||||
|
||||
// }
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
|
||||
package cn.ecpark.service.usergw;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import reactor.netty.http.client.HttpClient;
|
||||
import reactor.netty.http.client.HttpClient.ResponseReceiver;
|
||||
import reactor.netty.http.client.HttpClientResponse;
|
||||
|
||||
// TODO: 添加附加Dubbo Service for Test启动进程
|
||||
@SpringBootTest(classes = App.class, webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@RunWith(SpringRunner.class)
|
||||
@TestPropertySource(locations = "classpath:/resources/test5.properties", properties = {"apollo.namespace=", "app.id=gateway"})
|
||||
@Ignore
|
||||
public class TestHttp2DubboConfig6 {
|
||||
|
||||
@LocalServerPort
|
||||
private int serverPort;
|
||||
|
||||
@Test
|
||||
|
||||
public void Test1LoadDefaultApolloConfig() {
|
||||
// Test Base Url
|
||||
|
||||
HttpClient client = HttpClient.create();
|
||||
ResponseReceiver<?> receiver;
|
||||
String content;
|
||||
|
||||
receiver = client.baseUrl("http://localhost:" + serverPort + "/dubbo/hello1")
|
||||
.headers(h -> h.set("method", "Hello")).get();
|
||||
|
||||
HttpClientResponse response = receiver.response().block();
|
||||
Assert.assertNotNull(response);
|
||||
|
||||
if(response.status().code() == 200) {
|
||||
content = receiver.responseContent().asString().blockLast();
|
||||
Assert.assertNotNull(content);
|
||||
Assert.assertEquals("Hello Dubbo", content);
|
||||
} else {
|
||||
Assert.assertEquals(429, response.status().code());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
33
usergw-service/src/test/java/resources/test5.properties
Normal file
33
usergw-service/src/test/java/resources/test5.properties
Normal file
|
@ -0,0 +1,33 @@
|
|||
|
||||
spring.application.name=gateway
|
||||
# AppID 非 NameSpace
|
||||
app.id=test-gateway5
|
||||
apollo.meta=http://localhost:8180
|
||||
apollo.namespace=gateway-test5.yaml
|
||||
# local.meta=http://localhost:8180
|
||||
# dev.meta=http://localhost:8180
|
||||
# fat.meta=http://localhost:8180
|
||||
# uat.meta=http://localhost:8180
|
||||
# lpt.meta=http://localhost:8180
|
||||
# pro.meta=http://localhost:8180
|
||||
# eureka.instance.ip-address=http://localhost:8180
|
||||
|
||||
dubbo.scan.base-packages=cn.ecpark.service.usergw.impl
|
||||
dubbo.protocol.name=dubbo
|
||||
dubbo.protocol.port=20999
|
||||
dubbo.registry.address=zookeeper://127.0.0.1:2181
|
||||
dubbo.config-center.address=zookeeper://127.0.0.1:2181
|
||||
dubbo.metadata-report.address=zookeeper://127.0.0.1:2181
|
||||
# 这个链接Apollo非常有意义.
|
||||
# 因为在一个线程内, 同时Connect Zookeeper 和 Apollo 会导致 Apollo可能超过3秒再加其他操作.Zookeeper会出现阻塞.
|
||||
dubbo.consumer.timeout=1000
|
||||
|
||||
server.port=8888
|
||||
|
||||
logging.file=logs/log
|
||||
yame.gateway.config=test-gateway5.yaml
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user