Skip to content

Commit c1a2211

Browse files
Merge pull request #13 from hango-io/release-v1.2
support dubbo bridge
2 parents cee315f + 84e03df commit c1a2211

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2083
-792
lines changed

hango-api-plane-server/src/main/java/org/hango/cloud/core/GlobalConfig.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ public class GlobalConfig {
2121
@Value("${telnet.connect.timeout:3000}")
2222
private Integer telnetConnectTimeout;
2323

24+
@Value("${customDefaultRespCode:500}")
25+
private int customDefaultRespCode;
26+
2427
public String getResourceNamespace() {
2528
return resourceNamespace;
2629
}
@@ -40,4 +43,8 @@ public String getApiPlaneVersion() {
4043
public Integer getTelnetConnectTimeout() {
4144
return telnetConnectTimeout;
4245
}
46+
47+
public int getCustomDefaultRespCode() {
48+
return customDefaultRespCode;
49+
}
4350
}

hango-api-plane-server/src/main/java/org/hango/cloud/core/gateway/GatewayIstioModelEngine.java

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package org.hango.cloud.core.gateway;
22

3+
import org.apache.commons.lang3.math.NumberUtils;
34
import org.hango.cloud.core.GlobalConfig;
45
import org.hango.cloud.core.IstioModelEngine;
56
import org.hango.cloud.core.editor.EditorContext;
7+
import org.hango.cloud.core.gateway.handler.*;
68
import org.hango.cloud.core.gateway.processor.DefaultModelProcessor;
79
import org.hango.cloud.core.gateway.processor.NeverReturnNullModelProcessor;
810
import org.hango.cloud.core.gateway.processor.RenderTwiceModelProcessor;
@@ -21,16 +23,8 @@
2123
import org.hango.cloud.service.PluginService;
2224
import org.hango.cloud.util.Const;
2325
import org.hango.cloud.util.constant.LogConstant;
24-
import org.hango.cloud.util.constant.PluginConstant;
2526
import io.fabric8.kubernetes.api.model.HasMetadata;
2627
import istio.networking.v1alpha3.VirtualServiceOuterClass;
27-
import org.hango.cloud.core.gateway.handler.GatewayPluginConfigMapDataHandler;
28-
import org.hango.cloud.core.gateway.handler.GatewayPluginDataHandler;
29-
import org.hango.cloud.core.gateway.handler.PluginOrderDataHandler;
30-
import org.hango.cloud.core.gateway.handler.PortalDestinationRuleServiceDataHandler;
31-
import org.hango.cloud.core.gateway.handler.PortalGatewayDataHandler;
32-
import org.hango.cloud.core.gateway.handler.PortalServiceEntryServiceDataHandler;
33-
import org.hango.cloud.core.gateway.handler.PortalVirtualServiceAPIDataHandler;
3428
import org.hango.cloud.meta.API;
3529
import org.hango.cloud.meta.GatewayPlugin;
3630
import org.hango.cloud.meta.IstioGateway;
@@ -46,11 +40,9 @@
4640
import org.springframework.util.CollectionUtils;
4741
import org.springframework.util.StringUtils;
4842

49-
import java.util.ArrayList;
50-
import java.util.Collections;
51-
import java.util.List;
52-
import java.util.Optional;
43+
import java.util.*;
5344
import java.util.stream.Collectors;
45+
import java.util.stream.Stream;
5446

5547
@Component
5648
public class GatewayIstioModelEngine extends IstioModelEngine {
@@ -102,6 +94,9 @@ public GatewayIstioModelEngine(IntegratedResourceOperator operator, TemplateTran
10294
private static final String pluginManager = "gateway/pluginManager";
10395
private static final String serviceServiceEntry = "gateway/service/serviceEntry";
10496
private static final String gatewayPlugin = "gateway/gatewayPlugin";
97+
private static final String smartLimiter = "gateway/smartLimiter";
98+
private static final String envoyFilter = "gateway/envoyFilter";
99+
private static final String grpcConfigPatch = "gateway/grpcConfigPatch";
105100
private static final String VIRTUAL_SERVICE = "VirtualService";
106101

107102
public List<K8sResourcePack> translate(API api) {
@@ -126,6 +121,9 @@ public List<K8sResourcePack> translate(API api, boolean simple) {
126121
.map(FragmentHolder::getVirtualServiceFragment)
127122
.collect(Collectors.toList());
128123
}
124+
if (NumberUtils.INTEGER_ZERO.equals(api.getCustomDefaultRespCode())){
125+
api.setCustomDefaultRespCode(globalConfig.getCustomDefaultRespCode());
126+
}
129127
List<String> rawVirtualServices = renderTwiceModelProcessor
130128
.process(apiVirtualService, api,
131129
new PortalVirtualServiceAPIDataHandler(
@@ -170,34 +168,39 @@ public List<K8sResourcePack> translate(GatewayPlugin plugin) {
170168
*/
171169
private List<K8sResourcePack> generateAndAddK8sResource(RawResourceContainer rawResourceContainer,
172170
GatewayPlugin plugin) {
173-
// 插件渲染GatewayPlugin资源
174-
logger.info("{}{} start render raw GatewayPlugin CRDs",
171+
// 插件渲染网关插件CR资源
172+
logger.info("{}{} start render raw Plugin CRs",
175173
LogConstant.TRANSLATE_LOG_NOTE, LogConstant.PLUGIN_LOG_NOTE);
176-
List<K8sResourcePack> resourcePacks = configureGatewayPlugin(rawResourceContainer, plugin);
177174

178-
// 路由级别的限流插件要渲染ConfigMap资源
179-
if (isNeedToRenderConfigMap(plugin)) {
180-
logger.info("{}{} start render raw ConfigMap CRDs",
181-
LogConstant.TRANSLATE_LOG_NOTE, LogConstant.PLUGIN_LOG_NOTE);
182-
configureRateLimitConfigMap(rawResourceContainer, resourcePacks, plugin);
183-
}
175+
// 渲染EnvoyPlugin和SmartPlugin资源
176+
List<K8sResourcePack> envoyPlugins = configureEnvoyPlugin(rawResourceContainer, plugin);
177+
List<K8sResourcePack> smartLimiters = configureSmartLimiter(rawResourceContainer, plugin);
184178

185-
return resourcePacks;
179+
// 聚合插件CR资源
180+
return Stream.of(envoyPlugins, smartLimiters)
181+
.flatMap(Collection::stream)
182+
.collect(Collectors.toList());
186183
}
187184

188185
/**
189-
* 插件流程只有两个场景需要渲染ConfigMap资源
190-
* 1.路由级别的限流插件
191-
* 2.没有传插件类型,即批量操作的场景,此时可能会有限流插件,因此需要无差别渲染(匹配路由启用、禁用、下线场景)
192-
* 注:限流插件只有路由级别,因此路由插件是先决条件
186+
* 插件转换为SmartLimiter CRD资源
193187
*
194-
* @param plugin 网关插件实例(内含插件配置)
195-
* @return 是否需要渲染ConfigMap资源
188+
* @param rawResourceContainer 存放资源的容器对象
189+
* @param plugin 插件对象
190+
* @return k8s资源集合
196191
*/
197-
private boolean isNeedToRenderConfigMap(GatewayPlugin plugin) {
198-
return plugin.isRoutePlugin() &&
199-
(StringUtils.isEmpty(plugin.getPluginType()) || plugin.getPluginType().equals(
200-
PluginConstant.RATE_LIMIT_PLUGIN_TYPE));
192+
private List<K8sResourcePack> configureSmartLimiter(RawResourceContainer rawResourceContainer,
193+
GatewayPlugin plugin) {
194+
List<K8sResourcePack> resourcePacks = new ArrayList<>();
195+
// 将插件配置转换为SmartLimiters
196+
List<String> rawSmartLimiters = defaultModelProcessor.process(smartLimiter, plugin,
197+
new SmartLimiterDataHandler(rawResourceContainer.getSmartLimiters(), globalConfig.getResourceNamespace()));
198+
199+
resourcePacks.addAll(generateK8sPack(rawSmartLimiters));
200+
logger.info("{}{} raw SmartLimiter CRs added ok",
201+
LogConstant.TRANSLATE_LOG_NOTE, LogConstant.PLUGIN_LOG_NOTE);
202+
203+
return resourcePacks;
201204
}
202205

203206
/**
@@ -207,8 +210,8 @@ private boolean isNeedToRenderConfigMap(GatewayPlugin plugin) {
207210
* @param plugin 插件对象
208211
* @return k8s资源集合
209212
*/
210-
private List<K8sResourcePack> configureGatewayPlugin(RawResourceContainer rawResourceContainer,
211-
GatewayPlugin plugin) {
213+
private List<K8sResourcePack> configureEnvoyPlugin(RawResourceContainer rawResourceContainer,
214+
GatewayPlugin plugin) {
212215
List<K8sResourcePack> resourcePacks = new ArrayList<>();
213216
// 插件配置放在GatewayPlugin的CRD上
214217
List<String> rawGatewayPlugins = renderTwiceModelProcessor.process(gatewayPlugin, plugin,
@@ -229,28 +232,6 @@ private List<K8sResourcePack> configureGatewayPlugin(RawResourceContainer rawRes
229232
return resourcePacks;
230233
}
231234

232-
/**
233-
* 限流插件转换为ConfigMap CRD资源
234-
*
235-
* @param rawResourceContainer 存放资源的容器对象
236-
* @param resourcePacks k8s资源集合
237-
* @param plugin 插件对象
238-
*/
239-
private void configureRateLimitConfigMap(RawResourceContainer rawResourceContainer,
240-
List<K8sResourcePack> resourcePacks,
241-
GatewayPlugin plugin) {
242-
// 限流插件需要额外的configMap配置
243-
List<String> rawConfigMaps = neverNullRenderTwiceProcessor.process(rateLimitConfigMap, plugin,
244-
new GatewayPluginConfigMapDataHandler(
245-
rawResourceContainer.getSharedConfigs(), rateLimitConfigMapName, rateLimitNamespace));
246-
// 加入限流插件configMap配置
247-
resourcePacks.addAll(generateK8sPack(rawConfigMaps,
248-
new GatewayRateLimitConfigMapMerger(),
249-
new GatewayRateLimitConfigMapSubtracter(plugin.getGateway(), plugin.getRouteId()),
250-
new EmptyResourceGenerator(new EmptyConfigMap(rateLimitConfigMapName, rateLimitNamespace))));
251-
logger.info("{}{} raw ConfigMap CRDs added ok", LogConstant.TRANSLATE_LOG_NOTE, LogConstant.PLUGIN_LOG_NOTE);
252-
}
253-
254235
public List<K8sResourcePack> translate(Service service) {
255236
List<K8sResourcePack> resources = new ArrayList<>();
256237
List<String> destinations = defaultModelProcessor.process(serviceDestinationRule, service, new PortalDestinationRuleServiceDataHandler());

hango-api-plane-server/src/main/java/org/hango/cloud/core/gateway/RawResourceContainer.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class RawResourceContainer {
1212
List<FragmentWrapper> virtualServices = new ArrayList<>();
1313
List<FragmentWrapper> sharedConfigs = new ArrayList<>();
1414
List<FragmentWrapper> gatewayPlugins = new ArrayList<>();
15+
List<FragmentWrapper> smartLimiters = new ArrayList<>();
1516

1617
public void add(FragmentHolder holder) {
1718

@@ -26,6 +27,10 @@ public void add(FragmentHolder holder) {
2627
if (holder.getGatewayPluginsFragment() != null) {
2728
gatewayPlugins.add(holder.getGatewayPluginsFragment());
2829
}
30+
31+
if (holder.getSmartLimiterFragment() != null) {
32+
smartLimiters.addAll(holder.getSmartLimiterFragment());
33+
}
2934
}
3035

3136
public void add(List<FragmentHolder> holders) {
@@ -44,4 +49,8 @@ public List<FragmentWrapper> getSharedConfigs() {
4449
public List<FragmentWrapper> getGatewayPlugins() {
4550
return gatewayPlugins;
4651
}
52+
53+
public List<FragmentWrapper> getSmartLimiters() {
54+
return smartLimiters;
55+
}
4756
}

hango-api-plane-server/src/main/java/org/hango/cloud/core/gateway/handler/APIDataHandler.java

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,34 @@
11
package org.hango.cloud.core.gateway.handler;
22

3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import me.snowdrop.istio.api.networking.v1alpha3.VirtualService;
5+
import org.apache.commons.lang3.StringEscapeUtils;
36
import org.hango.cloud.core.gateway.handler.meta.UriMatchMeta;
47
import org.hango.cloud.core.template.TemplateParams;
58
import org.hango.cloud.meta.API;
9+
import org.hango.cloud.meta.CRDMetaEnum;
610
import org.hango.cloud.meta.PairMatch;
711
import org.hango.cloud.meta.UriMatch;
12+
import org.hango.cloud.meta.dto.DubboInfoDto;
813
import org.hango.cloud.util.CommonUtil;
914
import org.hango.cloud.util.PriorityUtil;
10-
import org.apache.commons.lang3.StringEscapeUtils;
15+
import org.slf4j.Logger;
16+
import org.slf4j.LoggerFactory;
1117
import org.springframework.util.CollectionUtils;
1218
import org.springframework.util.StringUtils;
1319

1420
import java.util.ArrayList;
21+
import java.util.Iterator;
1522
import java.util.List;
23+
import java.util.Map;
1624
import java.util.stream.Collectors;
1725

1826
import static org.hango.cloud.core.template.TemplateConst.*;
1927

2028
public abstract class APIDataHandler implements DataHandler<API> {
2129

30+
private static final Logger logger = LoggerFactory.getLogger(APIDataHandler.class);
31+
2232
@Override
2333
public List<TemplateParams> handle(API api) {
2434
TemplateParams tp = handleApi(api);
@@ -75,11 +85,83 @@ public TemplateParams handleApi(API api) {
7585
.put(VIRTUAL_SERVICE_REQUEST_HEADERS, api.getRequestOperation())
7686
.put(VIRTUAL_SERVICE_VIRTUAL_CLUSTER_NAME, api.getVirtualClusterName())
7787
.put(VIRTUAL_SERVICE_VIRTUAL_CLUSTER_HEADERS, getVirtualClusterHeaders(api))
78-
.put(VIRTUAL_SERVICE_STATS, api.getStatsMeta());
88+
.put(VIRTUAL_SERVICE_RESP_EXCEPTION_CODE, api.getCustomDefaultRespCode())
89+
;
90+
91+
return handleApiMetaMap(api,tp);
92+
}
93+
94+
/**
95+
* 处理VirtualService metadata 数据
96+
*
97+
* @param api 上层输入的API数据
98+
* @param tp 模板参数
99+
* @return TemplateParams
100+
*/
101+
private TemplateParams handleApiMetaMap(API api, TemplateParams tp) {
102+
if (CollectionUtils.isEmpty(api.getMetaMap())) {
103+
return tp;
104+
}
105+
Iterator<Map.Entry<String, String>> iterator = api.getMetaMap().entrySet().iterator();
106+
while (iterator.hasNext()) {
107+
Map.Entry<String, String> next = iterator.next();
108+
handleApiMeta(next.getKey(), next.getValue(), tp);
109+
}
110+
return tp;
111+
}
79112

113+
/**
114+
* 处理VirtualService metadata 数据
115+
*
116+
* @param name 上层输入的metadata类型
117+
* @param value 上层输入的metadata数据
118+
* @param tp 模板参数
119+
* @return TemplateParams
120+
*/
121+
private TemplateParams handleApiMeta(String name, String value, TemplateParams tp) {
122+
CRDMetaEnum metaEnum = CRDMetaEnum.get(VirtualService.class, name);
123+
if (metaEnum == null) {
124+
logger.warn("find null meta enum ,please check input content , target class is {} , name is {} ", VirtualService.class, name);
125+
return tp;
126+
}
127+
try {
128+
switch (metaEnum) {
129+
case VIRTUAL_SERVICE_STATS_META:
130+
tp.put(metaEnum.getTemplateName(), metaEnum.getTransData(value));
131+
break;
132+
case VIRTUAL_SERVICE_DUBBO_META:
133+
handleDubboMeta(tp, metaEnum.getTransData(value));
134+
break;
135+
default:
136+
break;
137+
}
138+
} catch (JsonProcessingException e) {
139+
logger.warn("meta content parse failed , errMsg is {}", e.getMessage());
140+
}
80141
return tp;
81142
}
82143

144+
/**
145+
* 将Dubbo meta 元数据信息加入模板参数中
146+
*
147+
* @param tp 模板参数
148+
* @param info dubbo meta信息
149+
* @return TemplateParams
150+
*/
151+
private TemplateParams handleDubboMeta(TemplateParams tp, DubboInfoDto info) {
152+
tp.put(VIRTUAL_SERVICE_DUBBO_META_SERVICE, info.getInterfaceName())
153+
.put(VIRTUAL_SERVICE_DUBBO_META_VERSION, info.getVersion())
154+
.put(VIRTUAL_SERVICE_DUBBO_META_METHOD, info.getMethod())
155+
.put(VIRTUAL_SERVICE_DUBBO_META_GROUP, info.getGroup())
156+
.put(VIRTUAL_SERVICE_DUBBO_META_SOURCE, info.getParamSource())
157+
.put(VIRTUAL_SERVICE_DUBBO_META_PARAMS, info.getParams())
158+
.put(VIRTUAL_SERVICE_DUBBO_META_ATTACHMENTS, info.getDubboAttachment())
159+
;
160+
return tp;
161+
}
162+
163+
164+
83165
protected String getOrDefault(String value, String defaultValue) {
84166
return StringUtils.isEmpty(value) ? defaultValue : value;
85167
}

hango-api-plane-server/src/main/java/org/hango/cloud/core/gateway/handler/GatewayPluginDataHandler.java

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -41,55 +41,27 @@ public List<TemplateParams> handle(GatewayPlugin plugin) {
4141
Map<String, List<String>> gatewayPluginMap = HandlerUtil.getGatewayPlugins(fragments);
4242
TemplateParams gatewayPluginParams = TemplateParams.instance()
4343
.put(TemplateConst.GATEWAY_PLUGIN_GATEWAYS, getGatewayName(plugin))
44-
.put(TemplateConst.GATEWAY_PLUGIN_NAME, getGatewayPluginName(plugin))
44+
.put(TemplateConst.GATEWAY_PLUGIN_NAME, HandlerUtil.getGatewayPluginName(plugin))
4545
.put(TemplateConst.GATEWAY_PLUGIN_PLUGINS, gatewayPluginMap);
4646

4747
// 路由和全局插件模板渲染数据区分填充
4848
if (plugin.isRoutePlugin()) {
4949
gatewayPluginParams
50-
.put(TemplateConst.GATEWAY_PLUGIN_ROUTES, getRouteList(plugin))
51-
.put(TemplateConst.RESOURCE_IDENTITY, getIdentity(plugin))
50+
.put(TemplateConst.GATEWAY_PLUGIN_ROUTES, HandlerUtil.getRouteList(plugin))
51+
.put(TemplateConst.RESOURCE_IDENTITY, HandlerUtil.getIdentity(plugin))
5252
.put(TemplateConst.SERVICE_INFO_API_SERVICE, PluginConstant.DEFAULT_SERVICE_NAME)
5353
.put(TemplateConst.SERVICE_INFO_API_GATEWAY, plugin.getGateway())
5454
.put(TemplateConst.SERVICE_INFO_API_NAME, plugin.getRouteId());
5555
} else if (plugin.isGlobalPlugin()) {
56-
if (!CollectionUtils.isEmpty(plugin.getHosts())){
57-
Integer port = plugin.getPort();
58-
List<String> hosts = plugin.getHosts().stream().map(host -> host + ":" + port).collect(Collectors.toList());
59-
plugin.setHosts(hosts);
60-
}
61-
gatewayPluginParams.put(TemplateConst.GATEWAY_PLUGIN_HOSTS, plugin.getHosts());
56+
gatewayPluginParams.put(TemplateConst.GATEWAY_PLUGIN_HOSTS, HandlerUtil.completeHosts(plugin));
6257
}
6358

6459
params.addAll(Arrays.asList((gatewayPluginParams)));
6560

6661
return params;
6762
}
6863

69-
private String getIdentity(GatewayPlugin plugin) {
70-
return String.format("%s-%s", plugin.getRouteId(), plugin.getGateway());
71-
}
72-
73-
private List<String> getRouteList(GatewayPlugin plugin) {
74-
final String routeId = plugin.getRouteId();
75-
Integer port = plugin.getPort();
76-
return plugin.getHosts().stream()
77-
.map(host -> host + ":"+ port + "/" + routeId)
78-
.collect(Collectors.toList());
79-
}
80-
8164
private List<String> getGatewayName(GatewayPlugin plugin) {
8265
return Collections.singletonList(String.format("%s/%s", gatewayNamespace, plugin.getGateway()));
8366
}
84-
85-
private String getGatewayPluginName(GatewayPlugin plugin) {
86-
String pluginName = PluginConstant.DEFAULT_PLUGIN_NAME;
87-
88-
if (plugin.isRoutePlugin()) {
89-
pluginName = plugin.getRouteId() + "-" + plugin.getGateway();
90-
} else if (plugin.isGlobalPlugin()) {
91-
pluginName = plugin.getCode().toLowerCase();
92-
}
93-
return pluginName;
94-
}
9567
}

0 commit comments

Comments
 (0)