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

support dubbo bridge #10

Merged
merged 6 commits into from
Jan 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import org.hango.cloud.dashboard.apiserver.dto.DubboInfoDto;
import org.hango.cloud.dashboard.apiserver.meta.DubboInfo;
import org.hango.cloud.dashboard.apiserver.meta.errorcode.ErrorCode;
import org.hango.cloud.dashboard.envoy.web.dto.EnvoyRouteRuleHeaderOperationDto;

/**
* @author zhangbj
Expand Down Expand Up @@ -83,13 +82,11 @@ public interface IDubboService {

ErrorCode checkAndComplete(DubboInfoDto dto);


/**
* 将Dubbo信息转换为Envoy Head to Add 信息
*
* 设置原始类型默认值
* @param dto
* @param headerOperationDto
* @return
*/
EnvoyRouteRuleHeaderOperationDto getDubboHeaderOperation(DubboInfoDto dto, EnvoyRouteRuleHeaderOperationDto headerOperationDto);
void parseDefaultValue(DubboInfoDto dto);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.BooleanUtils;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.hango.cloud.dashboard.apiserver.dao.IDubboDao;
Expand All @@ -13,22 +13,29 @@
import org.hango.cloud.dashboard.apiserver.meta.RegistryCenterEnum;
import org.hango.cloud.dashboard.apiserver.meta.errorcode.CommonErrorCode;
import org.hango.cloud.dashboard.apiserver.meta.errorcode.ErrorCode;
import org.hango.cloud.dashboard.apiserver.service.*;
import org.hango.cloud.dashboard.apiserver.service.IDubboMetaService;
import org.hango.cloud.dashboard.apiserver.service.IDubboService;
import org.hango.cloud.dashboard.apiserver.service.IRouteRuleInfoService;
import org.hango.cloud.dashboard.apiserver.service.IRouteRuleProxyService;
import org.hango.cloud.dashboard.apiserver.service.IServiceProxyService;
import org.hango.cloud.dashboard.apiserver.util.ClassTypeUtil;
import org.hango.cloud.dashboard.apiserver.util.Const;
import org.hango.cloud.dashboard.apiserver.util.ZkClientUtils;
import org.hango.cloud.dashboard.envoy.dao.IRouteRuleProxyDao;
import org.hango.cloud.dashboard.envoy.meta.RouteRuleInfo;
import org.hango.cloud.dashboard.envoy.meta.RouteRuleProxyInfo;
import org.hango.cloud.dashboard.envoy.meta.ServiceProxyInfo;
import org.hango.cloud.dashboard.envoy.web.dto.EnvoyRouteRuleHeaderOperationDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.hango.cloud.dashboard.apiserver.util.Const.POSITION_COOKIE;
Expand Down Expand Up @@ -374,89 +381,35 @@ private boolean publishToEnvoy(DubboInfoDto dto, boolean isDelete) {
logger.info("发布失败,未找到已发布的路由,已发布路由ID为 {}", dto.getObjectId());
return false;
}
parseDefaultValue(dto);
RouteRuleInfo routeRule = envoyRouteRuleInfoService.getRouteRuleInfoById(routeRuleProxy.getRouteRuleId());
if (routeRule == null) {
logger.info("发布失败,未找到路由,路由ID为 {}", routeRuleProxy.getRouteRuleId());
return false;
}
EnvoyRouteRuleHeaderOperationDto headerOperation = JSON.parseObject(routeRule.getHeaderOperation(), EnvoyRouteRuleHeaderOperationDto.class);
headerOperation = getDubboHeaderOperation(isDelete ? null : dto, headerOperation);
routeRuleProxy.setHeaderOperation(headerOperation);
Map<String, String> metaMap = routeRuleProxy.getMetaMap() == null ? Maps.newHashMap() : routeRuleProxy.getMetaMap();
metaMap.put("DubboMeta", isDelete ? StringUtils.EMPTY : JSON.toJSONString(dto));
routeRuleProxy.setMetaMap(metaMap);
return Const.ERROR_RESULT != envoyRouteRuleProxyService.updateEnvoyRouteRuleProxy(routeRuleProxy);
}


@Override
public EnvoyRouteRuleHeaderOperationDto getDubboHeaderOperation(DubboInfoDto dto, EnvoyRouteRuleHeaderOperationDto headerOperation) {
if (headerOperation == null) {
headerOperation = new EnvoyRouteRuleHeaderOperationDto();
}
if (dto == null) {
dto = new DubboInfoDto();
}
EnvoyRouteRuleHeaderOperationDto.RequestOperation requestOperation = headerOperation.getRequestOperation();
if (requestOperation == null) {
requestOperation = headerOperation.new RequestOperation();
headerOperation.setRequestOperation(requestOperation);
}
Map<String, String> add = requestOperation.getAdd();
if (add == null) {
add = new HashMap<>();
requestOperation.setAdd(add);
}

add.put(Const.HEADER_DUBBO_INTERFACE, dto.getInterfaceName());
add.put(Const.HEADER_DUBBO_METHOD, dto.getMethod());
add.put(Const.HEADER_DUBBO_GROUP, dto.getGroup());
add.put(Const.HEADER_DUBBO_VERSION, dto.getVersion());
add.put(Const.HEADER_DUBBO_PARAMS, dto.getParamToStr());
add.put(Const.HEADER_DUBBO_PARAM_SOURCE, dto.getParamSource());
add.put(Const.HEADER_DUBBO_CUSTOM_PARAMS_MAPPING_SWITCH, BooleanUtils.toStringTrueFalse(dto.getCustomParamMapping()));
List<DubboInfoDto.DubboParam> params = dto.getParams();
if (!CollectionUtils.isEmpty(params)){
List<String> genericInfoList = params.stream().map(DubboInfoDto.DubboParam::getGenericInfo).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(genericInfoList)){
add.put(Const.HEADER_DUBBO_GENERIC, StringUtils.join(genericInfoList, ";"));
}
if (dto.getCustomParamMapping()){
List<Object> defaultValueList = params.stream().map(o -> parseDefaultValue(o.getValue(), o.getDefaultValue())).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(defaultValueList)){
add.put(Const.HEADER_DUBBO_DEFAULT, JSONObject.toJSONString(defaultValueList));
}
List<String> requiredList = params.stream().map(o -> o.isRequired() ? "T" : "F").collect(Collectors.toList());
if (!CollectionUtils.isEmpty(requiredList)){
add.put(Const.HEADER_DUBBO_REQUIRED, StringUtils.join(requiredList, ";"));
}
}

}
List<DubboInfoDto.DubboAttachmentDto> dubboAttachment = dto.getDubboAttachment();
if (!CollectionUtils.isEmpty(dubboAttachment)){
List<String> headers = new ArrayList<>();
List<String> cookies = new ArrayList<>();
for (DubboInfoDto.DubboAttachmentDto dubboAttachmentDto : dubboAttachment) {
String paramPosition = dubboAttachmentDto.getParamPosition();
if (POSITION_HEADER.equalsIgnoreCase(paramPosition)){
headers.add(dubboAttachmentDto.getClientParamName() + ":" + dubboAttachmentDto.getServerParamName());
}else if (POSITION_COOKIE.equalsIgnoreCase(paramPosition)){
cookies.add(dubboAttachmentDto.getClientParamName() + ":" + dubboAttachmentDto.getServerParamName());

}
}
if (!CollectionUtils.isEmpty(headers)){
add.put(Const.HEADER_DUBBO_ATTACTMENT_HEADER, String.join(";", headers));
}
if (!CollectionUtils.isEmpty(cookies)){
add.put(Const.HEADER_DUBBO_ATTACTMENT_COOKIE, String.join(";", cookies));
}
}
return headerOperation;
}

public Object parseDefaultValue(String typeString, Object value){
if (value == null && ClassTypeUtil.PrimitiveTypeEnum.isPrimitiveType(typeString)){
return ClassTypeUtil.PrimitiveTypeEnum.getDefaultValueByName(typeString);
}
return value;
}

public void parseDefaultValue(DubboInfoDto.DubboParam param){
Object o = parseDefaultValue(param.getValue(), param.getDefaultValue());
param.setDefaultValue(o);
}

@Override
public void parseDefaultValue(DubboInfoDto dto){
List<DubboInfoDto.DubboParam> params = dto.getParams();
if (!CollectionUtils.isEmpty(params)){
params.stream().forEach(this::parseDefaultValue);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.hango.cloud.dashboard.envoy.web.dto.HttpRetryDto;

import java.util.List;
import java.util.Map;

/**
* 路由规则发布信息
Expand Down Expand Up @@ -101,6 +102,60 @@ public class RouteRuleProxyInfo extends RouteRuleMatchInfo {
*/
private long mirrorServiceId;

/**
* meta数据传输集
* Map<mata_type,meta_data>
* mata_type meta类型
*
* mata_type: 路由meta数据类型
* meta_data: 路由meta数据值,使用JSON传输
* eg.
* {
* "DubboMeta": {
* "ObjectType": "route",
* "ObjectId": 259,
* "Params": [
* {
* "Key": "str",
* "Value": "java.lang.String",
* "GenericInfo": ".dataA:com.demo.B,.dataAA:com.demo.B,.dataA.dataB:com.demo.C,.dataAA.dataB:com.demo.C",
* "Required": false,
* "DefaultValue": "sdfsdfs",
* "_formTableKey": 1660649073793,
* "index": 0
* },
* {
* "Key": "wer",
* "Value": "java.lang.Integer",
* "GenericInfo": null,
* "Required": true,
* "DefaultValue": null,
* "_formTableKey": 1660649073793
* }
* ],
* "Method": "echoStrAndInt",
* "CustomParamMapping": true,
* "ParamSource": "body",
* "Attachment": [
* {
* "ClientParamName": "xcvxcv",
* "Description": "cxvxcv",
* "ParamPosition": "Header",
* "ServerParamName": "cvcv",
* "distinctName": "Headerxcvxcv",
* "_formTableKey": 1660648830195
* }
* ],
* "MethodWorks": true
* },
* "StatsMeta": [
* "/test",
* "/test1"
* ]
* }
*/
private Map<String, String> metaMap;

public long getMirrorServiceId() {
return mirrorServiceId;
}
Expand Down Expand Up @@ -269,6 +324,14 @@ public void setGwType(String gwType) {
this.gwType = gwType;
}

public Map<String, String> getMetaMap() {
return metaMap;
}

public void setMetaMap(Map<String, String> metaMap) {
this.metaMap = metaMap;
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.hango.cloud.dashboard.apiserver.config.ApiServerConfig;
import org.hango.cloud.dashboard.apiserver.dto.DubboInfoDto;
import org.hango.cloud.dashboard.apiserver.dto.DubboMetaDto;
import org.hango.cloud.dashboard.apiserver.dto.RegistryCenterDto;
import org.hango.cloud.dashboard.apiserver.meta.DubboInfo;
import org.hango.cloud.dashboard.apiserver.meta.GatewayInfo;
import org.hango.cloud.dashboard.apiserver.meta.HttpClientResponse;
import org.hango.cloud.dashboard.apiserver.meta.RegistryCenterEnum;
Expand All @@ -21,7 +24,6 @@
import org.hango.cloud.dashboard.apiserver.service.IRouteRuleProxyService;
import org.hango.cloud.dashboard.apiserver.service.IServiceInfoService;
import org.hango.cloud.dashboard.apiserver.service.IServiceProxyService;
import org.hango.cloud.dashboard.apiserver.service.impl.DubboServiceImpl;
import org.hango.cloud.dashboard.apiserver.util.Const;
import org.hango.cloud.dashboard.apiserver.web.holder.ActionInfoHolder;
import org.hango.cloud.dashboard.apiserver.web.holder.UserPermissionHolder;
Expand Down Expand Up @@ -349,7 +351,6 @@ public JSONObject generateBodyForPublishOrDelete(GatewayInfo gatewayInfo, RouteR
body.put("Order", routeRuleProxyInfo.getOrders());
body.put("ProjectId", routeRuleInfo.getProjectId());
EnvoyRouteRuleHeaderOperationDto headerOperation = JSON.parseObject(routeRuleInfo.getHeaderOperation(), EnvoyRouteRuleHeaderOperationDto.class);
headerOperation = processDubboInfoForPublishOrDelete(routeRuleInfo, routeRuleProxyInfo, headerOperation);
if (headerOperation != null) {
body.put("RequestOperation", headerOperation.getRequestOperation());
}
Expand Down Expand Up @@ -430,35 +431,67 @@ public JSONObject generateBodyForPublishOrDelete(GatewayInfo gatewayInfo, RouteR
body.put("MirrorTraffic", mirrorTraffic);
}

body.put("MetaMap",processRouteMetadata(routeRuleProxyInfo));
return body;
}

/**
* 处理Dubbo路由额外信息
* <p>
* 优先使用RouteRuleProxyInfo中的路由头信息
* 该属性仅在单独处理Dubbo转换信息时,才被填充{@link DubboServiceImpl}
* 添加路由 metadata 数据
*
* @param routeRuleInfo
* @param routeRuleProxyInfo
* @param headerOperation
* @return
*/
private EnvoyRouteRuleHeaderOperationDto processDubboInfoForPublishOrDelete(RouteRuleInfo routeRuleInfo, RouteRuleProxyInfo routeRuleProxyInfo, EnvoyRouteRuleHeaderOperationDto headerOperation) {
//
//
if (routeRuleProxyInfo.getHeaderOperation() != null) {
return routeRuleProxyInfo.getHeaderOperation();
}
//dubbo 路由Head-To-Add组装
ServiceInfo serviceInfo = serviceInfoService.getServiceById(String.valueOf(routeRuleInfo.getServiceId()));
private Map<String, String> processRouteMetadata(RouteRuleProxyInfo routeRuleProxyInfo) {
Map<String, String> metaMap = routeRuleProxyInfo.getMetaMap() == null ? Maps.newHashMap() : routeRuleProxyInfo.getMetaMap();
//处理路由指标Meta数据
processRouteStatsMeta(routeRuleProxyInfo, metaMap);
//处理Dubbo Meta相关的数据
processDubboMeta(routeRuleProxyInfo, metaMap);
return metaMap;
}

/**
* 添加路由指标Meta数据
*
* @param routeRuleProxyInfo
* @param metaMap
*/
private void processRouteStatsMeta(RouteRuleProxyInfo routeRuleProxyInfo, Map<String, String> metaMap) {
String statsValue = apiServerConfig.getRouteMetricPathStats() ? routeRuleProxyInfo.getUri() : String.valueOf(routeRuleProxyInfo.getRouteRuleId());
Map<String, String> stats = Maps.newHashMap();
stats.put("route_rule_id", statsValue);
metaMap.put("StatsMeta", JSON.toJSONString(stats));
}

/**
* 添加Dubbo Meta相关的数据
*
* @param routeRuleProxyInfo
* @param metaMap
*/
private void processDubboMeta(RouteRuleProxyInfo routeRuleProxyInfo, Map<String, String> metaMap) {
//如果已存在就不进行复写
//适用于Dubbo在创建、更新、删除的场景
//@see DubboServiceImpl publishToEnvoy
String dubboMeta = "DubboMeta";
if (metaMap.containsKey(dubboMeta)){
return;
}
ServiceInfo serviceInfo = serviceInfoService.getServiceById(String.valueOf(routeRuleProxyInfo.getServiceId()));
if (serviceInfo == null) {
return headerOperation;
return;
}
if (!ServiceType.dubbo.name().equals(serviceInfo.getServiceType())) {
return headerOperation;
return;
}
DubboInfo dubboInfo = dubboService.getDubboInfo(routeRuleProxyInfo.getId(), Const.ROUTE);
if (dubboInfo == null) {
return;
}
return dubboService.getDubboHeaderOperation(dubboService.getDubboDto(routeRuleProxyInfo.getId(), Const.ROUTE), headerOperation);
DubboInfoDto dubboDto = DubboInfoDto.toDto(dubboInfo);
dubboService.parseDefaultValue(dubboDto);
metaMap.put(dubboMeta, JSON.toJSONString(dubboDto));

}

/**
Expand Down