TODO: 解决getBody Map的匿名函数的问题

This commit is contained in:
huangsimin 2019-07-08 18:53:10 +08:00
parent 6b61269e8e
commit 8624659273
8 changed files with 252 additions and 77 deletions

View File

@ -25,8 +25,6 @@ public class VerifyFilter implements GlobalFilter {
if(true) return chain.filter(exchange); if(true) return chain.filter(exchange);
ServerHttpRequest request = exchange.getRequest(); ServerHttpRequest request = exchange.getRequest();
HttpHeaders header = request.getHeaders(); HttpHeaders header = request.getHeaders();

View File

@ -1,17 +1,7 @@
package cn.ecpark.service.usergw.biz.filters.bean; package cn.ecpark.service.usergw.biz.filters.bean;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.rpc.service.GenericService; import org.apache.dubbo.rpc.service.GenericService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -19,7 +9,6 @@ import lombok.extern.slf4j.Slf4j;
/** /**
* GenericServicePool * GenericServicePool
*/ */
@Slf4j
public class GenericServicePool { public class GenericServicePool {
HashMap<String, GenericService> gsDictionary; HashMap<String, GenericService> gsDictionary;

View File

@ -1,30 +1,35 @@
package cn.ecpark.service.usergw.biz.filters.factory; package cn.ecpark.service.usergw.biz.filters.factory;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.concurrent.atomic.AtomicReference;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.rpc.service.GenericService; import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.support.HttpStatusHolder;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import cn.ecpark.service.usergw.biz.filters.bean.GenericServicePool; import cn.ecpark.service.usergw.biz.filters.bean.GenericServicePool;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;; import reactor.core.publisher.Mono;;
@Component @Component
@Slf4j
public class DubboGatewayFilterFactory extends AbstractGatewayFilterFactory<DubboGatewayFilterFactory.Config> { public class DubboGatewayFilterFactory extends AbstractGatewayFilterFactory<DubboGatewayFilterFactory.Config> {
@Autowired @Autowired
@ -34,6 +39,7 @@ public class DubboGatewayFilterFactory extends AbstractGatewayFilterFactory<Dubb
* DUBBO_URI key. * DUBBO_URI key.
*/ */
public static final String DUBBO_URI = "dubbo_uri"; public static final String DUBBO_URI = "dubbo_uri";
public static HashMap<String, List<String>> mehtods = new HashMap<>();
public DubboGatewayFilterFactory() { public DubboGatewayFilterFactory() {
super(Config.class); super(Config.class);
@ -52,15 +58,43 @@ public class DubboGatewayFilterFactory extends AbstractGatewayFilterFactory<Dubb
GenericServicePool gsPool = appContext.getBean(GenericServicePool.class); GenericServicePool gsPool = appContext.getBean(GenericServicePool.class);
GenericService gs = gsPool.get(uri); GenericService gs = gsPool.get(uri);
// special
Object result = gs.$invoke("Say", new String[] { "java.lang.String" }, new Object[] { "222" }); ServerHttpRequest req = exchange.getRequest();
// gsPool.add(rkey, gs); Flux<DataBuffer> body = req.getBody();
if (result != null) { HttpMethod m = req.getMethod();
ServerHttpResponse response = exchange.getResponse();
return response.writeWith(Mono
.just(response.bufferFactory().wrap(ByteBuffer.wrap(JSON.toJSONString(result).getBytes())))); MultiValueMap<String, String> queryParams = req.getQueryParams();
body.map( buffer -> {
byte[] bytes = new byte[buffer.readableByteCount()];
buffer.read(bytes);
DataBufferUtils.release(buffer);
try {
String bodyString = new String(bytes, "utf-8");
log.error("test body");
} catch (Exception e) {
e.printStackTrace();
}
});
List<String> methodString = queryParams.get("method");
if(methodString.size() != 0) {
// special
Object result = gs.$invoke(methodString.get(0), new String[] { "java.lang.String" }, new Object[] { "222" });
// gsPool.add(rkey, gs);
if (result != null) {
ServerHttpResponse response = exchange.getResponse();
return response.writeWith(Mono
.just(response.bufferFactory().wrap(ByteBuffer.wrap(JSON.toJSONString(result).getBytes()))));
}
} else {
log.info("queryParams.get(\"method\") is null");
} }
return chain.filter(exchange); return chain.filter(exchange);
}; };
} }

View File

@ -16,16 +16,13 @@ import java.util.function.BiConsumer;
import org.apache.dubbo.config.ReferenceConfig; import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.rpc.service.GenericService; import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.filter.FilterDefinition; import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition; import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator; import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
import cn.ecpark.service.usergw.biz.filters.bean.GenericServicePool; import cn.ecpark.service.usergw.biz.filters.bean.GenericServicePool;
@ -45,7 +42,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
// List<MediaType> mediaTypes = new ArrayList<>(); // List<MediaType> mediaTypes = new ArrayList<>();
List<FilterDefinition> defaultFilters = new ArrayList<>(); List<FilterDefinition> defaultFilters = new ArrayList<>();
HashMap<String, BiConsumer<ReferenceConfig<GenericService>, String>> specialField = new HashMap<String, BiConsumer<ReferenceConfig<GenericService>, String>>(); HashMap<String, BiConsumer<ReferenceConfig<GenericService>, Object>> specialField = new HashMap<String, BiConsumer<ReferenceConfig<GenericService>, Object>>();
Set<String> ignoreKey = new HashSet<>(); Set<String> ignoreKey = new HashSet<>();
@Autowired @Autowired
@ -54,6 +51,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
public ConfigGateway() { public ConfigGateway() {
specialField.put("application", ConfigSpecialFunction::setApplication); specialField.put("application", ConfigSpecialFunction::setApplication);
specialField.put("registry", ConfigSpecialFunction::setRegistry); specialField.put("registry", ConfigSpecialFunction::setRegistry);
specialField.put("methods", ConfigSpecialFunction::setMethods);
ignoreKey.add("predicates"); ignoreKey.add("predicates");
ignoreKey.add("filters"); ignoreKey.add("filters");
@ -116,18 +114,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
// return Flux.fromIterable(it); // return Flux.fromIterable(it);
} }
@SuppressWarnings("unchecked")
private void getDefaultFilter(List<FilterDefinition> filters, Map<String, Object> defaultYaml) {
// default-filters: 下的相关设置
Object unknownDefaultFilters = defaultYaml.get("default-filters");
if (unknownDefaultFilters != null) {
List<String> defaultFiltersYaml = (ArrayList<String>) unknownDefaultFilters;
for (String filterString : defaultFiltersYaml) {
filters.add(new FilterDefinition(filterString));
}
}
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void configDefault(List<RouteDefinition> routeList, Map<String, Object> defaultYaml) { private void configDefault(List<RouteDefinition> routeList, Map<String, Object> defaultYaml) {
@ -143,13 +130,13 @@ public class ConfigGateway implements RouteDefinitionLocator {
RouteDefinition rd = new RouteDefinition(); RouteDefinition rd = new RouteDefinition();
// 设置基础属性 // 设置基础属性
this.ParseAndSetBase(rd, iter); this.parseAndSetBase(rd, iter);
// predicates: 下的相关属性 // predicates: 下的相关属性
this.ParseAndAddPredicates(predicates, iter, "predicates"); this.parseAndAddPredicates(predicates, iter, "predicates");
// filters: 下的相关属性 // filters: 下的相关属性
this.ParseAndAddFilters(filters, iter, "filters"); this.parseAndAddFilters(filters, iter, "filters");
rd.setPredicates(predicates); rd.setPredicates(predicates);
rd.setFilters(filters); rd.setFilters(filters);
@ -176,13 +163,13 @@ public class ConfigGateway implements RouteDefinitionLocator {
RouteDefinition rd = new RouteDefinition(); RouteDefinition rd = new RouteDefinition();
// 设置基础属性 // 设置基础属性
String dubboUri = this.ParseDubboUriAndSetBase(rd, iter); String dubboUri = this.parseDubboUriAndSetBase(rd, iter);
// predicates: 下的相关属性 // predicates: 下的相关属性
this.ParseAndAddPredicates(predicates, iter, "predicates"); this.parseAndAddPredicates(predicates, iter, "predicates");
// filters: 下的相关属性 // filters: 下的相关属性
this.ParseAndAddDubboFilters(dubboUri, filters, iter, "filters"); this.parseAndAddDubboFilters(dubboUri, filters, iter, "filters");
rd.setPredicates(predicates); rd.setPredicates(predicates);
rd.setFilters(filters); rd.setFilters(filters);
@ -194,7 +181,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
} }
} catch (Exception e) { } catch (Exception e) {
log.error(e.toString()); log.error(e.getMessage());
log.warn("App is exit"); log.warn("App is exit");
((ConfigurableApplicationContext) appContext).close(); ((ConfigurableApplicationContext) appContext).close();
} }
@ -203,7 +190,20 @@ public class ConfigGateway implements RouteDefinitionLocator {
} }
private void ParseAndSetBase(RouteDefinition rd, LinkedHashMap<String, List<String>> iter) { @SuppressWarnings("unchecked")
private void getDefaultFilter(List<FilterDefinition> filters, Map<String, Object> defaultYaml) {
// default-filters: 下的相关设置
Object unknownDefaultFilters = defaultYaml.get("default-filters");
if (unknownDefaultFilters != null) {
List<String> defaultFiltersYaml = (ArrayList<String>) unknownDefaultFilters;
for (String filterString : defaultFiltersYaml) {
filters.add(new FilterDefinition(filterString));
}
}
}
private void parseAndSetBase(RouteDefinition rd, LinkedHashMap<String, List<String>> iter) {
// 设置id // 设置id
Object id = iter.get("id"); Object id = iter.get("id");
if (id != null) { if (id != null) {
@ -223,7 +223,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
} }
} }
private String ParseDubboUriAndSetBase(RouteDefinition rd, LinkedHashMap<String, List<String>> iter) { private String parseDubboUriAndSetBase(RouteDefinition rd, LinkedHashMap<String, List<String>> iter) {
// 设置id // 设置id
Object id = iter.get("id"); Object id = iter.get("id");
if (id != null) { if (id != null) {
@ -266,7 +266,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
String UriString = "dubbo://"; String UriString = "dubbo://";
Object application = iter.get("application"); Object application = iter.get("application");
if (application != null) { if (application != null) {
BiConsumer<ReferenceConfig<GenericService>, String> doFunc = specialField.get("application"); BiConsumer<ReferenceConfig<GenericService>, Object> doFunc = specialField.get("application");
if (doFunc != null) { if (doFunc != null) {
doFunc.accept(reference, (String) application); doFunc.accept(reference, (String) application);
} }
@ -282,9 +282,9 @@ public class ConfigGateway implements RouteDefinitionLocator {
Object value = entry.getValue(); Object value = entry.getValue();
if (value != null) { if (value != null) {
BiConsumer<ReferenceConfig<GenericService>, String> doFunc = specialField.get((String) key); BiConsumer<ReferenceConfig<GenericService>, Object> doFunc = specialField.get((String) key);
if (doFunc != null) { if (doFunc != null) {
doFunc.accept(reference, (String) value); doFunc.accept(reference, value);
} else { } else {
try { try {
ConfigSpecialFunction.setDefault(reference, key, value); ConfigSpecialFunction.setDefault(reference, key, value);
@ -305,7 +305,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
return UriString; return UriString;
} }
private void ParseAndAddPredicates(List<PredicateDefinition> predicates, LinkedHashMap<String, List<String>> iter, private void parseAndAddPredicates(List<PredicateDefinition> predicates, LinkedHashMap<String, List<String>> iter,
String yamlField) { String yamlField) {
List<String> predicatesYaml = iter.get(yamlField); List<String> predicatesYaml = iter.get(yamlField);
if (predicatesYaml != null) { if (predicatesYaml != null) {
@ -315,7 +315,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
} }
} }
private void ParseAndAddFilters(List<FilterDefinition> filters, LinkedHashMap<String, List<String>> iter, private void parseAndAddFilters(List<FilterDefinition> filters, LinkedHashMap<String, List<String>> iter,
String yamlField) { String yamlField) {
List<String> filtersYaml = iter.get(yamlField); List<String> filtersYaml = iter.get(yamlField);
if (filtersYaml != null) { if (filtersYaml != null) {
@ -328,12 +328,12 @@ public class ConfigGateway implements RouteDefinitionLocator {
} }
} }
private void ParseAndAddDubboFilters(String dubboUri, List<FilterDefinition> filters, private void parseAndAddDubboFilters(String dubboUri, List<FilterDefinition> filters,
LinkedHashMap<String, List<String>> iter, String yamlField) { LinkedHashMap<String, List<String>> iter, String yamlField) {
List<String> filtersYaml = iter.get(yamlField); List<String> filtersYaml = iter.get(yamlField);
filters.addAll(defaultFilters); filters.addAll(defaultFilters);
if (filtersYaml != null) { if (filtersYaml != null) {
for (String filterString : filtersYaml) { for (String filterString : filtersYaml) {
FilterDefinition fd = new FilterDefinition(filterString); FilterDefinition fd = new FilterDefinition(filterString);
@ -343,11 +343,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
} }
} }
} }
filters.add(new FilterDefinition("Dubbo=" + dubboUri)); filters.add(new FilterDefinition("Dubbo=" + dubboUri));
} }
private static void callMethod(ReferenceConfig ref, String name, String params) throws Exception {
Method method = ref.getClass().getMethod("set" + Convert.firstUpperCase(name));
method.invoke(ref, method.getParameterTypes(), params);
}
} }

View File

@ -1,6 +1,8 @@
package cn.ecpark.service.usergw.config; package cn.ecpark.service.usergw.config;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function; import java.util.function.Function;
@ -24,12 +26,12 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class ConfigSpecialFunction { public class ConfigSpecialFunction {
public static void setDefault(ReferenceConfig<GenericService> ref, String methodName, Object cfgValue) throws Exception {
methodName = "set" + Convert.firstUpperCase(methodName);
// public static BiConsumer<ReferenceConfig<GenericService>, String> log.info("method:{}, value:{}",methodName,cfgValue);
// setApplication = (ref, cfgValue) -> { Method method = ref.getClass().getMethod(methodName, cfgValue.getClass());
// ref.setApplication(new ApplicationConfig(cfgValue)); method.invoke(ref, cfgValue);
// }; }
public static void setApplication(ReferenceConfig<GenericService> ref, Object cfgValue) { public static void setApplication(ReferenceConfig<GenericService> ref, Object cfgValue) {
ref.setApplication(new ApplicationConfig((String)cfgValue)); ref.setApplication(new ApplicationConfig((String)cfgValue));
@ -39,10 +41,20 @@ public class ConfigSpecialFunction {
ref.setRegistry(new RegistryConfig((String)cfgValue)); ref.setRegistry(new RegistryConfig((String)cfgValue));
} }
public static void setDefault(ReferenceConfig<GenericService> ref, String methodName, Object cfgValue) throws Exception { @SuppressWarnings("unchecked")
methodName = "set" + Convert.firstUpperCase(methodName); public static void setMethods(ReferenceConfig<GenericService> ref, Object cfgValue) {
log.info("method:{}, value:{}",methodName,cfgValue); List<HashMap<String, Object>> cfgs = (List<HashMap<String, Object>>) cfgValue;
Method method = ref.getClass().getMethod(methodName, cfgValue.getClass()); for(HashMap<String, Object> cfg: cfgs) {
method.invoke(ref, cfgValue); String name = (String)cfg.get("name");
if(DubboGatewayFilterFactory.mehtods.containsKey(name)) {
log.warn("method {} is duplicate", name);
}
List<String> params = (List<String>)cfg.get("param-types");
DubboGatewayFilterFactory.mehtods.put(name, params);
}
} }
} }

View File

@ -26,4 +26,90 @@ public class Extract {
} }
return ret.toString(); return ret.toString();
} }
public static class GenericServiceBase {
private String application;
private String group;
private String iinterface;
private String version;
/**
* @param application the application to set
*/
public void setApplication(String application) {
this.application = application;
}
/**
* @return the application
*/
public String getApplication() {
return application;
}
/**
* @return the group
*/
public String getGroup() {
return group;
}
/**
* @param group the group to set
*/
public void setGroup(String group) {
this.group = group;
}
/**
* @return the iinterface
*/
public String getInterface() {
return iinterface;
}
/**
* @param iinterface the iinterface to set
*/
public void setInterface(String iinterface) {
this.iinterface = iinterface;
}
/**
* @return the version
*/
public String getVersion() {
return version;
}
/**
* @param version the version to set
*/
public void setVersion(String version) {
this.version = version;
}
public static GenericServiceBase Parse(String dubboUri) {
// dubbo://application/group/com.a.b:version?method=say
dubboUri = dubboUri.substring(8);
String[] token = dubboUri.split("[/:]");
GenericServiceBase gsb = new GenericServiceBase();
if (token.length == 3) {
gsb.setApplication(token[0]);
gsb.setInterface(token[1]);
gsb.setVersion(token[2]);
} else if (token.length == 4) {
gsb.setApplication(token[0]);
gsb.setGroup(token[1]);
gsb.setInterface(token[2]);
gsb.setVersion(token[3]);
}
return gsb;
}
}
} }

View File

@ -1,4 +1,4 @@
default: restful:
default-filters: default-filters:
- AddResponseHeader=X-Response-Default-Foo, Default-Bar - AddResponseHeader=X-Response-Default-Foo, Default-Bar
routes: routes:
@ -10,7 +10,7 @@ default:
- Path=/get - Path=/get
- Header=XX, \d+ - Header=XX, \d+
- id: path_route12 - id: path_route12;
uri: http://httpbin.org:80/* uri: http://httpbin.org:80/*
order: 9 order: 9
predicates: predicates:
@ -34,7 +34,14 @@ dubbo:
- id: test - id: test
order: 10 order: 10
application: dubbo-exchange application: dubbo-exchange
# method: methods: # 如果没填就从 request拿 意味着所有接口都可以使用
- name: Say
param-types:
- java.lang.String
- name: Hello
connections: 4 connections: 4
group: test group: test
# registry: zookeeper://127.0.0.1:2181 # registry: zookeeper://127.0.0.1:2181

View File

@ -0,0 +1,53 @@
package cn.ecpark.service.usergw.utils;
import java.net.URI;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.assertj.core.util.Arrays;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.boot.test.context.TestComponent;
import cn.ecpark.service.usergw.utils.Extract.GenericServiceBase;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.QueryStringDecoder;
@TestComponent
public class TestExtract {
@Test
public void TestParseDubboUri() {
GenericServiceBase gsb;
gsb = Extract.GenericServiceBase.Parse("dubbo://application/test/com.a.b:1.0.0");
Assert.assertNotNull("is Null", gsb);
Assert.assertEquals(gsb.getApplication(), "application");
Assert.assertEquals(gsb.getGroup(), "test");
Assert.assertEquals(gsb.getInterface(), "com.a.b");
Assert.assertEquals(gsb.getVersion(), "1.0.0");
gsb = Extract.GenericServiceBase.Parse("dubbo://application/com.a.b:1.0.0");
Assert.assertNotNull("is Null", gsb);
Assert.assertEquals(gsb.getApplication(), "application");
Assert.assertEquals(gsb.getInterface(), "com.a.b");
Assert.assertEquals(gsb.getVersion(), "1.0.0");
}
@Test
public void TestUriQueryList() {
// String uriString = "dubbo://qu/ha?method=213&method=312";
// QueryStringDecoder decode = new QueryStringDecoder(uriString);
// URI uri = URI.create(uriString);
// Map<String, List<String>> parameters = decode.parameters();
// Assert.assertNotNull(uri);
String[] _words = {"Hello", "World", "Hello"};
Object owords = Arrays.asList(_words);
List<String> words = (List<String>) owords;
List<String[]> a = words.stream().map(word -> ((String) word).split("e")).distinct().collect(Collectors.toList());
System.out.println(a);
}
}