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);
ServerHttpRequest request = exchange.getRequest();
HttpHeaders header = request.getHeaders();

View File

@ -1,17 +1,7 @@
package cn.ecpark.service.usergw.biz.filters.bean;
import java.util.ArrayList;
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 lombok.extern.slf4j.Slf4j;
@ -19,7 +9,6 @@ import lombok.extern.slf4j.Slf4j;
/**
* GenericServicePool
*/
@Slf4j
public class GenericServicePool {
HashMap<String, GenericService> gsDictionary;

View File

@ -1,30 +1,35 @@
package cn.ecpark.service.usergw.biz.filters.factory;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
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.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.stereotype.Component;
import org.springframework.util.MultiValueMap;
import cn.ecpark.service.usergw.biz.filters.bean.GenericServicePool;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;;
@Component
@Slf4j
public class DubboGatewayFilterFactory extends AbstractGatewayFilterFactory<DubboGatewayFilterFactory.Config> {
@Autowired
@ -34,6 +39,7 @@ public class DubboGatewayFilterFactory extends AbstractGatewayFilterFactory<Dubb
* DUBBO_URI key.
*/
public static final String DUBBO_URI = "dubbo_uri";
public static HashMap<String, List<String>> mehtods = new HashMap<>();
public DubboGatewayFilterFactory() {
super(Config.class);
@ -52,14 +58,42 @@ public class DubboGatewayFilterFactory extends AbstractGatewayFilterFactory<Dubb
GenericServicePool gsPool = appContext.getBean(GenericServicePool.class);
GenericService gs = gsPool.get(uri);
ServerHttpRequest req = exchange.getRequest();
Flux<DataBuffer> body = req.getBody();
HttpMethod m = req.getMethod();
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("Say", new String[] { "java.lang.String" }, new Object[] { "222" });
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);
};

View File

@ -16,16 +16,13 @@ import java.util.function.BiConsumer;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.rpc.service.GenericService;
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.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.yaml.snakeyaml.Yaml;
import cn.ecpark.service.usergw.biz.filters.bean.GenericServicePool;
@ -45,7 +42,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
// List<MediaType> mediaTypes = 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<>();
@Autowired
@ -54,6 +51,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
public ConfigGateway() {
specialField.put("application", ConfigSpecialFunction::setApplication);
specialField.put("registry", ConfigSpecialFunction::setRegistry);
specialField.put("methods", ConfigSpecialFunction::setMethods);
ignoreKey.add("predicates");
ignoreKey.add("filters");
@ -116,18 +114,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
// 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")
private void configDefault(List<RouteDefinition> routeList, Map<String, Object> defaultYaml) {
@ -143,13 +130,13 @@ public class ConfigGateway implements RouteDefinitionLocator {
RouteDefinition rd = new RouteDefinition();
// 设置基础属性
this.ParseAndSetBase(rd, iter);
this.parseAndSetBase(rd, iter);
// predicates: 下的相关属性
this.ParseAndAddPredicates(predicates, iter, "predicates");
this.parseAndAddPredicates(predicates, iter, "predicates");
// filters: 下的相关属性
this.ParseAndAddFilters(filters, iter, "filters");
this.parseAndAddFilters(filters, iter, "filters");
rd.setPredicates(predicates);
rd.setFilters(filters);
@ -176,13 +163,13 @@ public class ConfigGateway implements RouteDefinitionLocator {
RouteDefinition rd = new RouteDefinition();
// 设置基础属性
String dubboUri = this.ParseDubboUriAndSetBase(rd, iter);
String dubboUri = this.parseDubboUriAndSetBase(rd, iter);
// predicates: 下的相关属性
this.ParseAndAddPredicates(predicates, iter, "predicates");
this.parseAndAddPredicates(predicates, iter, "predicates");
// filters: 下的相关属性
this.ParseAndAddDubboFilters(dubboUri, filters, iter, "filters");
this.parseAndAddDubboFilters(dubboUri, filters, iter, "filters");
rd.setPredicates(predicates);
rd.setFilters(filters);
@ -194,7 +181,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
}
} catch (Exception e) {
log.error(e.toString());
log.error(e.getMessage());
log.warn("App is exit");
((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
Object id = iter.get("id");
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
Object id = iter.get("id");
if (id != null) {
@ -266,7 +266,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
String UriString = "dubbo://";
Object application = iter.get("application");
if (application != null) {
BiConsumer<ReferenceConfig<GenericService>, String> doFunc = specialField.get("application");
BiConsumer<ReferenceConfig<GenericService>, Object> doFunc = specialField.get("application");
if (doFunc != null) {
doFunc.accept(reference, (String) application);
}
@ -282,9 +282,9 @@ public class ConfigGateway implements RouteDefinitionLocator {
Object value = entry.getValue();
if (value != null) {
BiConsumer<ReferenceConfig<GenericService>, String> doFunc = specialField.get((String) key);
BiConsumer<ReferenceConfig<GenericService>, Object> doFunc = specialField.get((String) key);
if (doFunc != null) {
doFunc.accept(reference, (String) value);
doFunc.accept(reference, value);
} else {
try {
ConfigSpecialFunction.setDefault(reference, key, value);
@ -305,7 +305,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
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) {
List<String> predicatesYaml = iter.get(yamlField);
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) {
List<String> filtersYaml = iter.get(yamlField);
if (filtersYaml != null) {
@ -328,7 +328,7 @@ 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) {
List<String> filtersYaml = iter.get(yamlField);
@ -343,11 +343,7 @@ public class ConfigGateway implements RouteDefinitionLocator {
}
}
}
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;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
@ -24,12 +26,12 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ConfigSpecialFunction {
// public static BiConsumer<ReferenceConfig<GenericService>, String>
// setApplication = (ref, cfgValue) -> {
// ref.setApplication(new ApplicationConfig(cfgValue));
// };
public static void setDefault(ReferenceConfig<GenericService> ref, String methodName, Object cfgValue) throws Exception {
methodName = "set" + Convert.firstUpperCase(methodName);
log.info("method:{}, value:{}",methodName,cfgValue);
Method method = ref.getClass().getMethod(methodName, cfgValue.getClass());
method.invoke(ref, cfgValue);
}
public static void setApplication(ReferenceConfig<GenericService> ref, Object cfgValue) {
ref.setApplication(new ApplicationConfig((String)cfgValue));
@ -39,10 +41,20 @@ public class ConfigSpecialFunction {
ref.setRegistry(new RegistryConfig((String)cfgValue));
}
public static void setDefault(ReferenceConfig<GenericService> ref, String methodName, Object cfgValue) throws Exception {
methodName = "set" + Convert.firstUpperCase(methodName);
log.info("method:{}, value:{}",methodName,cfgValue);
Method method = ref.getClass().getMethod(methodName, cfgValue.getClass());
method.invoke(ref, cfgValue);
@SuppressWarnings("unchecked")
public static void setMethods(ReferenceConfig<GenericService> ref, Object cfgValue) {
List<HashMap<String, Object>> cfgs = (List<HashMap<String, Object>>) cfgValue;
for(HashMap<String, Object> cfg: cfgs) {
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();
}
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:
- AddResponseHeader=X-Response-Default-Foo, Default-Bar
routes:
@ -10,7 +10,7 @@ default:
- Path=/get
- Header=XX, \d+
- id: path_route12
- id: path_route12;
uri: http://httpbin.org:80/*
order: 9
predicates:
@ -34,7 +34,14 @@ dubbo:
- id: test
order: 10
application: dubbo-exchange
# method:
methods: # 如果没填就从 request拿 意味着所有接口都可以使用
- name: Say
param-types:
- java.lang.String
- name: Hello
connections: 4
group: test
# 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);
}
}