mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 12:56:28 +08:00
路由修改
This commit is contained in:
@@ -118,7 +118,7 @@ body{
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.x-body{
|
.x-body{
|
||||||
padding: 20px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
.x-nav{
|
.x-nav{
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
|
@@ -5,6 +5,18 @@ var ApiUtil = (function () {
|
|||||||
// 接口URL,更改此处即可
|
// 接口URL,更改此处即可
|
||||||
var url = 'http://localhost:8082/api';
|
var url = 'http://localhost:8082/api';
|
||||||
var URI_CHAR = '/';
|
var URI_CHAR = '/';
|
||||||
|
var params = {};
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
var aPairs, aTmp;
|
||||||
|
var queryString = window.location.search.toString();
|
||||||
|
queryString = queryString.substring(1, queryString.length); //remove "?"
|
||||||
|
aPairs = queryString.split("&");
|
||||||
|
for (var i = 0; i < aPairs.length; i++) {
|
||||||
|
aTmp = aPairs[i].split("=");
|
||||||
|
params[aTmp[0]] = decodeURIComponent(aTmp[1]);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
function formatUri(uri) {
|
function formatUri(uri) {
|
||||||
if (uri.substring(0, 1) !== URI_CHAR) {
|
if (uri.substring(0, 1) !== URI_CHAR) {
|
||||||
@@ -49,5 +61,8 @@ var ApiUtil = (function () {
|
|||||||
}
|
}
|
||||||
return url + formatUri(uri);
|
return url + formatUri(uri);
|
||||||
}
|
}
|
||||||
|
, getParam: function (paramName) {
|
||||||
|
return params[paramName];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
@@ -1,24 +0,0 @@
|
|||||||
var Common = (function () {
|
|
||||||
|
|
||||||
function initProfiles() {
|
|
||||||
var $profileList = $('#profileList');
|
|
||||||
if ($profileList.length > 0) {
|
|
||||||
ApiUtil.post('system.profile.list', {}, function (resp) {
|
|
||||||
var list = resp.data;
|
|
||||||
var html = [];
|
|
||||||
for (var i = 0; i < list.length; i++) {
|
|
||||||
html.push('<li' + (i == 0 ? ' class="layui-this"' : '') + '>' + list[i] + '</li>');
|
|
||||||
}
|
|
||||||
$profileList.html(html.join(''))
|
|
||||||
|
|
||||||
$profileList.find('li').on('click', function () {
|
|
||||||
window.profile = $(this).text();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initProfiles();
|
|
||||||
|
|
||||||
return {}
|
|
||||||
})();
|
|
@@ -14,7 +14,7 @@ var lib = (function () {
|
|||||||
,'../../assets/lib/layui/layui.js'
|
,'../../assets/lib/layui/layui.js'
|
||||||
,'../../assets/lib/easyopen/sdk.js'
|
,'../../assets/lib/easyopen/sdk.js'
|
||||||
,'../../assets/js/ApiUtil.js'
|
,'../../assets/js/ApiUtil.js'
|
||||||
,'../../assets/js/common.js'
|
,'../../assets/js/profile.js'
|
||||||
]
|
]
|
||||||
|
|
||||||
var jsArr = [];
|
var jsArr = [];
|
||||||
|
30
sop-admin/sop-admin-front/assets/js/profile.js
Normal file
30
sop-admin/sop-admin-front/assets/js/profile.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
;(function () {
|
||||||
|
var currentProfile = ApiUtil.getParam('profile') || 'default';
|
||||||
|
|
||||||
|
ApiUtil.post('system.profile.list', {}, function (resp) {
|
||||||
|
var profileList = resp.data;
|
||||||
|
var html = ['<div class="layui-tab layui-tab-brief" style="margin-top: 0px;">'];
|
||||||
|
html.push('<ul id="profileList" class="layui-tab-title">')
|
||||||
|
for (var i = 0; i < profileList.length; i++) {
|
||||||
|
var profile = profileList[i];
|
||||||
|
var cls = currentProfile == profile ? 'layui-this' : '';
|
||||||
|
html.push('<li><a class="' + cls + '" href="' + getCurrentPage(profile) + '">' + profile + '</a></li>');
|
||||||
|
}
|
||||||
|
html.push('</ul>')
|
||||||
|
html.push('</div>')
|
||||||
|
$('.x-body').prepend(html.join(''));
|
||||||
|
});
|
||||||
|
|
||||||
|
function getCurrentPage(profile) {
|
||||||
|
var currentUrl = location.href.toString();
|
||||||
|
var indexStart = currentUrl.lastIndexOf('/') + 1;
|
||||||
|
var indexEnd = currentUrl.lastIndexOf('?');
|
||||||
|
var page = indexEnd > -1
|
||||||
|
? currentUrl.substring(indexStart, indexEnd)
|
||||||
|
: currentUrl.substring(indexStart);
|
||||||
|
|
||||||
|
return page + '?q=' + new Date().getTime() + '&profile=' + profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.profile = currentProfile;
|
||||||
|
})();
|
@@ -22,37 +22,46 @@
|
|||||||
<i class="layui-icon layui-icon-refresh" style="line-height:30px"></i></a>
|
<i class="layui-icon layui-icon-refresh" style="line-height:30px"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="x-body">
|
<div class="x-body">
|
||||||
<div class="layui-tab" style="margin-top: 0px;" lay-filter="docDemoTabBrief">
|
<div class="layui-row">
|
||||||
<ul id="profileList" class="layui-tab-title">
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="layui-col-md2">
|
|
||||||
<ul id="leftTree"></ul>
|
|
||||||
</div>
|
|
||||||
<div class="layui-col-md10">
|
|
||||||
<div class="layui-row">
|
|
||||||
<form class="layui-form layui-col-md12 x-so" action="" lay-filter="searchFrm">
|
|
||||||
路由名称:
|
|
||||||
<input name="id" class="layui-input" style="width: 200px;" placeholder="输入接口名或版本号">
|
|
||||||
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="searchFilter">
|
|
||||||
<i class="layui-icon layui-icon-search"></i>搜索
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="layui-btn-group demoTable">
|
|
||||||
<button class="layui-btn layui-btn-ms layui-btn-normal" lay-event="addRoute">添加路由</button>
|
|
||||||
</div>
|
|
||||||
<table class="layui-hide" id="routeTable" lay-filter="routeTable"></table>
|
|
||||||
<script type="text/html" id="optBar" >
|
|
||||||
<a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="edit">修改</a>
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="layui-row">
|
||||||
|
<div class="layui-col-md2">
|
||||||
|
<ul id="leftTree"></ul>
|
||||||
|
</div>
|
||||||
|
<div id="optTip" class="layui-col-md2" style="margin-top: 20px;">
|
||||||
|
<i class="layui-icon layui-icon-return"></i>点击树节点查看
|
||||||
|
</div>
|
||||||
|
<div id="rightPart" class="layui-col-md10" style="display: none;">
|
||||||
|
<div class="layui-row">
|
||||||
|
<form class="layui-form layui-col-md12 x-so" action="" lay-filter="searchFrm">
|
||||||
|
路由名称:
|
||||||
|
<input name="id" class="layui-input" style="width: 200px;" placeholder="输入接口名或版本号">
|
||||||
|
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="searchFilter">
|
||||||
|
<i class="layui-icon layui-icon-search"></i>搜索
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-btn-group demoTable">
|
||||||
|
<button class="layui-btn layui-btn-ms layui-btn-normal" lay-event="addRoute">
|
||||||
|
<i class="layui-icon layui-icon-add-circle-fine"></i>添加路由
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<table class="layui-hide" id="routeTable" lay-filter="routeTable"></table>
|
||||||
|
<script type="text/html" id="optBar" >
|
||||||
|
<a class="layui-btn layui-btn-xs layui-btn-normal" lay-event="edit">修改</a>
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="updateWin" style="display: none;padding: 20px;">
|
<div id="updateWin" style="display: none;padding: 20px;">
|
||||||
<form class="layui-form" action="" lay-filter="updateWinFilter">
|
<form class="layui-form" action="" lay-filter="updateWinFilter">
|
||||||
|
<input type="hidden" name="serviceId" />
|
||||||
|
<input type="hidden" name="profile" />
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">id</label>
|
<label class="layui-form-label">id</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
@@ -65,6 +74,12 @@
|
|||||||
<input type="text" name="uri" lay-verify="required" class="layui-input"/>
|
<input type="text" name="uri" lay-verify="required" class="layui-input"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">path</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="path" class="layui-input"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">忽略验证</label>
|
<label class="layui-form-label">忽略验证</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
@@ -75,8 +90,14 @@
|
|||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">状态</label>
|
<label class="layui-form-label">状态</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="radio" name="disabled" value="true" title="启用">
|
<input type="radio" name="disabled" value="false" title="启用">
|
||||||
<input type="radio" name="disabled" value="false" title="<span class='x-red'>禁用</span>">
|
<input type="radio" name="disabled" value="true" title="<span class='x-red'>禁用</span>">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="updateWinSubmitFilter">保存</button>
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary" onclick="layer.closeAll()">取消</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@@ -2,62 +2,26 @@ lib.use(['element', 'table', 'tree', 'form'], function () {
|
|||||||
var form = layui.form;
|
var form = layui.form;
|
||||||
var table = layui.table;
|
var table = layui.table;
|
||||||
var currentServiceId;
|
var currentServiceId;
|
||||||
|
var routeTable;
|
||||||
|
var profile = window.profile;
|
||||||
|
|
||||||
var routeTable = table.render({
|
form.on('submit(searchFilter)', function (data) {
|
||||||
elem: '#routeTable'
|
var param = data.field;
|
||||||
, url: ApiUtil.createUrl('route.list')
|
param.serviceId = currentServiceId;
|
||||||
, cellMinWidth: 80 //全局定义常规单元格的最小宽度,layui 2.2.1 新增
|
searchTable(param)
|
||||||
, cols: [[
|
return false;
|
||||||
{field: 'id', title: 'id(接口名+版本号)'}
|
|
||||||
, {field: 'uri', title: 'uri'}
|
|
||||||
, {
|
|
||||||
field: 'ignoreValidate', width: 80, title: '忽略验证', templet: function (row) {
|
|
||||||
return row.ignoreValidate
|
|
||||||
? '<span class="x-red">是</span>'
|
|
||||||
: '<span>否</span>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
field: 'disabled', title: '状态', width: 80, templet: function (row) {
|
|
||||||
return row.disabled
|
|
||||||
? '<span class="x-red">禁用</span>'
|
|
||||||
: '<span class="x-green">启用</span>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, {fixed: 'right', title: '操作', toolbar: '#optBar', width: 100}
|
|
||||||
]]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//监听单元格事件
|
//监听提交
|
||||||
table.on('tool(routeTable)', function(obj){
|
form.on('submit(updateWinSubmitFilter)', function(data) {
|
||||||
var data = obj.data;
|
ApiUtil.post('route.update', data.field, function (resp) {
|
||||||
if(obj.event === 'edit'){
|
layer.closeAll();
|
||||||
//表单初始赋值
|
routeTable.reload();
|
||||||
data.disabled = !data.disabled + '';
|
})
|
||||||
data.ignoreValidate = data.ignoreValidate + '';
|
return false;
|
||||||
form.val('updateWinFilter', data)
|
|
||||||
|
|
||||||
layer.open({
|
|
||||||
type: 1
|
|
||||||
,title: '修改路由'
|
|
||||||
,area: ['490px', '360px']
|
|
||||||
,content: $('#updateWin') //这里content是一个DOM,注意:最好该元素要存放在body最外层,否则可能被其它的相对元素所影响
|
|
||||||
,btn: ['保存', '取消']
|
|
||||||
,yes: function(index, layero){
|
|
||||||
|
|
||||||
}
|
|
||||||
,btn2: function(index, layero){
|
|
||||||
layer.close(index);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#profileList').find('li').on('click', function () {
|
function initTree() {
|
||||||
initTree($(this).text());
|
|
||||||
})
|
|
||||||
|
|
||||||
function initTree(profile) {
|
|
||||||
ApiUtil.post('service.list', {profile: profile}, function (resp) {
|
ApiUtil.post('service.list', {profile: profile}, function (resp) {
|
||||||
var serviceList = resp.data;
|
var serviceList = resp.data;
|
||||||
var children = [];
|
var children = [];
|
||||||
@@ -68,10 +32,7 @@ lib.use(['element', 'table', 'tree', 'form'], function () {
|
|||||||
name: serviceInfo.serviceId
|
name: serviceInfo.serviceId
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 清空表格
|
|
||||||
reloadRightPart({name: ''})
|
|
||||||
// 清空树
|
|
||||||
$('#leftTree').text('');
|
|
||||||
layui.tree({
|
layui.tree({
|
||||||
elem: '#leftTree' //传入元素选择器
|
elem: '#leftTree' //传入元素选择器
|
||||||
, nodes: [{ //节点
|
, nodes: [{ //节点
|
||||||
@@ -93,6 +54,8 @@ lib.use(['element', 'table', 'tree', 'form'], function () {
|
|||||||
* @param node 树节点
|
* @param node 树节点
|
||||||
*/
|
*/
|
||||||
function reloadRightPart(node) {
|
function reloadRightPart(node) {
|
||||||
|
$('#optTip').hide();
|
||||||
|
$('#rightPart').show();
|
||||||
var serviceId = node.name;
|
var serviceId = node.name;
|
||||||
currentServiceId = serviceId;
|
currentServiceId = serviceId;
|
||||||
searchTable({
|
searchTable({
|
||||||
@@ -100,21 +63,70 @@ lib.use(['element', 'table', 'tree', 'form'], function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
form.on('submit(searchFilter)', function (data) {
|
/**
|
||||||
var param = data.field;
|
* 查询表格
|
||||||
param.serviceId = currentServiceId;
|
* @param params
|
||||||
searchTable(param)
|
*/
|
||||||
return false;
|
function searchTable(params) {
|
||||||
});
|
var postData = {
|
||||||
|
data: JSON.stringify(params)
|
||||||
|
, profile: profile
|
||||||
|
};
|
||||||
|
|
||||||
function searchTable(param) {
|
if (!routeTable) {
|
||||||
routeTable.reload({
|
routeTable = table.render({
|
||||||
where: {
|
elem: '#routeTable'
|
||||||
data: JSON.stringify(param)
|
, url: ApiUtil.createUrl('route.list')
|
||||||
, profile: window.profile
|
, where: postData
|
||||||
}
|
, cellMinWidth: 80 //全局定义常规单元格的最小宽度,layui 2.2.1 新增
|
||||||
})
|
, cols: [[
|
||||||
|
{field: 'id', title: 'id(接口名+版本号)', width: 250}
|
||||||
|
, {field: 'uri', title: 'uri', width: 200}
|
||||||
|
, {field: 'path', title: 'path', width: 200}
|
||||||
|
, {
|
||||||
|
field: 'ignoreValidate', width: 80, title: '忽略验证', templet: function (row) {
|
||||||
|
return row.ignoreValidate
|
||||||
|
? '<span class="x-red">是</span>'
|
||||||
|
: '<span>否</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
field: 'disabled', title: '状态', width: 80, templet: function (row) {
|
||||||
|
return row.disabled
|
||||||
|
? '<span class="x-red">禁用</span>'
|
||||||
|
: '<span class="x-green">启用</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, {fixed: 'right', title: '操作', toolbar: '#optBar', width: 100}
|
||||||
|
]]
|
||||||
|
});
|
||||||
|
|
||||||
|
//监听单元格事件
|
||||||
|
table.on('tool(routeTable)', function(obj) {
|
||||||
|
var data = obj.data;
|
||||||
|
if(obj.event === 'edit'){
|
||||||
|
//表单初始赋值
|
||||||
|
data.disabled = data.disabled + '';
|
||||||
|
data.ignoreValidate = data.ignoreValidate + '';
|
||||||
|
data.serviceId = currentServiceId;
|
||||||
|
data.profile = profile;
|
||||||
|
form.val('updateWinFilter', data)
|
||||||
|
|
||||||
|
layer.open({
|
||||||
|
type: 1
|
||||||
|
,title: '修改路由'
|
||||||
|
,area: ['500px', '400px']
|
||||||
|
,content: $('#updateWin') //这里content是一个DOM,注意:最好该元素要存放在body最外层,否则可能被其它的相对元素所影响
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
routeTable.reload({
|
||||||
|
where: postData
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initTree('default');
|
initTree();
|
||||||
|
|
||||||
});
|
});
|
@@ -22,10 +22,6 @@
|
|||||||
<i class="layui-icon layui-icon-refresh" style="line-height:30px"></i></a>
|
<i class="layui-icon layui-icon-refresh" style="line-height:30px"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="x-body">
|
<div class="x-body">
|
||||||
<div class="layui-tab" style="margin-top: 0px;" lay-filter="docDemoTabBrief">
|
|
||||||
<ul id="profileList" class="layui-tab-title">
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="layui-row">
|
<div class="layui-row">
|
||||||
<form class="layui-form layui-col-md12 x-so" action="" lay-filter="searchFrm">
|
<form class="layui-form layui-col-md12 x-so" action="" lay-filter="searchFrm">
|
||||||
服务名称:
|
服务名称:
|
||||||
|
@@ -6,11 +6,13 @@ import com.gitee.easyopen.annotation.ApiService;
|
|||||||
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
import com.gitee.easyopen.doc.annotation.ApiDoc;
|
||||||
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
|
||||||
import com.gitee.sop.adminserver.api.service.param.RouteSearchParam;
|
import com.gitee.sop.adminserver.api.service.param.RouteSearchParam;
|
||||||
|
import com.gitee.sop.adminserver.api.service.param.UpdateRouteParam;
|
||||||
import com.gitee.sop.adminserver.bean.GatewayRouteDefinition;
|
import com.gitee.sop.adminserver.bean.GatewayRouteDefinition;
|
||||||
import com.gitee.sop.adminserver.bean.SopAdminConstants;
|
import com.gitee.sop.adminserver.bean.SopAdminConstants;
|
||||||
import com.gitee.sop.adminserver.bean.ZookeeperContext;
|
import com.gitee.sop.adminserver.bean.ZookeeperContext;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.curator.framework.recipes.cache.ChildData;
|
import org.apache.curator.framework.recipes.cache.ChildData;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -54,4 +56,15 @@ public class RouteListApi {
|
|||||||
return routeDefinitionList;
|
return routeDefinitionList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Api(name = "route.update")
|
||||||
|
@ApiDocMethod(description = "修改路由")
|
||||||
|
void updateRoute(UpdateRouteParam param) throws Exception {
|
||||||
|
String serviceIdPath = ZookeeperContext.getSopRouteRootPath(param.getProfile()) + "/" + param.getServiceId();
|
||||||
|
String zookeeperRoutePath = serviceIdPath + "/" + param.getId();
|
||||||
|
String data = ZookeeperContext.getData(zookeeperRoutePath);
|
||||||
|
GatewayRouteDefinition routeDefinition = JSON.parseObject(data, GatewayRouteDefinition.class);
|
||||||
|
BeanUtils.copyProperties(param, routeDefinition);
|
||||||
|
ZookeeperContext.setData(zookeeperRoutePath, JSON.toJSONString(routeDefinition));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,57 @@
|
|||||||
|
package com.gitee.sop.adminserver.api.service.param;
|
||||||
|
|
||||||
|
import com.gitee.easyopen.doc.annotation.ApiDocField;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author tanghc
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class UpdateRouteParam {
|
||||||
|
|
||||||
|
@NotBlank(message = "profile不能为空")
|
||||||
|
@ApiDocField(description = "profile")
|
||||||
|
private String profile;
|
||||||
|
|
||||||
|
@NotBlank(message = "serviceId不能为空")
|
||||||
|
@ApiDocField(description = "serviceId")
|
||||||
|
private String serviceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由的Id
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "id不能为空")
|
||||||
|
@ApiDocField(description = "路由id")
|
||||||
|
private String id = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由规则转发的目标uri
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "uri不能为空")
|
||||||
|
@ApiDocField(description = "路由uri")
|
||||||
|
private String uri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uri后面跟的path
|
||||||
|
*/
|
||||||
|
@ApiDocField(description = "路由path")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否忽略验证,业务参数验证除外
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
@ApiDocField(description = "是否忽略验证")
|
||||||
|
private Boolean ignoreValidate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否禁用
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
@ApiDocField(description = "是否禁用")
|
||||||
|
private Boolean disabled;
|
||||||
|
}
|
@@ -10,16 +10,43 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class GatewayRouteDefinition {
|
public class GatewayRouteDefinition {
|
||||||
/** 路由的Id */
|
/**
|
||||||
|
* 路由的Id
|
||||||
|
*/
|
||||||
private String id = "";
|
private String id = "";
|
||||||
/** 路由断言集合配置 */
|
|
||||||
|
/**
|
||||||
|
* 路由断言集合配置
|
||||||
|
*/
|
||||||
private List<GatewayPredicateDefinition> predicates = new ArrayList<>();
|
private List<GatewayPredicateDefinition> predicates = new ArrayList<>();
|
||||||
/** 路由过滤器集合配置 */
|
|
||||||
|
/**
|
||||||
|
* 路由过滤器集合配置
|
||||||
|
*/
|
||||||
private List<GatewayFilterDefinition> filters = new ArrayList<>();
|
private List<GatewayFilterDefinition> filters = new ArrayList<>();
|
||||||
/** 路由规则转发的目标uri */
|
|
||||||
|
/**
|
||||||
|
* 路由规则转发的目标uri
|
||||||
|
*/
|
||||||
private String uri;
|
private String uri;
|
||||||
/** 路由执行的顺序 */
|
|
||||||
|
/**
|
||||||
|
* uri后面跟的path
|
||||||
|
*/
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由执行的顺序
|
||||||
|
*/
|
||||||
private int order = 0;
|
private int order = 0;
|
||||||
/** 是否忽略验证,业务参数验证除外 */
|
|
||||||
|
/**
|
||||||
|
* 是否忽略验证,业务参数验证除外
|
||||||
|
*/
|
||||||
private boolean ignoreValidate;
|
private boolean ignoreValidate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否禁用
|
||||||
|
*/
|
||||||
|
private boolean disabled;
|
||||||
}
|
}
|
@@ -7,6 +7,7 @@ import org.apache.curator.framework.CuratorFrameworkFactory;
|
|||||||
import org.apache.curator.framework.recipes.cache.ChildData;
|
import org.apache.curator.framework.recipes.cache.ChildData;
|
||||||
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
|
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
|
||||||
import org.apache.curator.retry.ExponentialBackoffRetry;
|
import org.apache.curator.retry.ExponentialBackoffRetry;
|
||||||
|
import org.apache.zookeeper.data.Stat;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@@ -68,6 +69,18 @@ public class ZookeeperContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Stat setData(String path, String data) throws Exception {
|
||||||
|
return getClient().setData().forPath(path, data.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getData(String path) throws Exception {
|
||||||
|
if (!isPathExist(path)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
byte[] data = getClient().getData().forPath(path);
|
||||||
|
return new String(data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取子节点数据
|
* 获取子节点数据
|
||||||
* @param parentPath 父节点
|
* @param parentPath 父节点
|
||||||
|
@@ -17,6 +17,12 @@ public class BaseRouteDefinition {
|
|||||||
* 路由规则转发的目标uri
|
* 路由规则转发的目标uri
|
||||||
*/
|
*/
|
||||||
private String uri;
|
private String uri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uri后面跟的path
|
||||||
|
*/
|
||||||
|
private String path;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 路由执行的顺序
|
* 路由执行的顺序
|
||||||
*/
|
*/
|
||||||
|
@@ -41,7 +41,7 @@ public class GatewayZookeeperRouteManager extends BaseRouteManager<GatewayServic
|
|||||||
protected GatewayTargetRoute buildRouteDefinition(GatewayServiceRouteInfo serviceRouteInfo, GatewayRouteDefinition gatewayRouteDefinition) {
|
protected GatewayTargetRoute buildRouteDefinition(GatewayServiceRouteInfo serviceRouteInfo, GatewayRouteDefinition gatewayRouteDefinition) {
|
||||||
RouteDefinition routeDefinition = new RouteDefinition();
|
RouteDefinition routeDefinition = new RouteDefinition();
|
||||||
routeDefinition.setId(gatewayRouteDefinition.getId());
|
routeDefinition.setId(gatewayRouteDefinition.getId());
|
||||||
routeDefinition.setUri(URI.create(gatewayRouteDefinition.getUri()));
|
routeDefinition.setUri(URI.create(gatewayRouteDefinition.getUri() + "#" + gatewayRouteDefinition.getPath()));
|
||||||
routeDefinition.setOrder(gatewayRouteDefinition.getOrder());
|
routeDefinition.setOrder(gatewayRouteDefinition.getOrder());
|
||||||
List<FilterDefinition> filterDefinitionList = new ArrayList<>(gatewayRouteDefinition.getFilters().size());
|
List<FilterDefinition> filterDefinitionList = new ArrayList<>(gatewayRouteDefinition.getFilters().size());
|
||||||
List<PredicateDefinition> predicateDefinitionList = new ArrayList<>(gatewayRouteDefinition.getPredicates().size());
|
List<PredicateDefinition> predicateDefinitionList = new ArrayList<>(gatewayRouteDefinition.getPredicates().size());
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
package com.gitee.sop.gatewaycommon.zuul.route;
|
package com.gitee.sop.gatewaycommon.zuul.route;
|
||||||
|
|
||||||
|
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
|
||||||
import com.gitee.sop.gatewaycommon.param.ApiParam;
|
import com.gitee.sop.gatewaycommon.param.ApiParam;
|
||||||
import com.gitee.sop.gatewaycommon.zuul.ZuulContext;
|
import com.gitee.sop.gatewaycommon.zuul.ZuulContext;
|
||||||
import org.springframework.cloud.netflix.zuul.filters.Route;
|
import org.springframework.cloud.netflix.zuul.filters.Route;
|
||||||
@@ -49,8 +50,9 @@ public class SopRouteLocator implements RouteLocator, Ordered {
|
|||||||
if (zuulTargetRoute == null) {
|
if (zuulTargetRoute == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
// 路由被禁用
|
||||||
if (zuulTargetRoute.getRouteDefinition().isDisabled()) {
|
if (zuulTargetRoute.getRouteDefinition().isDisabled()) {
|
||||||
return null;
|
throw ErrorEnum.ISV_INVALID_METHOD.getErrorMeta().getException();
|
||||||
}
|
}
|
||||||
return zuulTargetRoute.getTargetRouteDefinition();
|
return zuulTargetRoute.getTargetRouteDefinition();
|
||||||
}
|
}
|
||||||
|
@@ -10,5 +10,4 @@ import lombok.Setter;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class ZuulRouteDefinition extends BaseRouteDefinition {
|
public class ZuulRouteDefinition extends BaseRouteDefinition {
|
||||||
private String path;
|
|
||||||
}
|
}
|
||||||
|
@@ -31,7 +31,7 @@ public class ZuulZookeeperRouteManager extends BaseRouteManager<ZuulServiceRoute
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ZuulTargetRoute buildRouteDefinition(ZuulServiceRouteInfo serviceRouteInfo, ZuulRouteDefinition routeDefinition) {
|
protected ZuulTargetRoute buildRouteDefinition(ZuulServiceRouteInfo serviceRouteInfo, ZuulRouteDefinition routeDefinition) {
|
||||||
Route route = new Route(routeDefinition.getId(), RoutePathUtil.findPath(routeDefinition.getUri()), serviceRouteInfo.getServiceId(), null, false, null);
|
Route route = new Route(routeDefinition.getId(), routeDefinition.getPath(), serviceRouteInfo.getServiceId(), null, false, null);
|
||||||
return new ZuulTargetRoute(serviceRouteInfo, routeDefinition, route);
|
return new ZuulTargetRoute(serviceRouteInfo, routeDefinition, route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -106,26 +106,27 @@ public class ServiceZookeeperApiMetaManager implements ApiMetaManager {
|
|||||||
gatewayRouteDefinition.setOrder(0);
|
gatewayRouteDefinition.setOrder(0);
|
||||||
List<GatewayPredicateDefinition> predicates = Arrays.asList(this.buildNameVersionPredicateDefinition(apiMeta));
|
List<GatewayPredicateDefinition> predicates = Arrays.asList(this.buildNameVersionPredicateDefinition(apiMeta));
|
||||||
gatewayRouteDefinition.setPredicates(predicates);
|
gatewayRouteDefinition.setPredicates(predicates);
|
||||||
// lb://story-service#/alipay.story.get/
|
|
||||||
String uri = this.buildUri(serviceApiInfo, apiMeta);
|
String uri = this.buildUri(serviceApiInfo, apiMeta);
|
||||||
|
String path = this.buildServletPath(serviceApiInfo, apiMeta);
|
||||||
gatewayRouteDefinition.setUri(uri);
|
gatewayRouteDefinition.setUri(uri);
|
||||||
|
gatewayRouteDefinition.setPath(path);
|
||||||
gatewayRouteDefinition.setIgnoreValidate(apiMeta.isIgnoreValidate());
|
gatewayRouteDefinition.setIgnoreValidate(apiMeta.isIgnoreValidate());
|
||||||
return gatewayRouteDefinition;
|
return gatewayRouteDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String buildUri(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) {
|
protected String buildUri(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) {
|
||||||
String servletPath = getServletPath(serviceApiInfo, apiMeta);
|
return "lb://" + serviceApiInfo.getServiceId();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String buildServletPath(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) {
|
||||||
|
String servletPath = apiMeta.getPath();
|
||||||
if (servletPath == null) {
|
if (servletPath == null) {
|
||||||
servletPath = PATH_START_CHAR;
|
servletPath = "";
|
||||||
}
|
}
|
||||||
if (!servletPath.startsWith(PATH_START_CHAR)) {
|
if (!servletPath.startsWith(PATH_START_CHAR)) {
|
||||||
servletPath = PATH_START_CHAR + servletPath;
|
servletPath = PATH_START_CHAR + servletPath;
|
||||||
}
|
}
|
||||||
return "lb://" + serviceApiInfo.getServiceId() + "#" + servletPath;
|
return servletPath;
|
||||||
}
|
|
||||||
|
|
||||||
protected String getServletPath(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) {
|
|
||||||
return apiMeta.getPath();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GatewayPredicateDefinition buildNameVersionPredicateDefinition(ServiceApiInfo.ApiMeta apiMeta) {
|
protected GatewayPredicateDefinition buildNameVersionPredicateDefinition(ServiceApiInfo.ApiMeta apiMeta) {
|
||||||
|
@@ -10,17 +10,39 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class GatewayRouteDefinition {
|
public class GatewayRouteDefinition {
|
||||||
/** 路由的Id */
|
/**
|
||||||
|
* 路由的Id
|
||||||
|
*/
|
||||||
private String id;
|
private String id;
|
||||||
/** 路由断言集合配置 */
|
|
||||||
|
/**
|
||||||
|
* 路由断言集合配置
|
||||||
|
*/
|
||||||
private List<GatewayPredicateDefinition> predicates = new ArrayList<>();
|
private List<GatewayPredicateDefinition> predicates = new ArrayList<>();
|
||||||
/** 路由过滤器集合配置 */
|
|
||||||
|
/**
|
||||||
|
* 路由过滤器集合配置
|
||||||
|
*/
|
||||||
private List<GatewayFilterDefinition> filters = new ArrayList<>();
|
private List<GatewayFilterDefinition> filters = new ArrayList<>();
|
||||||
/** 路由规则转发的目标uri */
|
|
||||||
|
/**
|
||||||
|
* 路由规则转发的目标uri
|
||||||
|
*/
|
||||||
private String uri;
|
private String uri;
|
||||||
/** 路由执行的顺序 */
|
|
||||||
|
/**
|
||||||
|
* uri后面跟的path
|
||||||
|
*/
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由执行的顺序
|
||||||
|
*/
|
||||||
private int order = 0;
|
private int order = 0;
|
||||||
/** 是否忽略验证,业务参数验证除外 */
|
|
||||||
|
/**
|
||||||
|
* 是否忽略验证,业务参数验证除外
|
||||||
|
*/
|
||||||
private boolean ignoreValidate;
|
private boolean ignoreValidate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user