diff --git a/app/console/.gitignore b/app/console/.gitignore
index ac7af2e80e3a7920c6989974744a27c21db8cd33..4a8647a62222df15a4bc5237f9e8e0c75cd1007b 100644
--- a/app/console/.gitignore
+++ b/app/console/.gitignore
@@ -1 +1,10 @@
/html/
+/console
+/work/
+/log/
+/logs/
+/cert/
+/config/
+/db/
+/static/
+/sql/
diff --git a/app/console/config/cluster.yaml b/app/console/config/cluster.yaml
deleted file mode 100644
index d6490fbd113844571c6bca8881421d116de73b47..0000000000000000000000000000000000000000
--- a/app/console/config/cluster.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-cluster:
- -
- name: "Default"
- title: "默认机房"
- note: "默认机房"
- db:
- driver: "mysql"
- host: "127.0.0.1"
- port: 3306
- userName: "root"
- password: "123456"
- database: "goku_ee"
- redis:
- mode: "stand"
- addrs: "127.0.0.1:6379" # stand、cluster模式下addrs为redis地址,多个地址间用英文逗号隔开
- password: "123456"
- dbIndex: 0
\ No newline at end of file
diff --git a/app/console/config/goku.conf b/app/console/config/goku.conf
deleted file mode 100644
index 89c03ea5f180b83f9e5ea6b87968521d8591e9e3..0000000000000000000000000000000000000000
--- a/app/console/config/goku.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-listen_port: 7000
-admin_bind: 127.0.0.1:7005
-db_host: 127.0.0.1
-db_port: 3306
-db_name: goku_ee
-db_user: root
-db_password: root
\ No newline at end of file
diff --git a/app/console/main.go b/app/console/main.go
index 1635546392227aec9b2a51d34515053c729998a5..05c82e0557507fa0d2664a6ec3624f591831aae7 100644
--- a/app/console/main.go
+++ b/app/console/main.go
@@ -2,6 +2,7 @@ package main
import (
"flag"
+
"github.com/eolinker/goku-api-gateway/console/module/account"
log "github.com/eolinker/goku-api-gateway/goku-log"
@@ -12,19 +13,15 @@ import (
)
var (
- // UserPassword 用户密码
- UserPassword string
- // UserName 用户名
- UserName string
- // ConfFilePath 配置文件地址
- ConfFilePath = "./config/goku.conf"
-
+ userPassword string
+ userName string
+ confFilePath = "./config/goku.conf"
)
func main() {
- flag.StringVar(&ConfFilePath, "c", "./config/goku.conf", "Please provide a valid configuration file path")
- flag.StringVar(&UserName, "u", "", "Please provide user name")
- flag.StringVar(&UserPassword, "p", "", "Please provide user password")
+ flag.StringVar(&confFilePath, "c", "./config/goku.conf", "Please provide a valid configuration file path")
+ flag.StringVar(&userName, "u", "", "Please provide user name")
+ flag.StringVar(&userPassword, "p", "", "Please provide user password")
isDebug := flag.Bool("debug", false, "")
flag.Parse()
@@ -32,7 +29,7 @@ func main() {
log.StartDebug()
}
// 初始化配置
- if err := conf.ReadConfigure(ConfFilePath); err != nil {
+ if err := conf.ReadConfigure(confFilePath); err != nil {
log.Panic(err)
return
}
@@ -40,32 +37,34 @@ func main() {
console.InitDatabase()
console.InitLog()
- console.InitClusters()
+ //console.InitClusters()
// 其他需要初始化的模块
_ = general.General()
// 检测是否安装
-
- if s, err := account.CheckSuperAdminCount(); err != nil {
- log.Panic(err)
- return
- } else if s == 0 {
- if UserName == "" {
+ s, err := account.CheckSuperAdminCount()
+ if err != nil {
+ err = console.InitTable()
+ if err != nil {
+ log.Panic(err)
+ return
+ }
+ }
+ if s == 0 {
+ if userName == "" {
log.Fatal("[ERROR] Fail to create administrator. Please try again or contact technical support of eoLinker GOKU API Gateway.")
- //fmt.Println("[ERROR] Fail to create administrator. Please try again or contact technical support of eoLinker GOKU API Gateway.")
return
}
- if UserPassword == "" {
+ if userPassword == "" {
log.Fatal("[ERROR] Fail to create administrator. Please try again or contact technical support of eoLinker GOKU API Gateway.")
- //fmt.Println("[ERROR] Fail to create administrator. Please try again or contact technical support of eoLinker GOKU API Gateway.")
+
return
}
// 用户注册
- password := utils.Md5(utils.Md5(UserPassword))
- f := console.Register(UserName, password)
+ password := utils.Md5(utils.Md5(userPassword))
+ f := console.Register(userName, password)
if !f {
log.Fatal("[ERROR] Fail to create administrator. Please try again or contact technical support of eoLinker GOKU API Gateway.")
- //fmt.Println("[ERROR] Fail to create administrator. Please try again or contact technical support of eoLinker GOKU API Gateway.")
return
}
}
diff --git a/app/console/static/scripts/app-9b3cb8f46b.js b/app/console/static/scripts/app-9b3cb8f46b.js
deleted file mode 100644
index 286dc41cff3fb3aced8bc12ddbc6ce30d2ef4003..0000000000000000000000000000000000000000
--- a/app/console/static/scripts/app-9b3cb8f46b.js
+++ /dev/null
@@ -1,22 +0,0 @@
-function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}!function(e){"use strict";function t(e,t){return t=t||Error,function(){var n,a,i=arguments[0],o=arguments[1],r="["+(e?e+":":"")+i+"] ",s=Q(arguments,2).map(function(e){return Ie(e,Ja.objectMaxDepth)});for(r+=o.replace(/\{\d+\}/g,function(e){var t=+e.slice(1,-1);return t0}function i(e){if(null==e||S(e))return!1;if(fi(e)||w(e)||ni&&e instanceof ni)return!0;var t="length"in Object(e)&&e.length;return I(t)&&(t>=0&&(t-1 in e||e instanceof Array)||"function"==typeof e.item)}function o(e,t,n){var a,r;if(e)if(C(e))for(a in e)"prototype"!==a&&"length"!==a&&"name"!==a&&e.hasOwnProperty(a)&&t.call(n,e[a],a,e);else if(fi(e)||i(e)){var s="object"!=typeof e;for(a=0,r=e.length;a=0&&e.splice(n,1),n}function U(e,t,n){function i(e,t,n){if(n--,n<0)return"...";var a,i=t.$$hashKey;if(fi(e))for(var o=0,s=e.length;o2?Q(arguments,2):[];return!C(t)||t instanceof RegExp?t:n.length?function(){return arguments.length?t.apply(e,H(n,arguments,0)):t.apply(e,n)}:function(){return arguments.length?t.apply(e,arguments):t.call(e)}}function z(t,n){var a=n;return"string"==typeof t&&"$"===t.charAt(0)&&"$"===t.charAt(1)?a=void 0:S(n)?a="$WINDOW":n&&e.document===n?a="$DOCUMENT":_(n)&&(a="$SCOPE"),a}function W(e,t){if(!$(e))return I(t)||(t=t?2:null),JSON.stringify(e,z,t)}function J(e){return w(e)?JSON.parse(e):e}function Y(e,t){e=e.replace(yi,"");var n=Date.parse("Jan 01, 1970 00:00:00 "+e)/6e4;return mi(n)?t:n}function X(e,t){return e=new Date(e.getTime()),e.setMinutes(e.getMinutes()+t),e}function Z(e,t,n){n=n?-1:1;var a=e.getTimezoneOffset(),i=Y(t,a);return X(e,n*(i-a))}function ee(e){e=ni(e).clone();try{e.empty()}catch(t){}var n=ni("").append(e).html();try{return e[0].nodeType===ki?Ya(n):n.match(/^(<[^>]+>)/)[1].replace(/^<([\w-]+)/,function(e,t){return"<"+Ya(t)})}catch(t){return Ya(n)}}function te(e){try{return decodeURIComponent(e)}catch(t){}}function ne(e){var t={};return o((e||"").split("&"),function(e){var n,a,i;e&&(a=e=e.replace(/\+/g,"%20"),n=e.indexOf("="),n!==-1&&(a=e.substring(0,n),i=e.substring(n+1)),a=te(a),y(a)&&(i=!y(i)||te(i),Wa.call(t,a)?fi(t[a])?t[a].push(i):t[a]=[t[a],i]:t[a]=i))}),t}function ae(e){var t=[];return o(e,function(e,n){fi(e)?o(e,function(e){t.push(oe(n,!0)+(e===!0?"":"="+oe(e,!0)))}):t.push(oe(n,!0)+(e===!0?"":"="+oe(e,!0)))}),t.length?t.join("&"):""}function ie(e){return oe(e,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function oe(e,t){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%20/g,t?"%20":"+")}function re(e,t){var n,a,i=xi.length;for(a=0;a
/,">"))}n=n||[],n.unshift(["$provide",function(e){e.value("$rootElement",t)}]),a.debugInfoEnabled&&n.push(["$compileProvider",function(e){e.debugInfoEnabled(!0)}]),n.unshift("ng");var o=pt(n,a.strictDi);return o.invoke(["$rootScope","$rootElement","$compile","$injector",function(e,t,n,a){e.$apply(function(){t.data("$injector",a),n(t)(e)})}]),o},s=/^NG_ENABLE_DEBUG_INFO!/,c=/^NG_DEFER_BOOTSTRAP!/;return e&&s.test(e.name)&&(a.debugInfoEnabled=!0,e.name=e.name.replace(s,"")),e&&!c.test(e.name)?r():(e.name=e.name.replace(c,""),pi.resumeBootstrap=function(e){return o(e,function(e){n.push(e)}),r()},void(C(pi.resumeDeferredBootstrap)&&pi.resumeDeferredBootstrap()))}function ue(){e.name="NG_ENABLE_DEBUG_INFO!"+e.name,e.location.reload()}function pe(e){var t=pi.element(e).injector();if(!t)throw ui("test","no injector found for element argument to getTestability");return t.get("$$testability")}function de(e,t){return t=t||"_",e.replace(wi,function(e,n){return(n?t:"")+e.toLowerCase()})}function me(){var t;if(!Ii){var n=$i();ai=$(n)?e.jQuery:n?e[n]:void 0,ai&&ai.fn.on?(ni=ai,p(ai.fn,{scope:Bi.scope,isolateScope:Bi.isolateScope,controller:Bi.controller,injector:Bi.injector,inheritedData:Bi.inheritedData}),t=ai.cleanData,ai.cleanData=function(e){for(var n,a,i=0;null!=(a=e[i]);i++)n=ai._data(a,"events"),n&&n.$destroy&&ai(a).triggerHandler("$destroy");t(e)}):ni=Pe,pi.element=ni,Ii=!0}}function fe(e,t,n){if(!e)throw ui("areq","Argument '{0}' is {1}",t||"?",n||"required");return e}function he(e,t,n){return n&&fi(e)&&(e=e[e.length-1]),fe(C(e),t,"not a function, got "+(e&&"object"==typeof e?e.constructor.name||"Object":typeof e)),e}function ge(e,t){if("hasOwnProperty"===e)throw ui("badname","hasOwnProperty is not a valid {0} name",t)}function ve(e,t,n){if(!t)return e;for(var a,i=t.split("."),o=e,r=i.length,s=0;s
=0)return"...";n.push(t)}return t})}function Ie(e,t){return"function"==typeof e?e.toString().replace(/ \{[\s\S]*$/,""):$(e)?"undefined":"string"!=typeof e?we(e,t):e}function Oe(a){p(a,{errorHandlingConfig:n,bootstrap:le,copy:U,extend:p,merge:d,equals:B,element:ni,forEach:o,injector:pt,noop:h,bind:K,toJson:W,fromJson:J,identity:g,isUndefined:$,isDefined:y,isString:w,isFunction:C,isObject:x,isNumber:I,isElement:T,isArray:fi,version:Ei,isDate:O,lowercase:Ya,uppercase:Xa,callbacks:{$$counter:0},getTestability:pe,reloadWithDebugInfo:ue,$$minErr:t,$$csp:bi,$$encodeUriSegment:ie,$$encodeUriQuery:oe,$$stringify:ye}),ii=xe(e),ii("ng",["ngLocale"],["$provide",function(e){e.provider({$$sanitizeUri:Dn}),e.provider("$compile",jt).directive({a:Zo,input:$r,textarea:$r,form:or,script:ms,select:gs,option:vs,ngBind:jr,ngBindHtml:Ir,ngBindTemplate:wr,ngClass:Cr,ngClassEven:Sr,ngClassOdd:kr,ngCloak:_r,ngController:Dr,ngForm:rr,ngHide:rs,ngIf:Rr,ngInclude:Mr,ngInit:Pr,ngNonBindable:Yr,ngPluralize:ts,ngRepeat:ns,ngShow:os,ngStyle:ss,ngSwitch:cs,ngSwitchWhen:ls,ngSwitchDefault:us,ngOptions:es,ngTransclude:ds,ngModel:zr,ngList:Tr,ngChange:Or,pattern:$s,ngPattern:$s,required:bs,ngRequired:bs,minlength:xs,ngMinlength:xs,maxlength:ys,ngMaxlength:ys,ngValue:xr,ngModelOptions:Jr}).directive({ngInclude:qr}).directive(er).directive(Er),e.provider({$anchorScroll:dt,$animate:co,$animateCss:po,$$animateJs:ro,$$animateQueue:so,$$AnimateRunner:uo,$$animateAsyncRun:lo,$browser:bt,$cacheFactory:$t,$controller:St,$document:_t,$$isDocumentHidden:Dt,$exceptionHandler:Et,$filter:Hn,$$forceReflow:$o,$interpolate:Ht,$interval:Qt,$http:Gt,$httpParamSerializer:Rt,$httpParamSerializerJQLike:Mt,$httpBackend:Vt,$xhrFactory:Ut,$jsonpCallbacks:ko,$location:cn,$log:ln,$parse:In,$rootScope:_n,$q:On,$$q:Cn,$sce:qn,$sceDelegate:Mn,$sniffer:Pn,$templateCache:yt,$templateRequest:Tn,$$testability:Ln,$timeout:Nn,$window:Un,$$rAF:Sn,$$jqLite:it,$$Map:Ji,$$cookieReader:Bn})}]).info({angularVersion:"1.6.4"})}function Ce(){return++Ri}function ke(e){return _e(e.replace(qi,"ms-"))}function Se(e,t){return t.toUpperCase()}function _e(e){return e.replace(Mi,Se)}function De(e){return!Ni.test(e)}function Ee(e){var t=e.nodeType;return t===Oi||!t||t===_i}function Ae(e){for(var t in Ai[e.ng339])return!0;return!1}function Re(e,t){var n,a,i,r,s=t.createDocumentFragment(),c=[];if(De(e))c.push(t.createTextNode(e));else{for(n=s.appendChild(t.createElement("div")),a=(Fi.exec(e)||["",""])[1].toLowerCase(),i=Ui[a]||Ui._default,n.innerHTML=i[1]+e.replace(Gi,"<$1>$2>")+i[2],r=i[0];r--;)n=n.lastChild;c=H(c,n.childNodes),n=s.firstChild,n.textContent=""}return s.textContent="",s.innerHTML="",o(c,function(e){s.appendChild(e)}),s}function Me(t,n){n=n||e.document;var a;return(a=Li.exec(t))?[n.createElement(a[1])]:(a=Re(t,n))?a.childNodes:[]}function qe(e,t){var n=e.parentNode;n&&n.replaceChild(t,e),t.appendChild(e)}function Pe(e){if(e instanceof Pe)return e;var t;if(w(e)&&(e=gi(e),t=!0),!(this instanceof Pe)){if(t&&"<"!==e.charAt(0))throw Ti("nosel","Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element");return new Pe(e)}t?Qe(this,Me(e)):C(e)?Xe(e):Qe(this,e)}function Te(e){return e.cloneNode(!0)}function Le(e,t){!t&&Ee(e)&&ni.cleanData([e]),e.querySelectorAll&&ni.cleanData(e.querySelectorAll("*"))}function Ne(e,t,n,a){if(y(a))throw Ti("offargs","jqLite#off() does not support the `selector` argument");var i=Ge(e),r=i&&i.events,s=i&&i.handle;if(s)if(t){var c=function(t){var a=r[t];y(n)&&G(a||[],n),y(n)&&a&&a.length>0||(e.removeEventListener(t,s),delete r[t])};o(t.split(" "),function(e){c(e),Pi[e]&&c(Pi[e])})}else for(t in r)"$destroy"!==t&&e.removeEventListener(t,s),delete r[t]}function Fe(e,t){var n=e.ng339,a=n&&Ai[n];if(a){if(t)return void delete a.data[t];a.handle&&(a.events.$destroy&&a.handle({},"$destroy"),Ne(e)),delete Ai[n],e.ng339=void 0}}function Ge(e,t){var n=e.ng339,a=n&&Ai[n];return t&&!a&&(e.ng339=n=Ce(),a=Ai[n]={events:{},data:{},handle:void 0}),a}function Ue(e,t,n){if(Ee(e)){var a,i=y(n),o=!i&&t&&!x(t),r=!t,s=Ge(e,!o),c=s&&s.data;if(i)c[_e(t)]=n;else{if(r)return c;if(o)return c&&c[_e(t)];for(a in t)c[_e(a)]=t[a]}}}function Ve(e,t){return!!e.getAttribute&&(" "+(e.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").indexOf(" "+t+" ")>-1}function Be(e,t){t&&e.setAttribute&&o(t.split(" "),function(t){e.setAttribute("class",gi((" "+(e.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").replace(" "+gi(t)+" "," ")))})}function He(e,t){if(t&&e.setAttribute){var n=(" "+(e.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ");o(t.split(" "),function(e){e=gi(e),n.indexOf(" "+e+" ")===-1&&(n+=e+" ")}),e.setAttribute("class",gi(n))}}function Qe(e,t){if(t)if(t.nodeType)e[e.length++]=t;else{var n=t.length;if("number"==typeof n&&t.window!==t){if(n)for(var a=0;a1&&(i=je(i));for(var c=0;cl&&this.remove(m.key),t}},get:function(e){if(l";var a=Ce.firstChild.attributes,i=a[0];a.removeNamedItem(i.name),i.value=n,e.attributes.setNamedItem(i)}function F(e,t){try{e.addClass(t)}catch(n){}}function U(e,t,n,a,i){e instanceof ni||(e=ni(e));var o=z(e,t,e,n,a,i);U.$$addScopeClass(e);var r=null;return function(t,n,a){if(!e)throw mo("multilink","This element has already been linked.");fe(t,"scope"),i&&i.needsNewScope&&(t=t.$parent.$new()),a=a||{};
-var s=a.parentBoundTranscludeFn,c=a.transcludeControllers,l=a.futureParentElement;s&&s.$$boundTransclude&&(s=s.$$boundTransclude),r||(r=H(l));var u;if(u="html"!==r?ni(ge(r,ni("'},,{key:"更新时间",html:"{{item.updateTime}}"}],operate:{funArr:[{key:"停用",fun:s.operate,itemExpression:'ng-if="item.pluginStatus===1"',params:{status:"Stop"}},{key:"启用",fun:s.operate,itemExpression:'ng-if="item.pluginStatus!==1" ng-disabled="item.pluginStatus===-1"',params:{status:"Start"}},{key:"修改",fun:s.edit,params:{status:"edit"}},{key:"删除",fun:s["delete"],params:'"single",arg'}],"class":"w_200"}},setting:{unhover:!0,batch:!0,defaultFoot:!0}},r.component.menuObject={list:[{type:"btn",authority:"edit","class":"pull-left",btnList:[{name:"添加插件",icon:"jiahao","class":"eo_theme_btn_success block-btn",fun:{"default":s.edit,params:{status:"add"}}}]},{type:"search","class":"pull-right",keyword:r.ajaxRequest.keyword,fun:s.search,placeholder:"输入插件名称或描述"},{type:"fun-list","class":"fun-list-li pull-right mr15",name:"筛选",icon:"shaixuan",activePoint:"condition",funList:[{name:"无",value:0,active:0,fun:{"default":s.conditionFilter}},{name:"启用",value:2,active:2,fun:{"default":s.conditionFilter}},{name:"停用",value:1,active:1,fun:{"default":s.conditionFilter}}]}],batchList:[{type:"btn","class":"pull-left",btnList:[{name:"删除",fun:{"default":s["delete"],params:'"batch"'}},{name:"启用",fun:{"default":s.batchOperate,params:{status:"Start"}}},{name:"停用",fun:{"default":s.batchOperate,params:{status:"Stop"}}}]}],setting:{batch:!0,batchInitFun:s.resetBatchInfo,titleAuthority:"showTitle",title:"策略插件"},active:{condition:0}}}}angular.module("eolinker").component("gpeditInsidePluginGpedit",{templateUrl:"app/ui/content/gpedit/inside/content/plugin/gpedit/index.html",controller:e}),e.$inject=["$scope","GatewayResource","$state","$rootScope","CODE","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i,o,r){var s=this;s.data={batch:{},pagination:{maxSize:10,pageSize:50,page:0,msgCount:0}},s.fun={},s.ajaxRequest={strategyID:a.params.strategyID,keyword:window.sessionStorage.getItem("COMMON_SEARCH_TIP")},s.ajaxResponse={query:null,balanceList:null},s.component={listDefaultCommonObject:null,menuObject:{}},s.service={authority:r};var c={},l={};c.batchBtnClickFun=function(){if(s.data.pagination.page!==Math.ceil(s.data.pagination.msgCount/s.data.pagination.pageSize)){var e={strategyID:s.ajaxRequest.strategyID,condition:s.component.menuObject.active.condition},t=null;s.ajaxRequest.keyword&&(e.keyword=s.ajaxRequest.keyword),t=n.StrategyApi.IDQuery(e).$promise,t.then(function(e){s.data.allQueryID=e.apiIDList||[]})}},c.scrollLoading=function(){var e={hasItem:s.ajaxResponse.query&&0!==s.ajaxResponse.query.length,hasNextPage:s.data.pagination.pages.data.pagination.page*s.data.pagination.pageSize&&c.getQuery("preload",s.data.pagination.page*s.data.pagination.pageSize,1),s.data.pagination.msgCount--,i.InfoModal(r.title+"成功","success")}}})})},c.getDefaultBalance=function(){var e=n.Balance.SimpleQuery().$promise;return e.then(function(e){s.ajaxResponse.balanceList=e.balanceNames}),e},c.setGpeditBalance=function(e){var t=function(){var t={itemArr:[]};switch(e.status){case"batch":t.apiIDs=s.data.batch.query;break;case"single":t.itemArr=[{type:"input",title:"[原]API负载后端",value:e.item.target,disabled:!0}],t.apiIDs=[e.item.apiID]}var a={title:"设置策略负载",resource:n.StrategyApi.ChangeTarget,textArray:t.itemArr.concat([{type:"html",title:"[新]策略负载后端",key:"target",value:e.item.rewriteTarget,query:s.ajaxResponse.balanceList,autoCompleteObj:{pattern:"[\\w\\._\\/\\-\\:]+"},html:' '}]),request:{strategyID:s.ajaxRequest.strategyID,apiIDs:JSON.stringify(t.apiIDs)}};i.MixInputModal(a,function(t){t&&("batch"===e.status?(c.resetBatchInfo(),c.getQuery("reset")):s.ajaxResponse.query[e.$index].rewriteTarget=t.target,i.InfoModal("设置策略负载成功","success"))})};if(s.ajaxResponse.balanceList)t();else{var a=c.getDefaultBalance();a["finally"](function(){t()})}},c.resetBatchInfo=function(){s.data.batch.isOperating=!1,s.data.batch.selectAll=!1,s.data.batch.query=[],s.data.batch.indexAddress={}},c.setGpeditPlugin=function(e){a.go("home.gpedit.inside.api.plugin",{apiID:e.item.apiID})},s.$onInit=function(){e.$emit("$WindowTitleSet",{list:["API接口","策略"]}),s.component.listDefaultCommonObject={item:{primaryKey:"apiID","default":[{key:"APIs",html:"{{item.apiName}}",draggableCacheMark:"name"},{key:"请求方式",html:"{{item.requestMethod}}",draggableCacheMark:"requestMethod"},{key:"请求URL",html:"{{item.requestURL}}",draggableCacheMark:"url"},{key:"转发方式",html:"{{item.isFollow?item.requestMethod:item.targetMethod}}",draggableCacheMark:"targetMethod"},_defineProperty({key:"转发URL",html:"{{item.targetURL}}",draggableCacheMark:"targetURL"},"draggableCacheMark","targetURL"),{key:'API负载后端 ',html:"{{item.target}}",draggableCacheMark:"target"},{key:'策略负载后端 ',html:"{{item.rewriteTarget}}",draggableCacheMark:"rewriteTarget"},{key:"更新时间",html:"{{item.updateTime}}",draggableCacheMark:"updateTime"}],operate:{funArr:[{key:"设置插件",show:!1,fun:c.setGpeditPlugin},{key:"设置策略负载",show:!1,fun:c.setGpeditBalance,params:{status:"single"}},{key:"删除",show:!1,fun:c["delete"],params:'"single",arg'}],"class":"w_200"}},setting:{draggable:!0,dragCacheVar:"GEPDIT_API_LIST_DRAG_VAR",dragCacheObj:{name:"250px",url:"250px",target:"150px",targetURL:"150px",updateTime:"150px",requestMethod:"150px",targetMethod:"150px",rewriteTarget:"150px"},page:!0,scroll:!0,scrollRemainRatio:7,isFixedHeight:!0,unhover:!0,batch:!0},baseFun:{scrollLoading:c.scrollLoading}},s.component.menuObject={list:[{type:"btn",authority:"edit","class":"pull-left",btnList:[{name:"绑定接口",icon:"jiahao","class":"eo_theme_btn_success block-btn",fun:{"default":c.edit,params:{status:"add"}}}]},{type:"search","class":"pull-right",keyword:s.ajaxRequest.keyword,fun:c.search,placeholder:"输入搜索内容"}],batchList:[{type:"btn","class":"pull-left",btnList:[{name:"删除",fun:{"default":c["delete"],params:'"batch"'}},{name:"设置策略负载",fun:{"default":c.setGpeditBalance,params:{status:"batch"}}}]}],setting:{batch:!0,batchInitFun:c.resetBatchInfo,titleAuthority:"showTitle",title:"API列表"},active:{condition:0},baseFun:{batchDefault:c.batchBtnClickFun}}}}angular.module("eolinker").component("gpeditInsideApiDefault",{templateUrl:"app/ui/content/gpedit/inside/content/api/_default/index.html",controller:e}),e.$inject=["$scope","CommonResource","GatewayResource","$state","$rootScope","CODE","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i){var o=this;o.data={batch:{isOperating:!0,query:[],indexAddress:{}},pagination:{maxSize:10,pageSize:50,page:0,msgCount:0}},o.fun={},o.ajaxResponse={},o.component={groupCommonObject:{firstGroup:{},secondGroup:{}}};var r={strategyID:t.params.strategyID,keyword:window.sessionStorage.getItem("COMMON_SEARCH_TIP")
-},s={projectObject:{},positionObject:{strategyID:t.params.strategyID,projectID:null,groupID:-1}},c={},l={groupCommon:i},u={project:null,apiGroup:null};c.scrollLoading=function(){var e={hasItem:o.ajaxResponse.query&&0!==o.ajaxResponse.query.length,hasNextPage:o.data.pagination.page0){var t=l.groupCommon.sort.init(o.ajaxResponse.firstGroupList[0]);o.ajaxResponse.seondGroupList=t.groupList,u.secondGroup=t.groupInfo,o.component.groupCommonObject.firstGroup.mainObject.baseInfo.resetFlag=!o.component.groupCommonObject.firstGroup.mainObject.baseInfo.resetFlag,o.component.groupCommonObject.secondGroup.mainObject.baseInfo.resetFlag=!o.component.groupCommonObject.secondGroup.mainObject.baseInfo.resetFlag,s.positionObject.projectID=o.ajaxResponse.firstGroupList[0].projectID,c.getApiList("reset")}else n.InfoModal("目前暂无可以被引用的API项目","error"),o.fun.back()}),n.global.ajax.ProjectQuery_Common.$promise},c.search=function(e){r.keyword=e.item.keyword,window.sessionStorage.setItem("COMMON_SEARCH_TIP",e.item.keyword),c.getApiList("reset")},c.selectAll=function(e){switch(e){case"selectAll":o.data.allQueryID.map(function(e,t){o.data.batch.indexAddress[e]||(o.data.batch.query.push(e),o.data.batch.indexAddress[e]=t+1)}),o.data.batch.selectAll=!0;break;case"selectView":o.ajaxResponse.query.map(function(e,t){o.data.batch.indexAddress[e.apiID]||(o.data.batch.query.push(e.apiID),o.data.batch.indexAddress[e.apiID]=t+1)});for(var t=o.ajaxResponse.query.length,n=t;n扩展插件处尚未开启该插件 停用 启用 '},{key:"更新时间",html:"{{item.updateTime}}"}],operate:{funArr:[{key:"停用",fun:s.operate,itemExpression:'ng-if="item.pluginStatus===1"',params:{status:"Stop"}},{key:"启用",fun:s.operate,itemExpression:'ng-if="item.pluginStatus!==1" ng-disabled="item.pluginStatus===-1"',params:{status:"Start"}},{key:"修改",fun:s.edit,params:{status:"edit"}},{key:"删除",fun:s["delete"],params:'"single",arg'}],"class":"w_200"}},setting:{unhover:!0,batch:!0,defaultFoot:!0}},r.component.menuDefaultObject={list:[{type:"btn","class":"btn-group-li",btnList:[{name:"返回API列表",icon:"chexiao",fun:{"default":function(){n.go("home.gpedit.inside.api.default")}}}]},{type:"customized-html",html:' {{$ctrl.otherObject.requestURL}}
{{$ctrl.otherObject.apiName}}
'}],setting:{"class":"common-menu-fixed-seperate common-menu-lg"}},r.component.menuObject={list:[{type:"btn",authority:"edit","class":"pull-left",btnList:[{name:"添加插件",icon:"jiahao","class":"eo_theme_btn_success block-btn",fun:{"default":s.edit,params:{status:"add"}}}]},{type:"search","class":"pull-right",keyword:r.ajaxRequest.keyword,fun:s.search,placeholder:"输入插件名称或描述"},{type:"fun-list","class":"fun-list-li pull-right mr15",name:"筛选",icon:"shaixuan",activePoint:"condition",funList:[{name:"无",value:0,active:0,fun:{"default":s.conditionFilter}},{name:"启用",value:2,active:2,fun:{"default":s.conditionFilter}},{name:"停用",value:1,active:1,fun:{"default":s.conditionFilter}}]}],batchList:[{type:"btn","class":"pull-left",btnList:[{name:"删除",fun:{"default":s["delete"],params:'"batch"'}},{name:"启用",fun:{"default":s.batchOperate,params:{status:"Start"}}},{name:"停用",fun:{"default":s.batchOperate,params:{status:"Stop"}}}]}],setting:{batch:!0,batchInitFun:s.resetBatchInfo,titleAuthority:"showTitle",title:"策略插件"},active:{condition:0}}}}angular.module("eolinker").component("gpeditInsideApiPlugin",{templateUrl:"app/ui/content/gpedit/inside/content/apiPlugin/index.html",controller:e}),e.$inject=["GatewayResource","$scope","$state","$rootScope","CODE","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i,o,r,s){var c=this;c.data={batch:{},pagination:{maxSize:10,pageSize:50,page:0,msgCount:0}},c.fun={},c.ajaxRequest={projectID:a.params.projectID,groupID:a.params.groupID||-1,keyword:window.sessionStorage.getItem("COMMON_SEARCH_TIP")},c.ajaxResponse={query:null},c.service={authority:s},c.component={listRequireObject:{},menuObject:{}};var l={},u={};c.fun.init=function(){return l.getQuery("reset")},l.batchBtnClickFun=function(){if(c.data.pagination.page!==Math.ceil(c.data.pagination.msgCount/c.data.pagination.pageSize)){var e={projectID:c.ajaxRequest.projectID,groupID:c.ajaxRequest.groupID,condition:c.component.menuObject.active.condition},t=null;c.ajaxRequest.keyword&&(e.keyword=c.ajaxRequest.keyword),t=n.Api.IDQuery(e).$promise,t.then(function(e){c.data.allQueryID=e.apiIDList||[]})}},l.getQuery=function(e,t,a){var o={projectID:c.ajaxRequest.projectID,groupID:c.ajaxRequest.groupID,condition:c.component.menuObject.active.condition,pageSize:a||c.data.pagination.pageSize},r=[];switch(e){case"reset":o.page=1;break;default:r=c.ajaxResponse.query,o.page=t}return c.ajaxRequest.keyword&&(o.keyword=c.ajaxRequest.keyword),i.global.ajax.Query_Api=n.Api.Query(o),i.global.ajax.Query_Api.$promise.then(function(t){"reset"===e&&(document.getElementsByClassName("tbody_container_ldcc")[0].scrollTop=0),u.isQuerying=!1,c.ajaxResponse.query=r.concat(t.apiList||[]),c.data.pagination.msgCount=t.page.totalNum||0,a||(c.data.pagination.page=o.page)}),i.global.ajax.Query_Api.$promise},l.scrollLoading=function(){var e={hasItem:c.ajaxResponse.query&&0!==c.ajaxResponse.query.length,hasNextPage:c.data.pagination.pagec.data.pagination.page*c.data.pagination.pageSize&&l.getQuery("preload",c.data.pagination.page*c.data.pagination.pageSize,1),c.data.pagination.msgCount--}i.InfoModal("API删除成功","success")}})})},l.batchMoveGroup=function(){var e={modal:{list:[{groupID:0,groupName:"未分组"}].concat(angular.copy(r.get())),title:"批量编辑接口分组",current:c.ajaxRequest},request:{projectID:c.ajaxRequest.projectID,apiIDList:c.data.batch.query.join(","),groupID:""}};i.SelectVisualGroupModal(e.modal,function(t){t&&(e.request.groupID=t.groupID,n.Api.ChangeGroup(e.request).$promise.then(function(e){switch(e.statusCode){case o.COMMON.SUCCESS:l.resetBatchInfo(),l.getQuery("reset"),i.InfoModal("Api批量编辑分组成功","success")}}))})},l.copy=function(e){var t=function(t){var n=angular.copy(e.item),a={apiName:"复制-"+n.apiName,requestURL:n.requestURL,balanceName:n.target,targetURL:n.targetURL,targetMethod:n.isFollow?"-1":n.targetMethod.toLowerCase(),protocol:n.protocol||"http",apiID:n.apiID,groupID:n.groupID||"0",projectID:c.ajaxRequest.projectID,balanceList:t,requestMethodList:[{key:"POST",value:"post"},{key:"GET",value:"get"},{key:"PUT",value:"put"},{key:"DELETE",value:"delete"},{key:"HEAD",value:"head"},{key:"OPTIONS",value:"options"},{key:"PATCH",value:"patch"}]},o=n.requestMethod.split(",");for(var r in o){var s=o[r];switch(s.toLowerCase()){case"post":a.requestMethodList[0].checkbox=!0;break;case"get":a.requestMethodList[1].checkbox=!0;break;case"put":a.requestMethodList[2].checkbox=!0;break;case"delete":a.requestMethodList[3].checkbox=!0;break;case"head":a.requestMethodList[4].checkbox=!0;break;case"options":a.requestMethodList[5].checkbox=!0;break;case"batch":a.requestMethodList[6].checkbox=!0}}i.Gateway_CopyApiModal(a,function(e){e&&(i.InfoModal("Api复制成功","success"),l.getQuery("reset"))})};if(c.ajaxResponse.balanceList)t(c.ajaxResponse.balanceList);else{var n=l.getDefaultBalance();n["finally"](function(){t(c.ajaxResponse.balanceList)})}},l.resetBatchInfo=function(){c.data.batch.isOperating=!1,c.data.batch.selectAll=!1,c.data.batch.query=[],c.data.batch.indexAddress={}},c.$onInit=function(){e.$emit("$WindowTitleSet",{list:["APIs列表"]}),c.component.listDefaultCommonObject={item:{primaryKey:"apiID","default":[{key:"APIs",html:"{{item.apiName}}",draggableCacheMark:"name"},{key:"请求方式",html:"{{item.requestMethod}}",draggableCacheMark:"requestMethod"},{key:"请求URL",html:"{{item.requestURL}}",draggableCacheMark:"url"},{key:"负载后端",html:"{{item.target}}",draggableCacheMark:"target"},{key:"转发方式",html:"{{item.isFollow?item.requestMethod:item.targetMethod}}",draggableCacheMark:"targetMethod"},{key:"转发URL",html:"{{item.targetURL}}",draggableCacheMark:"targetURL"},{key:"分组",html:"{{item.groupName}}",draggableCacheMark:"group"},{key:"更新时间",html:"{{item.updateTime}}",draggableCacheMark:"updateTime"}],operate:{funArr:[{key:"复制",fun:l.copy},{key:"修改",fun:l.edit,params:{status:"edit"}},{key:"删除",fun:l["delete"],params:'"single",arg'}],"class":"w_150"}},setting:{page:!0,scroll:!0,scrollRemainRatio:7,isFixedHeight:!0,draggable:!0,dragCacheVar:"AMS_API_LIST_DRAG_VAR",dragCacheObj:{name:"250px",url:"250px",target:"150px",targetURL:"150px",group:"150px",manager:"150px",updater:"150px",updateTime:"150px",requestMethod:"150px",targetMethod:"150px"},batch:!0,batchInitFun:l.resetBatchInfo,titleAuthority:"showTitle",unhover:!0,warning:"尚未新建任何接口"},baseFun:{scrollLoading:l.scrollLoading}},c.component.menuObject={list:[{type:"more-btn",authority:"edit",icon:"jiahao",name:"新建","class":"pull-left",btnClass:"eo_theme_btn_success",btnList:[{name:"新建接口",fun:{"default":l.edit,params:{status:"add"}}},{name:"导入接口",fun:{"default":l["import"]}}]},{type:"search","class":"pull-right",keyword:c.ajaxRequest.keyword,fun:l.search,placeholder:"输入搜索内容"}],batchList:[{type:"btn","class":"btn-group-li pull-left",btnList:[{name:"修改分组",fun:{"default":l.batchMoveGroup}},{name:"批量删除",fun:{"default":l["delete"],params:'"batch",arg'}}]}],setting:{batch:!0,batchInitFun:l.resetBatchInfo,titleAuthority:"showTitle",title:"接口列表"},active:{condition:0},baseFun:{batchDefault:l.batchBtnClickFun}}}}angular.module("eolinker").component("apiDefault",{templateUrl:"app/ui/content/project/api/_default/index.html",controller:e}),e.$inject=["$scope","CommonResource","GatewayResource","$state","$rootScope","CODE","GroupService","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i,o){var r=this;r.data={requestMethod:!1,apiGroup:null,requestMethodList:[{key:"POST",value:"post"},{key:"GET",value:"get"},{key:"PUT",value:"put"},{key:"DELETE",value:"delete"},{key:"HEAD",value:"head"},{key:"OPTIONS",value:"options"},{key:"PATCH",value:"patch"}]},r.fun={},r.ajaxRequest={projectID:n.params.projectID,groupID:n.params.groupID||-1,apiID:n.params.apiID},r.ajaxResponse={apiInfo:{apiName:"",requestMethod:"",requestURL:"/",balanceName:"",targetURL:"/",targetMethod:"-1",isFollow:!0,stripPrefix:!0,stripSlash:!0,timeout:"2000",retryCount:"",alertValve:0,protocol:"http"},balanceList:[]},r.component={selectMultistageCommonComponentObject:{"new":{},original:{}},menuObject:{list:[]},balanceAutoCompleteObj:{required:!0,pattern:"[\\w\\._\\/\\-\\:]+"}},r.CONST={PROTOCOL_ARR:[{key:"HTTP",value:"http"},{key:"HTTPS",value:"https"}]};var s={};r.fun.back=function(){n.go("home.project.api.default",{groupID:n.params.groupID})},s.confirm=function(){r.data.requestMethod=!1;var e={projectID:r.ajaxRequest.projectID,groupID:r.component.selectMultistageCommonComponentObject["new"].value==-1?0:r.component.selectMultistageCommonComponentObject["new"].value,apiName:r.ajaxResponse.apiInfo.apiName,requestMethod:[],requestURL:r.ajaxResponse.apiInfo.requestURL,balanceName:r.ajaxResponse.apiInfo.balanceName,targetURL:r.ajaxResponse.apiInfo.targetURL,targetMethod:r.ajaxResponse.apiInfo.targetMethod,stripPrefix:r.ajaxResponse.apiInfo.stripPrefix,timeout:r.ajaxResponse.apiInfo.timeout,retryCount:r.ajaxResponse.apiInfo.retryCount,alertValve:r.ajaxResponse.apiInfo.alertValve,protocol:r.ajaxResponse.apiInfo.protocol,stripSlash:r.ajaxResponse.apiInfo.stripSlash};for(var t in r.data.requestMethodList)r.data.requestMethodList[t].checkbox&&e.requestMethod.push(r.data.requestMethodList[t].value);switch(e.requestMethod.length>0?e.requestMethod=e.requestMethod.join(","):r.data.requestMethod=!0,n.params.status){case"edit":e.apiID=r.ajaxRequest.apiID}return"-1"==r.ajaxResponse.apiInfo.targetMethod&&(e.isFollow=!0,delete e.targetMethod),e},r.fun.load=function(t){e.$emit("$TransferStation",{state:"$Init_LoadingCommonComponent",data:t})},r.fun.requestProcessing=function(t){var n=s.confirm(),a=null;return r.data.submitted=!0,e.ConfirmForm.$valid&&!r.data.requestMethod?a=s.edit({request:n}):i.InfoModal("API编辑失败,请检查信息是否填写完整!","error"),a},s.edit=function(o){var s=null;return"edit"==n.params.status?(s=t.Api.Edit(o.request).$promise,s.then(function(t){switch(t.statusCode){case a.COMMON.SUCCESS:r.fun.back(),i.InfoModal("API修改成功","success");break;case"190005":r.data.requestMethod=!0,e.ConfirmForm.requestURL.$invalid=!0}})):(s=t.Api.Add(o.request).$promise,s.then(function(t){switch(t.statusCode){case a.COMMON.SUCCESS:r.fun.back(),i.InfoModal("API添加成功","success");break;case"190005":r.data.requestMethod=!0,e.ConfirmForm.requestURL.$invalid=!0}})),s},s.initApi=function(){var e={projectID:r.ajaxRequest.projectID,apiID:r.ajaxRequest.apiID};switch(n.params.status){case"edit":t.Api.Info(e).$promise.then(function(e){switch(e.statusCode){case a.COMMON.SUCCESS:r.ajaxResponse.apiInfo=e.apiInfo;var t=e.apiInfo.requestMethod.split(",");r.ajaxResponse.apiInfo.targetMethod=e.apiInfo.isFollow?"-1":r.ajaxResponse.apiInfo.targetMethod;for(var n in t){var i=t[n];switch(i.toLowerCase()){case"post":r.data.requestMethodList[0].checkbox=!0;break;case"get":r.data.requestMethodList[1].checkbox=!0;break;case"put":r.data.requestMethodList[2].checkbox=!0;break;case"delete":r.data.requestMethodList[3].checkbox=!0;break;case"head":r.data.requestMethodList[4].checkbox=!0;break;case"options":r.data.requestMethodList[5].checkbox=!0;break;case"batch":r.data.requestMethodList[6].checkbox=!0}}}})}},s.getDefaultBalance=function(){t.Balance.SimpleQuery().$promise.then(function(e){r.ajaxResponse.balanceList=e.balanceNames})},r.fun.init=function(){var e=[{groupName:"未分组",groupID:-1}],t=o.get();t?(r.data.apiGroup=e.concat(t),s.initApi()):i.global.ajax.Query_Group.$promise["finally"](function(){r.data.apiGroup=e.concat(o.get()),s.initApi()})}(),r.$onInit=function(){s.getDefaultBalance(),r.component.menuObject={list:[{type:"btn","class":"btn-group-li pull-left",btnList:[{name:"返回列表",icon:"chexiao",fun:{"default":r.fun.back}}]},{type:"btn","class":"btn-group-li",btnList:[{name:"保存","class":"eo_theme_btn_success block-btn",fun:{disabled:1,"default":r.fun.requestProcessing,params:{status:1}}}]}],setting:{"class":"common-menu-fixed-seperate"}}}}angular.module("eolinker").component("apiOperate",{templateUrl:"app/ui/content/project/api/operate/index.html",controller:e}).filter("Filter_SlashSymbol",function(){return function(e){return(e||"").replace(/\/{2,}/g,"/")}}),e.$inject=["$scope","GatewayResource","$state","CODE","$rootScope","GroupService"]}(),function(){function e(e,t,n,a,i,o,r){var s=this;s.data={"static":{query:[{groupID:-1,groupName:"所有接口",icon:"caidan"},{groupID:0,groupName:"未分组",icon:"caidan"}]},sidebarShow:null},s.ajaxRequest={projectID:n.params.projectID,groupID:n.params.groupID||-1,apiID:n.params.apiID,orderNumber:[]},s.component={groupCommonObject:{}},s.service={authority:o};var c={};c.init=function(){n.current.name.indexOf("api.default")>-1?s.data.sidebarShow=!0:s.data.sidebarShow=!1},c.init(),c["import"]=function(){var e={modal:{title:"导入分组",resource:t.ImportAms.Group,request:{projectID:s.ajaxRequest.projectID}}};a.ImportModal(e.modal,function(t){t&&(a.InfoModal(e.modal.title+"成功","success"),s.component.groupCommonObject.mainObject.baseInfo.resetFlag=!s.component.groupCommonObject.mainObject.baseInfo.resetFlag)})},e.$on("$stateChangeSuccess",function(){
-n.current.name.indexOf("api.default")>-1?s.data.sidebarShow=!0:s.data.sidebarShow=!1,s.ajaxRequest.groupID=n.params.groupID}),s.$onInit=function(){var e;s.component.groupCommonObject={requestObject:{resource:t.ApiGroup,baseRequest:{projectID:s.ajaxRequest.projectID}},funObject:{unTop:!0,btnGroupList:[{type:"more-btn",authority:"edit",icon:"jiahao",name:"新建","class":"pull-left",btnClass:"eo_theme_btn_success",btnList:[(e={funName:"edit",name:"新建分组"},_defineProperty(e,"funName","edit"),_defineProperty(e,"icon","jiahao"),e),{name:"导入",fun:c["import"]}]}],callback:{querySuccess:function(e){n.current.name.indexOf("list")>-1?i.set(e):i.set(e,!0)}}},mainObject:{showRouterList:["home.project.api.default"],baseInfo:{sort:!0,name:"groupName",id:"groupID",current:s.ajaxRequest},staticQuery:s.data["static"].query,itemFun:[{funName:"edit",key:"新建子分组",params:'"add-child",arg',authority:"edit",isStrong:1},{funName:"edit",key:"编辑",authority:"edit",params:'"edit",arg'},{funName:"delete",authority:"edit",params:{modal:{title:"删除分组",message:"删除分组后,该分组下的api将全部移入接口回收站,该操作无法撤销,确认删除?"}},key:"删除"}]}}}}angular.module("eolinker").component("apiGroup",{template:' ',controller:e}),e.$inject=["$scope","GatewayResource","$state","$rootScope","GroupService","Authority_CommonService","Cache_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i,o){var r=this;r.data={batch:{address:[]}},r.fun={},r.ajaxRequest={nodeID:[],groupID:n.params.groupID||-1,cluster:n.params.cluster,keyword:window.sessionStorage.getItem("COMMON_SEARCH_TIP")},r.ajaxResponse={query:null},r.component={listDefaultCommonObject:{},menuObject:{}},r.service={authority:o};var s={},c={GROUP_ARR:[{groupID:0,groupDepth:1,groupName:"未分组"}]};s.search=function(e){window.sessionStorage.setItem("COMMON_SEARCH_TIP",e.item.keyword),n.reload(n.current.name)},s.initQueryAjax=function(){var e={groupID:r.ajaxRequest.groupID,cluster:r.ajaxRequest.cluster};return r.ajaxRequest.keyword&&(e.keyword=r.ajaxRequest.keyword),a.global.ajax.Query_Node=t.Node.Query(e),a.global.ajax.Query_Node.$promise.then(function(e){r.ajaxResponse.query=e.nodeList||[]}),a.global.ajax.Query_Node.$promise},r.fun.init=function(){return s.initQueryAjax()},s.changeGroup=function(){var e={modal:{title:"批量修改节点分组",query:c.GROUP_ARR.concat(r.groupArr),position:{key:"groupName"}},request:{nodeIDList:r.data.batch.query.join(","),groupID:"",cluster:r.ajaxRequest.cluster}};a.SingleSelectModal(e.modal,function(n){n&&(e.request.groupID=e.modal.query[n.$index].groupID,t.Node.ChangeGroup(e.request).$promise.then(function(e){switch(e.statusCode){case i.COMMON.SUCCESS:s.resetBatchInfo(),a.InfoModal("节点批量修改分组成功","success"),r.fun.init()}}))})},s.edit=function(e){var n={title:"edit"==e.status?"修改节点":"新建节点",group:c.GROUP_ARR.concat(r.groupArr),item:"edit"==e.status?e.item:{}},o={request:{}};n.item.groupID=e.item.groupID||parseInt(r.ajaxRequest.groupID),n.item.groupID===-1&&(n.item.groupID=0),a.GatewayClusterModal(n,function(n){if(n)switch(o.request={groupID:n.groupID,nodeIP:n.nodeIP,nodeName:n.nodeName,nodePort:n.nodePort,gatewayPath:n.gatewayPath,cluster:r.ajaxRequest.cluster},e.status){case"add":t.Node.Add(o.request).$promise.then(function(e){switch(e.statusCode){case i.COMMON.SUCCESS:r.fun.init(),a.InfoModal("新增节点成功!","success")}});break;default:o.request.nodeID=e.item.nodeID,t.Node.Edit(o.request).$promise.then(function(e){switch(e.statusCode){case i.COMMON.SUCCESS:r.fun.init(),a.InfoModal("修改节点成功!","success")}})}})},s["delete"]=function(e,n){var o={request:{nodeIDList:"batch"==e?r.data.batch.query.join(","):n.item.nodeID,cluster:r.ajaxRequest.cluster}};a.EnsureModal("删除节点",null,"确认删除?",{},function(c){c&&t.Node.Delete(o.request).$promise.then(function(t){switch(t.statusCode){case i.COMMON.SUCCESS:switch(e){case"batch":s.resetBatchInfo(),r.fun.init();break;case"single":r.ajaxResponse.query.splice(n.$index,1)}a.InfoModal("节点删除成功","success")}})})},s.resetBatchInfo=function(){r.data.batch.isOperating=!1,r.data.batch.selectAll=!1,r.data.batch.query=[],r.data.batch.indexAddress={}},r.$onInit=function(){e.$emit("$WindowTitleSet",{list:["节点管理"]}),r.component.listDefaultCommonObject={item:{primaryKey:"nodeID","default":[{key:"名称",html:"{{item.nodeName}}"},{key:"IP:Port",html:"{{item.nodeIP}}:{{item.nodePort}}"},{key:"状态",html:'未运行 异常 运行中 '},{key:"分组",html:"{{item.groupName}}"},{key:"版本",html:"{{item.version}}"},{key:"更新时间",html:"{{item.updateTime}}","class":"w_180"}],operate:{funArr:[{type:"html",html:'修改 '},{key:"删除",fun:s["delete"],params:'"single",arg'}],"class":"w_150"}},baseFun:{edit:s.edit},setting:{isFixedHeight:!0,batch:!0,batchInitFun:s.resetBatchInfo,titleAuthority:"showTitle",unhover:!0,warning:"尚未新建任何节点",fixFoot:!0}},r.component.menuObject={list:[{type:"btn","class":"btn-group-li pull-left",authority:"edit",btnList:[{name:"新建节点",icon:"jiahao","class":"eo_theme_btn_success block-btn",fun:{"default":s.edit,params:{status:"add"}}}]},{type:"search","class":"pull-right",keyword:r.ajaxRequest.keyword,fun:s.search,placeholder:"输入节点名称或IP信息"}],batchList:[{type:"btn","class":"btn-group-li pull-left",btnList:[{name:"修改分组",fun:{"default":s.changeGroup}},{name:"批量删除",fun:{"default":s["delete"],params:'"batch",arg'}}]}],setting:{batch:!0,batchInitFun:s.resetBatchInfo,titleAuthority:"showTitle",title:"节点列表"}}}}angular.module("eolinker").component("clusterNodeDefault",{templateUrl:"app/ui/content/cluster/node/_default/index.html",bindings:{groupArr:"<"},controller:e}),e.$inject=["$scope","GatewayResource","$state","$rootScope","CODE","Authority_CommonService"]}(),function(){function e(e,t,n){var a=this;a.data={"static":{query:[{groupID:-1,groupName:"所有分组",icon:"caidan"},{groupID:0,groupName:"未分组",icon:"caidan"}]}},a.ajaxRequest={cluster:t.params.cluster,groupID:t.params.groupID||-1},a.ajaxResponse={query:[]},a.service={authority:n},a.component={groupCommonObject:{}},a.$onInit=function(){a.component.groupCommonObject={requestObject:{resource:e.NodeGroup,baseRequest:{cluster:a.ajaxRequest.cluster}},funObject:{btnGroupList:[{type:"btn",authority:"edit",icon:"jiahao",name:"新建分组",funName:"edit","class":"eo_theme_btn_success"}],callback:{querySuccess:function(e){a.groupArr=e||[]}}},mainObject:{baseInfo:{name:"groupName",id:"groupID",current:a.ajaxRequest},staticQuery:a.data["static"].query,itemFun:[{funName:"edit",key:"编辑",authority:"edit",params:'"edit",arg'},{funName:"delete",key:"删除",authority:"edit",params:{modal:{title:"删除分组",message:"删除分组后,该分组内的网关节点也将被删除,该操作无法撤销,确认删除?"}}}]}}}}angular.module("eolinker").component("clusterNodeGroup",{template:' ',controller:e,bindings:{groupArr:"="}}),e.$inject=["GatewayResource","$state","Authority_CommonService"]}(),function(){function e(e,t){var n=this;n.data={component:{sidebarCommonObject:{}},info:{menu:[{base:"/api/",name:"API列表",sref:"home.gpedit.inside.api",childSref:"home.gpedit.inside.api.default",icon:"icon-api",power:-1},{base:"/plugin/",name:"策略插件",sref:"home.gpedit.inside.plugin",childSref:"home.gpedit.inside.plugin.gpedit",icon:"icon-cengji_o",power:-1},{base:"/auth",name:"鉴权方式",sref:"home.gpedit.inside.auth",icon:"icon-dunpaibaoxianrenzheng_o",power:-1},{base:"/setting",name:"策略管理",sref:"home.gpedit.inside.setting",icon:"icon-quanjushezhi_o",power:-1}]}};var a={};a.shrink=function(){e.$emit("$Home_ShrinkSidebar",{shrink:n.shrinkObject.isShrink})},n.$onInit=function(){var e={common:"home.gpedit.common.list",open:"home.gpedit.default"};n.data.component.sidebarCommonObject={mainObject:{baseInfo:{staticTop:!0,menu:n.data.info.menu,navigation:[{name:"访问策略",sref:"home.gpedit.default"},{name:t.params.strategyName}],staticQuery:[{name:"返回",sref:e[t.params.groupType],icon:"icon-chexiao",params:{groupID:t.params.groupID}}]},baseFun:{shrink:a.shrink}}}}}angular.module("eolinker").component("gpeditNavbar",{templateUrl:"app/ui/content/gpedit/inside/navbar/index.html",bindings:{shrinkObject:"<"},controller:e}),e.$inject=["$scope","$state"]}(),function(){function e(e,t,n,a){var i=this;i.data={"static":{query:[{groupID:-1,groupName:"所有分组",icon:"caidan"},{groupID:0,groupName:"未分组",icon:"caidan"}]}},i.ajaxRequest={groupID:n.params.groupID||-1},i.ajaxResponse={query:[]},i.service={authority:a},i.component={groupCommonObject:{}};var o={cache:t};i.$onInit=function(){i.component.groupCommonObject={requestObject:{resource:e.StrategyGroup,baseRequest:{}},funObject:{btnGroupList:[{type:"btn",authority:"edit",icon:"jiahao",name:"新建分组",funName:"edit","class":"eo_theme_btn_success"}],callback:{querySuccess:function(e){o.cache.set(e,"gpeditGroup")}}},mainObject:{baseInfo:{name:"groupName",id:"groupID",current:i.ajaxRequest},staticQuery:i.data["static"].query,itemFun:[{funName:"edit",key:"编辑",authority:"edit",params:'"edit",arg'},{funName:"delete",key:"删除",authority:"edit",params:{modal:{title:"删除分组",message:"删除分组后,该分组内的网关节点也将被删除,该操作无法撤销,确认删除?"}}}]}}}}angular.module("eolinker").component("gpeditGroup",{template:' ',controller:e}),e.$inject=["GatewayResource","Cache_CommonService","$state","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i,o,r){var s=this;s.data={groupType:n.params.groupType||null,batch:{},pagination:{maxSize:10,pageSize:50,page:1,msgCount:0}},s.ajaxRequest={groupID:n.params.groupID||-1,strategyID:[],keyword:window.sessionStorage.getItem("COMMON_SEARCH_TIP")},s.ajaxResponse={},s.fun={},s.service={authority:r},s.component={listDefaultCommonObject:{},menuObject:{}};var c={cache:o},l={},u={GROUP_ARR:[{groupID:0,groupName:"未分组",icon:"caidan"}]},p={};l.scrollLoading=function(){var e={hasItem:s.ajaxResponse.query&&0!==s.ajaxResponse.query.length,hasNextPage:s.data.pagination.pages.data.pagination.page*s.data.pagination.pageSize&&l.getQuery("preload",s.data.pagination.page*s.data.pagination.pageSize,1),s.data.pagination.msgCount--,a.InfoModal("策略删除成功","success")}}})})},l.conditionFilter=function(t){s.component.menuObject.active.condition!=t.item.value&&(s.component.menuObject.active.condition=t.item.value,s.ajaxRequest.ids=null,e.$broadcast("$Init_LoadingCommonComponent"))},l.resetBatchInfo=function(){s.data.batch.isOperating=!1,s.data.batch.selectAll=!1,s.data.batch.query=[],s.data.batch.indexAddress={}},s.$onInit=function(){e.$emit("$WindowTitleSet",{list:["普通策略列表"]}),s.component.listDefaultCommonObject={item:{primaryKey:"strategyID","default":[{key:"名称",html:"{{item.strategyName}}"},{key:"策略ID",html:'{{item.strategyID}} 复制 '},{key:"状态",html:'停用 启用 '},{key:"分组",html:"{{item.groupName}}"},{key:"更新时间",html:"{{item.updateTime}}","class":"w_180"}],operate:{funArr:[{key:"复制",fun:l.edit,params:{status:"copy"}},{key:"修改",fun:l.edit,params:{status:"edit"}},{key:"删除",fun:l["delete"],params:'"single",arg'},{key:"启用",itemExpression:'ng-if="item.enableStatus===0"',fun:l.operate,params:{status:"Start"}},{key:"停用",itemExpression:'ng-if="item.enableStatus===1"',fun:l.operate,params:{status:"Stop"}}],"class":"w_220"}},baseFun:{edit:l.edit,click:function(e){n.go("home.gpedit.inside.api.default",{groupType:"common",strategyID:e.item.strategyID,strategyName:e.item.strategyName,groupID:s.ajaxRequest.groupID})},scrollLoading:l.scrollLoading},setting:{page:!0,scroll:!0,scrollRemainRatio:7,isFixedHeight:!0,batch:!0,batchInitFun:l.resetBatchInfo,titleAuthority:"showTitle",warning:"尚未新建任何策略"}},s.component.menuObject={list:[{type:"btn","class":"btn-group-li pull-left",authority:"edit",btnList:[{name:"新建策略",icon:"jiahao","class":"eo_theme_btn_success block-btn",fun:{"default":l.edit,params:{status:"add"}}}]},{type:"search","class":"pull-right",keyword:s.ajaxRequest.keyword,fun:l.search,placeholder:"输入策略名称或策略ID"},{type:"fun-list","class":"fun-list-li pull-right mr15",name:"筛选",icon:"shaixuan",activePoint:"condition",funList:[{name:"无",value:0,active:0,fun:{"default":l.conditionFilter}},{name:"启用",value:2,active:2,fun:{"default":l.conditionFilter}},{name:"停用",value:1,active:1,fun:{"default":l.conditionFilter}}]}],batchList:[{type:"btn","class":"btn-group-li pull-left",btnList:[{name:"修改分组",fun:{"default":l.changeGroup}},{name:"批量删除",fun:{"default":l["delete"],params:'"batch",arg'}},{name:"批量开启",fun:{"default":l.operate,params:{status:"Start"}}},{name:"批量关闭",fun:{"default":l.operate,params:{status:"Stop"}}}]}],setting:{batch:!0,batchInitFun:l.resetBatchInfo,titleAuthority:"showTitle",title:"普通策略列表"},baseFun:{batchDefault:l.batchBtnClickFun},active:{condition:0}}}}angular.module("eolinker").component("gpeditDefault",{templateUrl:"app/ui/content/gpedit/common/default/index.html",controller:e}),e.$inject=["$scope","GatewayResource","$state","$rootScope","CODE","Cache_CommonService","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i){var o=this,r={accessLog:null,nodeLog:null,consoleLog:null},s={};o.data={nodeText:"info",consoleText:"warn"},o.ajaxResponse={nodeLog:{},consoleLog:{},accessLog:{}},o.fun={},o.component={progressBarObj:{setting:{value:"name",key:"title"}},listBlockObj:{tdList:[{type:"sort",itemExpression:'ng-show="$ctrl.authorityObject.edit"'},{type:"checkbox",modelKey:"select",authority:"edit"},{type:"text",thKey:"字段名",modelKey:"name","class":"w_20percent"},{type:"html",thKey:"描述",html:'{{item.desc}} '}]},navigationMenuObject:{}},o.service={authority:i},o.fun.saveForm=function(i){var s=i.charAt(0).toUpperCase()+i.slice(1);if(o.data.submitted=!0,!a[s+"Form"].$invalid){var c=o.ajaxResponse[i+"Log"],l={enable:c.enable,dir:c.dir,file:c.file,period:c.period,expire:c.expire};switch(i){case"access":l.fields=JSON.stringify(c.fields,function(e,t){if(!/(desc)|(isHide)/.test(e))return t});break;default:l.level=c.level}var u=n.ConfigLog["Set"+s](l).$promise;return u.then(function(n){switch(n.statusCode){case t.COMMON.SUCCESS:e.InfoModal("保存成功!","success"),o.data[i+"IsEdit"]=!1,r[i+"Log"]=angular.copy(o.ajaxResponse[i+"Log"])}}),u}},o.fun.cancleEdit=function(e){o.data.submitted=!1,o.data[e+"IsEdit"]=!1,o.ajaxResponse[e+"Log"]=angular.copy(r[e+"Log"])},s.changeMenu=function(e){switch(o.data.menuType=e.item.active,o.data.menuType){case 0:r.accessLog||n.ConfigLog.Access({t:(new Date).getTime()}).$promise.then(function(e){o.ajaxResponse.accessLog=e.data,r.accessLog=angular.copy(o.ajaxResponse.accessLog)});break;case 1:r.consoleLog||n.ConfigLog.Console({t:(new Date).getTime()}).$promise.then(function(e){o.ajaxResponse.consoleLog=e.data,r.consoleLog=angular.copy(o.ajaxResponse.consoleLog)}),r.nodeLog||n.ConfigLog.Node({t:(new Date).getTime()}).$promise.then(function(e){o.ajaxResponse.nodeLog=e.data,r.nodeLog=angular.copy(o.ajaxResponse.nodeLog)})}},o.fun.wantToEdit=function(e){o.data[e+"IsEdit"]=!0},o.$onInit=function(){a.$emit("$WindowTitleSet",{list:["日志设置","网关设置"]}),o.component.navigationMenuObject={list:[{type:"navigation","class":"menu-navigation",activePoint:"menuType",tabList:[{name:"请求日志",active:0,fun:{"default":s.changeMenu}},{name:"运行日志",active:1,fun:{"default":s.changeMenu}}]}],setting:{"class":"common-menu-fixed-seperate common-menu-only-navigation"}},s.changeMenu({item:{active:0}})}}angular.module("eolinker").component("settingLog",{templateUrl:"app/ui/content/setting/log/index.html",controller:e}),e.$inject=["$rootScope","CODE","GatewayResource","$scope","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i){var o=this;o.data={status:{config:{isEdit:!1}},userEmail:[{value:""}]},o.interaction={response:{gatewayConfig:{}}},o.fun={},o.constant={monitorUpdatePeriodQuery:[{key:"30秒",value:30},{key:"60秒",value:60},{key:"180秒",value:180}]};var r={template:{gatewayConfig:{}}};o.service={authority:i},o.fun.editBasicInfo=function(){if(o.data.status.config.submitted=!0,!a.BasicForm.$invalid){var i={request:{successCode:o.interaction.response.gatewayConfig.successCode,monitorUpdatePeriod:o.interaction.response.gatewayConfig.monitorUpdatePeriod,nodeUpdatePeriod:o.interaction.response.gatewayConfig.nodeUpdatePeriod}};n.Config.BaseEdit(i.request).$promise.then(function(n){switch(n.statusCode){case t.COMMON.SUCCESS:e.InfoModal("修改成功!","success"),o.data.status.config.isEdit=!1,angular.copy(o.interaction.response.gatewayConfig,r.template.gatewayConfig)}})}},o.fun.cancleBasicInfo=function(){o.data.status.config.isEdit=!1,o.interaction.response.gatewayConfig=angular.copy(r.template.gatewayConfig)},o.$onInit=function(){a.$emit("$WindowTitleSet",{list:["基本设置","网关设置"]}),n.Config.BaseInfo().$promise.then(function(e){switch(e.statusCode){case t.COMMON.SUCCESS:o.interaction.response.gatewayConfig={successCode:e.gatewayConfig.successCode,monitorUpdatePeriod:e.gatewayConfig.monitorUpdatePeriod,nodeUpdatePeriod:e.gatewayConfig.nodeUpdatePeriod},angular.copy(o.interaction.response.gatewayConfig,r.template.gatewayConfig)}})}}angular.module("eolinker").component("settingBasic",{templateUrl:"app/ui/content/setting/basic/index.html",controller:e}),e.$inject=["$rootScope","CODE","GatewayResource","$scope","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i){var o=this;o.data={from:n.params.status,status:n.params.status,info:{},interaction:{response:{pluginInfo:{pluginName:n.params.pluginName||"",pluginPriority:"",pluginConfig:"",pluginDesc:"",isStop:"1",pluginType:""}}}},o.component={menuObject:{list:[]}},o.fun={};var r={};o.fun.init=function(){if("add"==n.params.status)return void(o.data.interaction.response.pluginInfo.pluginType="0");var a={request:{pluginName:o.data.interaction.response.pluginInfo.pluginName}};t.Plugin.Info(a.request).$promise.then(function(t){t.pluginInfo.isStop=t.pluginInfo.isStop.toString(),t.pluginInfo.pluginType=t.pluginInfo.pluginType.toString(),o.data.interaction.response.pluginInfo=t.pluginInfo,e.$broadcast("$Maunal_AceEditorAms",t.pluginInfo.pluginConfig||"")})},o.fun.back=function(){n.go("home.plugin.default")},r.confirm=function(){var e={output:{pluginName:o.data.interaction.response.pluginInfo.pluginName,pluginPriority:o.data.interaction.response.pluginInfo.pluginPriority,pluginDesc:o.data.interaction.response.pluginInfo.pluginDesc,isStop:o.data.interaction.response.pluginInfo.isStop,pluginType:o.data.interaction.response.pluginInfo.pluginType}};switch(e.output.pluginType){case"0":e.output.pluginConfig=o.data.interaction.response.pluginInfo.pluginConfig}return e.output},o.fun.load=function(t){e.$emit("$TransferStation",{state:"$Init_LoadingCommonComponent",data:t})},o.fun.requestProcessing=function(t){var n={request:r.confirm(),promise:null};return o.data.info.submited=!1,e.editForm.$valid&&(n.request.pluginConfig&&"0"==n.request.pluginType||"0"!=n.request.pluginType)?n.promise=r.edit({request:n.request}):n.request.pluginConfig?(o.data.info.submited=!0,i.InfoModal("插件编辑失败,请检查信息是否填写完整!","error")):(o.data.info.submited=!0,i.InfoModal("插件编辑失败,未填写插件配置文件信息!","error")),n.promise},r.edit=function(e){var r={promise:null};return"edit"==n.params.status?r.promise=t.Plugin.Edit(e.request).$promise:r.promise=t.Plugin.Add(e.request).$promise,r.promise.then(function(e){switch(e.statusCode){case a.COMMON.SUCCESS:o.fun.back(),i.InfoModal(("edit"==n.params.status?"修改":"添加")+"插件成功","success")}}),r.promise},o.$onInit=function(){o.component.menuObject={list:[{type:"btn","class":"btn-group-li pull-left",btnList:[{name:"返回列表",icon:"chexiao",fun:{"default":o.fun.back}}]},{type:"btn","class":"btn-group-li",btnList:[{name:"保存","class":"eo_theme_btn_success block-btn",fun:{disabled:1,"default":o.fun.requestProcessing,params:{status:1}}}]}],setting:{"class":"common-menu-fixed-seperate"}}}}angular.module("eolinker").component("pluginOperate",{templateUrl:"app/ui/content/plugin/operate/index.html",controller:e}),e.$inject=["$scope","GatewayResource","$state","CODE","$rootScope"]}(),function(){"use strict";function e(e,t,n,a,i,o){var r=this;r.data={batch:{address:[]}},r.ajaxResponse={},r.service={authority:o},r.ajaxRequest={pluginName:[],keyword:window.sessionStorage.getItem("COMMON_SEARCH_TIP")},r.component={menuObject:{},listRequireObject:null},r.fun={};var s={},c={checking:!1};r.fun.init=function(){var e={condition:r.component.menuObject.active.condition};return r.ajaxRequest.keyword&&(e.keyword=r.ajaxRequest.keyword),a.global.ajax.Query_Plugin=t.Plugin.Query(e),a.global.ajax.Query_Plugin.$promise.then(function(e){r.ajaxResponse.query=e.pluginList||[],r.ajaxResponse.query.map(function(e){e.isAlreadyStart=1===e.pluginStatus})}),a.global.ajax.Query_Plugin.$promise},s.conditionFilter=function(t){r.component.menuObject.active.condition!=t.item.value&&(r.component.menuObject.active.condition=t.item.value,r.ajaxRequest.ids=null,e.$broadcast("$Init_LoadingCommonComponent"))},s.search=function(e){window.sessionStorage.setItem("COMMON_SEARCH_TIP",e.item.keyword),n.reload(n.current.name)},s.check=function(e){if(c.checking)return void a.InfoModal("当前已有插件正在进行检测,请稍后再试","error");var n={request:{pluginName:e.item.pluginName},pluginStatus:e.item.pluginStatus};c.checking=!0,r.ajaxResponse.query[e.$index].pluginStatus=2,t.Plugin.Check(n.request).$promise.then(function(t){switch(c.checking=!1,r.ajaxResponse.query[e.$index].pluginStatus=n.pluginStatus,r.ajaxResponse.query[e.$index].isAlreadyStart=n.pluginStatus,t.statusCode){case i.COMMON.SUCCESS:a.InfoModal("检测在全部节点内检测成功,插件可正常使用","success"),r.ajaxResponse.query[e.$index].isCheck=!0;break;case"210000":a.Gateway_NodeCheckErrorReportModal({query:t.errNodeList,pluginName:e.item.pluginName},"success"),r.ajaxResponse.query[e.$index].isCheck=!1}})},s.batchOperate=function(e){var o={tip:"",resource:null,pluginStatus:0};switch(e){case"start":o.tip="开启",o.resource=t.Plugin.BatchStart,o.pluginStatus=1;break;case"stop":o.tip="关闭",o.resource=t.Plugin.BatchStop}o.resource({pluginNameList:r.data.batch.query.join(",")}).$promise.then(function(e){switch(e.statusCode){case i.COMMON.SUCCESS:a.InfoModal("批量"+o.tip+"插件成功!","success"),n.reload("home.plugin.default")}})},s.operate=function(e){t.Plugin[e.status]({pluginName:e.item.pluginName}).$promise.then(function(t){switch(t.statusCode){case i.COMMON.SUCCESS:r.ajaxResponse.query[e.$index].pluginStatus="Start"==e.status?1:0,r.ajaxResponse.query[e.$index].isAlreadyStart=r.ajaxResponse.query[e.$index].pluginStatus,r.ajaxResponse.query[e.$index].isCheck=0,a.InfoModal(("Start"==e.status?"开启":"关闭")+e.item.pluginName+"成功!","success")}})},s.edit=function(e){var t={uri:{status:e.status}};switch(e.status){case"edit":t.uri.pluginName=e.item.pluginName}n.go("home.plugin.operate",t.uri)},s["delete"]=function(e){var n={request:{pluginName:e.item.pluginName}};a.EnsureModal("删除"+e.item.pluginName,null,"确认删除?",{},function(o){o&&t.Plugin.Delete(n.request).$promise.then(function(t){switch(t.statusCode){case i.COMMON.SUCCESS:r.ajaxResponse.query.splice(e.$index,1),a.InfoModal(e.item.pluginName+"删除成功","success")}})})},s.resetBatchInfo=function(){r.data.batch.isOperating=!1,r.data.batch.selectAll=!1,r.data.batch.query=[],r.data.batch.indexAddress={}},r.$onInit=function(){e.$emit("$WindowTitleSet",{list:["插件管理"]}),r.component.listDefaultCommonObject={item:{primaryKey:"pluginName","default":[{key:"名称",html:"{{item.pluginName}}"},{key:"描述",html:"{{item.pluginDesc}}"},{key:"插件类型",html:'全局 策略 API ',"switch":"pluginType","class":"w_100"},{key:"优先级(0-3000)",html:"{{item.pluginPriority}}","class":"w_150"},{key:"状态",html:'关闭 开启 检测中 ',"switch":"pluginStatus","class":"w_80"}],operate:{funArr:[{key:"配置",itemExpression:'ng-if="item.pluginType===0"',fun:s.edit,params:{status:"edit"}},{key:"关闭",fun:s.operate,itemExpression:'ng-if="item.isAlreadyStart"',params:{status:"Stop"}},{key:"开启",fun:s.operate,itemExpression:'ng-if="!item.isAlreadyStart" ng-disabled="!item.isCheck"',params:{status:"Start"}},{key:'检测 ',itemExpression:'ng-disabled="item.isAlreadyStart"',fun:s.check},{key:"删除",fun:s["delete"]}],power:-1,"class":"w_250"}},setting:{unhover:!0,batch:!0,defaultFoot:!0}},r.component.menuObject={list:[{type:"btn",authority:"edit","class":"pull-left",btnList:[{name:"添加插件",icon:"jiahao","class":"eo_theme_btn_success block-btn",fun:{"default":s.edit,params:{status:"add"}}}]},{type:"search","class":"pull-right",keyword:r.ajaxRequest.keyword,fun:s.search,placeholder:"输入插件名称或描述"},{type:"fun-list","class":"fun-list-li pull-right mr15",name:"筛选",icon:"shaixuan",activePoint:"condition",funList:[{name:"无",value:0,active:0,fun:{"default":s.conditionFilter}},{name:"全局插件",value:1,active:1,fun:{"default":s.conditionFilter}},{name:"策略插件",value:2,active:2,fun:{"default":s.conditionFilter}},{name:"接口插件",value:3,active:3,fun:{"default":s.conditionFilter}}]}],batchList:[{type:"btn",disabledPoint:"isBatchSelected","class":"pull-left",btnList:[{name:"批量开启",show:!0,disabled:0,fun:{"default":s.batchOperate,params:'"start"'}},{name:"批量关闭",show:!0,disabled:0,fun:{"default":s.batchOperate,params:'"stop"'}}]}],setting:{batch:!0,batchInitFun:s.resetBatchInfo,"class":"common-menu-fixed-seperate common-menu-lg",titleAuthority:"showTitle",title:"扩展插件"},active:{condition:0}}}}angular.module("eolinker").component("pluginDefault",{templateUrl:"app/ui/content/plugin/_default/index.html",controller:e}),e.$inject=["$scope","GatewayResource","$state","$rootScope","CODE","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i,o){var r=this;r.data={batch:{}},r.ajaxRequest={projectID:[],keyword:window.sessionStorage.getItem("COMMON_SEARCH_TIP")},r.ajaxResponse={},r.fun={},r.service={authority:o},r.component={menuObject:null};var s={};r.fun.init=function(){var e={};return r.ajaxRequest.keyword&&(e.keyword=r.ajaxRequest.keyword),a.global.ajax.Query_Project=t.Project.Query(e),a.global.ajax.Query_Project.$promise.then(function(e){r.ajaxResponse.query=e.projectList||[]}),a.global.ajax.Query_Project.$promise},s["import"]=function(){var n={title:"导入项目",resource:t.ImportAms.Project};a.ImportModal(n,function(t){t&&(a.InfoModal(n.title+"成功","success"),e.$broadcast("$Init_LoadingCommonComponent"))})},s.edit=function(e){var n={},o={title:("edit"==e.status?"修改":"新增")+"项目",placeholder:"项目名称",text:e.item.projectName||""};a.Common_SingleInputModal(o,function(s){if(s)switch(n.projectName=s.text,e.status){case"add":t.Project.Add(n).$promise.then(function(e){switch(e.statusCode){case i.COMMON.SUCCESS:a.InfoModal(o.title+"成功","success"),r.fun.init()}});break;case"edit":n.projectID=e.item.projectID,t.Project.Edit(n).$promise.then(function(e){switch(e.statusCode){case i.COMMON.SUCCESS:a.InfoModal(o.title+"成功","success"),r.fun.init()}})}})},s["delete"]=function(e){var n={projectIDList:"batch"==e.status?r.data.batch.query.join(","):e.item.projectID},o={title:"batch"==e.status?"批量删除项目":"删除项目-"+e.item.projectName};a.EnsureModal(o.title,null,"确认删除?",{},function(c){
-c&&t.Project.Delete(n).$promise.then(function(t){switch(t.statusCode){case i.COMMON.SUCCESS:switch(e.status){case"batch":s.resetBatchInfo(),r.fun.init();break;case"single":r.ajaxResponse.query.splice(e.$index,1)}a.InfoModal(o.title+"成功","success")}})})},s.click=function(e){n.go("home.project.api.default",{projectID:e.item.projectID,projectName:e.item.projectName})},s.resetBatchInfo=function(){r.data.batch.isOperating=!1,r.data.batch.selectAll=!1,r.data.batch.query=[],r.data.batch.groupQuery=[],r.data.batch.indexAddress={},r.data.batchOprArchive=[]},s.search=function(e){window.sessionStorage.setItem("COMMON_SEARCH_TIP",e.item.keyword),n.reload(n.current.name)},r.$onInit=function(){e.$emit("$WindowTitleSet",{list:["项目列表"]}),r.component.listDefaultCommonObject={item:{primaryKey:"projectID",resource:t.Project,"default":[{key:"名称",html:"{{item.projectName}}",contentClass:"item-title-li"},{key:"更新时间",html:"{{item.updateTime}}","class":"w_250",isUnneccessary:!0}],operate:{funArr:[{key:"编辑",fun:s.edit,params:{status:"edit"}},{key:"删除",fun:s["delete"],params:{status:"single"}}],"class":"w_150"}},setting:{batch:!0,warning:"尚未新建任何项目",defaultFoot:!0},baseFun:{click:s.click,batchSelectAll:function(e,t){switch(e){case"select":switch(t.isArchive){case 1:var n=r.data.batchOprArchive.indexOf(t.projectHashKey);n===-1&&r.data.batchOprArchive.push(t.projectHashKey)}break;case"cancel":r.data.batchOprArchive=[]}},batchItemClick:function(e){switch(e.isArchive){case 1:var t=r.data.batchOprArchive.indexOf(e.projectHashKey);t===-1?r.data.batchOprArchive.push(e.projectHashKey):r.data.batchOprArchive.splice(t,1)}}}},r.component.menuObject={list:[{type:"btn",authority:"edit","class":"pull-left",btnList:[{name:"新建项目",icon:"jiahao","class":"eo_theme_btn_success block-btn",fun:{"default":s.edit,params:{status:"add"}}}]},{type:"btn",authority:"edit","class":"pull-left",btnList:[{name:"导入",icon:"yunshangchuan",fun:{"default":s["import"]}}]},{type:"search","class":"pull-right mr15",keyword:r.ajaxRequest.keyword,fun:s.search,placeholder:"输入项目名称"}],batchList:[{type:"btn",disabledPoint:"isBatchSelected","class":"pull-left",btnList:[{name:"删除",icon:"shanchu",disabled:!1,fun:{"default":s["delete"],params:{status:"batch"}}}]}],setting:{batch:!0,batchInitFun:s.resetBatchInfo,"class":"common-menu-fixed-seperate common-menu-lg",title:"接口管理",titleAuthority:"showTitle"}}}}angular.module("eolinker").component("projectDefault",{templateUrl:"app/ui/content/project/_default/index.html",controller:e}),e.$inject=["$scope","GatewayResource","$state","$rootScope","CODE","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a){var i=this,o={cache:t,navbar:e};i.data={},i.component={menuObject:null};var r={};r.setNavShow=function(){n.current.name.indexOf("api.default")>-1?i.data.navShow=!0:i.data.navShow=!1},a.$on("$stateChangeSuccess",r.setNavShow),i.$onInit=function(){o.cache.clear("apiGroup"),r.setNavShow(),o.navbar.info.navigation.extra=n.params.projectName,i.component.menuObject={list:[{type:"btn","class":"btn-group-li pull-left",btnList:[{name:"返回项目列表",icon:"chexiao",fun:{"default":function(){n.go("home.project.default")}}}]}],setting:{"class":"common-menu-fixed-seperate"}}}}angular.module("eolinker").component("api",{templateUrl:"app/ui/content/project/api/index.html",controller:e}),e.$inject=["NavbarService","Cache_CommonService","$state","$scope"]}(),function(){"use strict";function e(e,t,n,a,i,o){var r=this,s={};r.data={cluster:"",tabSummaryList:[{name:"今天",active:0},{name:"近3天",active:1},{name:"近7天",active:2},{active:3,type:"html"}],granularityList:[{name:"小时",active:1},{name:"天",active:0}]},r.fun={},r.ajaxRequest={projectHashKey:n.params.projectHashKey,table:{beginTime:null,endTime:null,period:0}},r.ajaxResponse={monitorInfo:null,redisArr:[]},r.directive={tableTimeObject:{show:!1,maxDate:new Date,maxMode:"month",request:{}}},r.component={overviewObject:{},listDefaultCommonObject:null},s.filterTime=function(e){var t={startTime:o.filter(r.directive[e+"TimeObject"].request.startTime,"yyyy-M!-dd"),endTime:o.filter(r.directive[e+"TimeObject"].request.endTime,"yyyy-M!-dd")};t.startTime?t.endTime?(r.ajaxRequest[e].period=3,r.directive[e+"TimeObject"].show=!1,t.startTime>t.endTime&&(t.templateTime=t.startTime,t.startTime=t.endTime,t.endTime=t.templateTime),r.ajaxRequest[e].beginTime=t.startTime,r.ajaxRequest[e].endTime=t.endTime,s.initTable()):i.InfoModal("请选择结束日期","error"):i.InfoModal("请选择开始日期","error")},r.fun.tableFilterTime=function(e){e&&e.$event.stopPropagation(),s.filterTime("table")},r.fun.changeMenu=function(e,t){return 3==t.item.active?(r.directive.tableTimeObject.show=!0,void t.$event.stopPropagation()):(r.directive.tableTimeObject.request={},r.ajaxRequest.table.beginTime=null,r.ajaxRequest.table.period=t.item.active,void s.initTable())},s.initTable=function(){var e={promise:null,request:{beginTime:r.ajaxRequest.table.beginTime,endTime:r.ajaxRequest.table.endTime,period:r.ajaxRequest.table.period,cluster:r.data.cluster}};return e.promise=t.Monitor.Info(e.request).$promise,e.promise.then(function(e){r.ajaxResponse.monitorInfo=e||{}}),e.promise},s.refresh=function(){var n=t.Monitor.Refresh().$promise;return n.then(function(t){switch(t.statusCode){case a.COMMON.SUCCESS:i.InfoModal("立即刷新成功!","success",function(){e.$emit("$TransferStation",{state:"$Init_LoadingCommonComponent"})})}}),n},s.initComponent=function(){r.component.overviewObject={setting:{title:"基本信息",showOperate:!0}}},r.fun.init=function(e){switch(e=e||{type:"default"},e.type){case"default":if(r.data.cluster)return s.initTable();var t=s.initCluster();return t["finally"](function(){s.initTable()}),t;case"refresh":return s.refresh();case"cluster":return s.initTable()}},r.fun.refresh=function(){e.$emit("$TransferStation",{state:"$Init_LoadingCommonComponent",data:{type:"refresh",tips:"刷新"}})},r.fun.changeClutser=function(){e.$emit("$TransferStation",{state:"$Init_LoadingCommonComponent",data:{type:"cluster"}})},s.initCluster=function(){var e=t.Cluster.SimpleQuery().$promise;return e.then(function(e){r.ajaxResponse.clusterArr=[{title:"所有集群",name:null}].concat(e.clusters||[]),r.data.cluster=r.ajaxResponse.clusterArr[0].name}),e},r.$onInit=function(){e.$emit("$WindowTitleSet",{list:["监控面板"]}),s.initComponent()}}angular.module("eolinker").component("panel",{templateUrl:"app/ui/content/monitor/global/index.html",controller:e}),e.$inject=["$scope","GatewayResource","$state","CODE","$rootScope","uibDateParser"]}(),function(){function e(e,t){var n=this,a={navbar:e};n.component={menuObject:{}},n.$onInit=function(){a.navbar.info.navigation.extra=t.params.clusterName,n.component.menuObject={list:[{type:"btn","class":"btn-group-li pull-left",btnList:[{name:"返回集群列表",icon:"chexiao",fun:{"default":function(){t.go("home.cluster.default")}}}]}],setting:{"class":"common-menu-fixed-seperate"}}}}angular.module("eolinker").component("clusterNode",{templateUrl:"app/ui/content/cluster/node/index.html",controller:e}),e.$inject=["NavbarService","$state"]}(),function(){"use strict";function e(e,t,n,a){var i=this;i.ajaxResponse={query:[]},i.fun={},i.component={listRequireObject:null};var o={};i.fun.init=function(){return n.global.ajax.Query_Cluster=t.Cluster.Query(),n.global.ajax.Query_Cluster.$promise.then(function(e){i.ajaxResponse.query=e.clusters||[]}),n.global.ajax.Query_Cluster.$promise},o.inToCluster=function(e){a.go("home.cluster.node.default",{cluster:e.item.name,clusterName:e.item.title})},i.$onInit=function(){e.$emit("$WindowTitleSet",{list:["网关节点"]}),i.component.menuObject={setting:{"class":"common-menu-fixed-seperate common-menu-lg",titleAuthority:"showTitle",title:"网关节点",secondTitle:"网关支持分集群管理节点"}},i.component.listDefaultCommonObject={setting:{warning:"尚无任何集群",defaultFoot:!0},item:{"default":[{key:"集群名称",html:"{{item.title}}"},{key:"备注",html:"{{item.note}}"},{key:"数据库地址",html:"{{item.db.host+':'+item.db.port+'/'+item.db.database}}"}],operate:{funArr:[{key:"查看详情",fun:o.inToCluster}],power:-1,"class":"w_100"}},baseFun:{click:o.inToCluster}}}}angular.module("eolinker").component("clusterDefault",{templateUrl:"app/ui/content/cluster/_default/index.html",controller:e}),e.$inject=["$scope","GatewayResource","$rootScope","$state"]}(),function(){"use strict";function e(e,t,n,a,i){var o=this;o.data={status:n.params.status,balanceNamePattern:"[\\w\\._\\/\\-\\:]+"},o.fun={},o.ajaxResponse={balanceInfo:{balanceName:n.params.balanceName||"",serviceType:"static"},serviceQuery:[{registryName:"无",serviceDiscoveryID:0}]},o.component={menuObject:{list:[]},listBlockObj:{}},o.CONST={SERVICE_TYPE_ARR:[{key:"静态服务",value:"static"},{key:"服务发现",value:"discovery"}]};var r={},s={staticServiceQuery:[],discoveryServiceQuery:[],serviceIDObj:{}};o.fun.switchMenu=function(e,t){o.ajaxResponse.balanceInfo.serviceType=e,o.ajaxResponse.serviceQuery=s[e+"ServiceQuery"],t||(o.ajaxResponse.balanceInfo.serviceName=s.serviceIDObj[e]||o.ajaxResponse.serviceQuery[0].name)},o.fun.init=function(){if("add"!==o.data.status){var e={balanceName:o.ajaxResponse.balanceInfo.balanceName};t.Balance.Info(e).$promise.then(function(e){e.balanceInfo.staticCluster=e.balanceInfo.staticCluster||{},o.ajaxResponse.balanceInfo=e.balanceInfo,i.global.ajax.Query_ServiceDiscovery.$promise["finally"](function(){o.fun.switchMenu(o.ajaxResponse.balanceInfo.serviceType,!0)}),i.global.ajax.SimpleQuery_Cluster.$promise["finally"](function(){o.ajaxResponse.clusterList.map(function(t,n){o.ajaxResponse.balanceInfo.staticCluster.hasOwnProperty(t.name)&&(o.ajaxResponse.clusterList[n].value=e.balanceInfo.staticCluster[t.name])})})})}},o.fun.back=function(){n.go("home.balance.list.default")},r.initRegistry=function(){return i.global.ajax.Query_ServiceDiscovery=t.ServiceDiscovery.SimpleQuery(),i.global.ajax.Query_ServiceDiscovery.$promise.then(function(e){e.data.list.map(function(e){switch(e.type){case"static":s.staticServiceQuery.push(e);break;default:s.discoveryServiceQuery.push(e)}}),0===s.staticServiceQuery.length&&s.staticServiceQuery.push({name:"无"}),0===s.discoveryServiceQuery.length&&s.discoveryServiceQuery.push({name:"无"}),"add"===o.data.status&&o.fun.switchMenu(o.ajaxResponse.balanceInfo.serviceType)}),i.global.ajax.Query_ServiceDiscovery.$promise},r.confirm=function(){var e={balanceName:o.ajaxResponse.balanceInfo.balanceName,serviceName:o.ajaxResponse.balanceInfo.serviceName};switch(o.ajaxResponse.balanceInfo.serviceType){case"static":e["static"]=o.ajaxResponse.balanceInfo["static"],e.staticCluster={};var t=!0,n=!1,a=void 0;try{for(var i,r=o.ajaxResponse.clusterList[Symbol.iterator]();!(t=(i=r.next()).done);t=!0){var s=i.value;e.staticCluster[s.name]=s.value}}catch(c){n=!0,a=c}finally{try{!t&&r["return"]&&r["return"]()}finally{if(n)throw a}}e.staticCluster=JSON.stringify(e.staticCluster);break;default:e.appName=o.ajaxResponse.balanceInfo.appName}return e},o.fun.load=function(t){e.$emit("$TransferStation",{state:"$Init_LoadingCommonComponent",data:t})},o.fun.requestProcessing=function(t){if(o.data.submitted=!0,"无"===o.ajaxResponse.balanceInfo.serviceName)return void i.InfoModal("暂未发现任何服务注册方式,请先新建服务注册方式","error");var n=r.confirm(),a=null;return e.ConfirmForm.$valid?a=r.edit({request:n}):i.InfoModal("编辑失败,请检查信息是否填写完整!","error"),a},r.edit=function(e){var n=null;if("edit"==o.data.status)n=t.Balance.Edit(e.request).$promise,n.then(function(e){switch(e.statusCode){case a.COMMON.SUCCESS:o.fun.back(),i.InfoModal("修改成功","success")}});else{var r=angular.copy(e.request);n=t.Balance.Add(r).$promise,n.then(function(e){switch(e.statusCode){case a.COMMON.SUCCESS:o.fun.back(),i.InfoModal("添加负载成功","success")}})}return n},r.initBlockTable=function(){o.component.listBlockObj={setting:{munalAddRow:!0},tdList:[{type:"text",thKey:"范围",modelKey:"title","class":"w_150"},{type:"input",thKey:"静态服务地址",modelKey:"value"}]}},r.initCluster=function(){i.global.ajax.SimpleQuery_Cluster=t.Cluster.SimpleQuery(),i.global.ajax.SimpleQuery_Cluster.$promise.then(function(e){o.ajaxResponse.clusterList=e.clusters||[]})},o.$onInit=function(){r.initCluster(),r.initRegistry(),r.initBlockTable(),o.component.menuObject={list:[{type:"btn","class":"btn-group-li pull-left",btnList:[{name:"返回列表",icon:"chexiao",fun:{"default":o.fun.back}}]},{type:"btn","class":"btn-group-li",btnList:[{name:"保存","class":"eo_theme_btn_success block-btn",fun:{disabled:1,"default":o.fun.requestProcessing,params:{status:1}}}]}],setting:{"class":"common-menu-fixed-seperate"}}}}angular.module("eolinker").component("balanceOperate",{templateUrl:"app/ui/content/balance/operate/index.html",controller:e,bindings:{groupArr:"<"}}),e.$inject=["$scope","GatewayResource","$state","CODE","$rootScope"]}(),function(){"use strict";function e(e,t,n,a,i,o){var r=this;r.data={batch:{}},r.ajaxRequest={name:[],keyword:window.sessionStorage.getItem("COMMON_SEARCH_TIP")},r.ajaxResponse={query:[]},r.fun={},r.service={authority:o},r.component={menuObject:{show:{batch:{disable:!1}}},listRequireObject:null};var s={},c={clusterQuery:null},l={clusterNameObj:{}};r.fun.init=function(){var e={};return r.ajaxRequest.keyword&&(e.keyword=r.ajaxRequest.keyword),a.global.ajax.Query_ServiceDiscovery=t.ServiceDiscovery.Query(e),a.global.ajax.Query_ServiceDiscovery.$promise.then(function(e){r.ajaxResponse.query=e.data||[]}),a.global.ajax.Query_ServiceDiscovery.$promise},s.search=function(e){window.sessionStorage.setItem("COMMON_SEARCH_TIP",e.item.keyword),n.reload(n.current.name)},s.initCluster=function(){var e=t.Cluster.SimpleQuery().$promise;return e},s.getServiceData=function(e){var n=t.ServiceDiscovery.Info({name:e}).$promise;return n},s.edit=function(e,t){t=t||{item:{}};var n={edit:{title:"编辑服务注册方式",resource:"Edit"},add:{title:"添加服务注册方式",resource:"Add"}},i=function(i){var o=function(t){t=Object.assign({},{type:"static",driver:"eureka"},t);var o={title:n[e].title,opr:n[e].resource,ajaxResponse:{serviceData:t,clusterQuery:i}};a.Gateway_ServiceModal(o,function(e){e&&r.fun.init()})};if("edit"===e){var c=s.getServiceData(t.item.name);c.then(function(e){if("discovery"===t.item.type){var n=e.data.clusterConfig||{};for(var a in n)l.clusterNameObj.hasOwnProperty(a)&&(i[l.clusterNameObj[a]].value=n[a])}o(e.data)})}else o()};if(c.clusterQuery)i(angular.copy(c.clusterQuery));else{var o=s.initCluster();o.then(function(e){c.clusterQuery=e.clusters||[],c.clusterQuery.map(function(e,t){l.clusterNameObj[e.name]=t}),i(c.clusterQuery)})}},s["delete"]=function(e){var n={names:"batch"==e.status?r.data.batch.query.join(","):e.item.name},o={title:"batch"==e.status?"批量删除服务注册方式":"删除服务注册方式-"+e.item.name};a.EnsureModal(o.title,null,"确认删除?",{},function(c){c&&t.ServiceDiscovery.Delete(n).$promise.then(function(t){switch(t.statusCode){case i.COMMON.SUCCESS:switch(e.status){case"batch":s.resetBatchInfo(),r.fun.init();break;case"single":r.ajaxResponse.query.splice(e.$index,1)}a.InfoModal(o.title+"成功","success")}})})},s.resetBatchInfo=function(){r.data.batch.isOperating=!1,r.data.batch.selectAll=!1,r.data.batch.query=[],r.data.batch.indexAddress={}},r.$onInit=function(){e.$emit("$WindowTitleSet",{list:["服务注册方式"]}),r.component.listDefaultCommonObject={item:{primaryKey:"name","default":[{key:"服务注册方式",html:"{{item.name}}"},{key:"服务类型",html:"{{item.driver}}"},{key:"更新时间",html:"{{item.updateTime}}",keyStyle:{width:"200px"}}],operate:{funArr:[{key:"修改",show:!1,fun:s.edit,params:'"edit",arg'},{key:"删除",show:!1,fun:s["delete"],params:{status:"single"}}],"class":"w_200"}},setting:{batch:!0,unhover:!0,warning:"尚未添加任何内容",defaultFoot:!0}},r.component.menuObject={list:[{type:"btn",authority:"edit","class":"pull-left",btnList:[{name:"服务注册方式",icon:"jiahao","class":"eo_theme_btn_success block-btn",fun:{"default":s.edit,params:'"add"'}}]},{type:"search","class":"pull-right",keyword:r.ajaxRequest.keyword,fun:s.search,placeholder:"输入服务注册方式名称"}],batchList:[{type:"btn",disabledPoint:"isBatchSelected","class":"pull-left",btnList:[{name:"删除",icon:"shanchu",disabled:!1,fun:{"default":s["delete"],params:{status:"batch"}}}]}],setting:{batch:!0,batchInitFun:s.resetBatchInfo,"class":"common-menu-fixed-seperate common-menu-lg",titleAuthority:"showTitle",title:"服务注册方式",secondTitle:"您可以通过静态或动态的方式来注册(发现)您的后端服务,创建好服务注册方式后,您可以在某个方式的基础上创建一个或多个负载(Upstream)"}}}}angular.module("eolinker").component("balanceService",{templateUrl:"app/ui/content/balance/service/index.html",controller:e}),e.$inject=["$scope","GatewayResource","$state","$rootScope","CODE","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i,o){var r=this;r.data={batch:{address:[]}},r.ajaxRequest={balanceName:[],keyword:window.sessionStorage.getItem("COMMON_SEARCH_TIP")},r.ajaxResponse={query:null},r.service={authority:o},r.component={menuObject:{},listRequireObject:null},r.fun={};var s={},c={};r.fun.init=function(){var e={};return r.ajaxRequest.keyword&&(e.keyword=r.ajaxRequest.keyword),a.global.ajax.Query_Balance=t.Balance.Query(e),a.global.ajax.Query_Balance.$promise.then(function(e){r.ajaxResponse.query=e.balanceList||[]}),a.global.ajax.Query_Balance.$promise},s.search=function(e){window.sessionStorage.setItem("COMMON_SEARCH_TIP",e.item.keyword),n.reload(n.current.name)},s.resetBatchInfo=function(){r.data.batch.isOperating=!1,r.data.batch.selectAll=!1,r.data.batch.query=[],r.data.batch.indexAddress={}},s.initRegistry=function(){return a.global.ajax.Query_ServiceDiscovery&&a.global.ajax.Query_ServiceDiscovery.$cancelRequest(),a.global.ajax.Query_ServiceDiscovery=t.ServiceDiscovery.SimpleQuery(),a.global.ajax.Query_ServiceDiscovery.$promise.then(function(e){c.registry=e.data.list}),a.global.ajax.Query_ServiceDiscovery.$promise},s.edit=function(e){var t={status:e.status};switch(e.status){case"edit":t.balanceName=e.item.balanceName,n.go("home.balance.list.operate",t);break;default:var i=s.initRegistry();i["finally"](function(){0===c.registry.length?a.InfoModal("请先新建服务注册方式","error"):n.go("home.balance.list.operate",t)})}},s["delete"]=function(e){var n={request:{balanceNames:"batch"==e.status?r.data.batch.query.join(","):e.item.balanceName},modal:{title:"batch"==e.status?"批量删除负载":"删除负载-"+e.item.balanceName},loop:{num:0}};a.EnsureModal(n.modal.title,null,"确认删除?",{},function(o){o&&t.Balance.Delete(n.request).$promise.then(function(t){switch(t.statusCode){case i.COMMON.SUCCESS:switch(e.status){case"batch":s.resetBatchInfo(),r.fun.init();break;case"single":r.ajaxResponse.query.splice(e.$index,1)}a.InfoModal(n.modal.title+"成功","success")}})})},r.$onInit=function(){e.$emit("$WindowTitleSet",{list:["负载管理"]}),r.component.listDefaultCommonObject={item:{primaryKey:"balanceName","default":[{key:"名称",html:"{{item.balanceName}}"},{key:"服务注册方式",html:"{{item.serviceName}}"},{key:"更新时间",html:"{{item.updateTime}}","class":"w_200"}],operate:{funArr:[{key:"修改",fun:s.edit,params:{status:"edit"}},{key:"删除",fun:s["delete"],params:{status:"single"}}],"class":"w_150"}},setting:{batch:!0,unhover:!0,warning:"尚未添加负载",defaultFoot:!0}},r.component.menuObject={list:[{type:"btn",authority:"edit","class":"pull-left",btnList:[{name:"添加负载",icon:"jiahao","class":"eo_theme_btn_success block-btn",fun:{"default":s.edit,params:{status:"add"}}}]},{type:"search","class":"pull-right",keyword:r.ajaxRequest.keyword,fun:s.search,placeholder:"输入负载名称或服务注册方式"}],batchList:[{type:"btn",disabledPoint:"isBatchSelected","class":"pull-left",btnList:[{name:"删除",icon:"shanchu",disabled:!1,fun:{"default":s["delete"],params:{status:"batch"}}}]}],setting:{batch:!0,batchInitFun:s.resetBatchInfo,"class":"common-menu-fixed-seperate common-menu-lg",titleAuthority:"showTitle",title:"负载配置",secondTitle:"配置API的转发目标服务器(负载后端),创建之后可以设置为 API 的转发地址 / 负载后端(Target / Upstream)"}}}}angular.module("eolinker").component("balanceList",{templateUrl:"app/ui/content/balance/list/index.html",controller:e}),e.$inject=["$scope","GatewayResource","$state","$rootScope","CODE","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n){var a=this;a.data={info:{strategyID:t.params.strategyID,shrinkObject:{}}},a.service={authority:n},a.$onInit=function(){e.$emit("$Home_ShrinkSidebar",{shrink:!1})}}angular.module("eolinker").config(["$stateProvider","RouteHelpersProvider",function(e,t){e.state("gepdit.inside",{url:"/inside?projectHashKey",template:" "})}]).component("gepditInside",{templateUrl:"app/ui/content/gpedit/inside/index.html",controller:e}),e.$inject=["$scope","$state","Authority_CommonService"]}(),function(){"use strict";function e(e,t){var n=this,a={cache:e};n.component={},n.$onInit=function(){a.cache.clear("gpeditGroup"),n.component.menuObject={list:[{type:"btn","class":"btn-group-li pull-left",btnList:[{name:"返回策略列表",icon:"chexiao",fun:{"default":function(){t.go("home.gpedit.default")}}}]}],setting:{"class":"common-menu-fixed-seperate"}}}}angular.module("eolinker").component("gpeditCommon",{templateUrl:"app/ui/content/gpedit/common/index.html",controller:e}),e.$inject=["Cache_CommonService","$state"]}(),function(){"use strict";function e(e,t,n){var a=this;a.component={menuObject:null},a.fun={},a.ajaxResponse={};var i={};i.ajaxOpenGpedit=function(){n.Strategy.Info({strategyType:1}).$promise.then(function(e){a.ajaxResponse.openGpeditInfo=e.strategyInfo||{}})},a.fun.enterGpedit=function(e){switch(e){case"open":t.go("home.gpedit.inside.api.default",{groupType:"open",strategyID:a.ajaxResponse.openGpeditInfo.strategyID,strategyName:a.ajaxResponse.openGpeditInfo.strategyName});break;case"common":t.go("home.gpedit.common.list",{groupType:"common"})}},a.$onInit=function(){e.$emit("$WindowTitleSet",{list:["访问策略"]}),a.component.menuObject={setting:{"class":"common-menu-fixed-seperate common-menu-lg",titleAuthority:"showTitle",title:"访问策略",secondTitle:"您可以给不同的调用方或应用设置访问策略,不同的访问策略可以设置不同的 API 访问权限、鉴权方式以及插件功能等"}},i.ajaxOpenGpedit()}}angular.module("eolinker").component("gpeditOverview",{templateUrl:"app/ui/content/gpedit/overview/index.html",controller:e}),e.$inject=["$scope","$state","GatewayResource"]}(),function(){"use strict";function e(e,t,n,a,i){var o=this;o.data={isEdit:!1,menu:"api"},o.ajaxResponse={alertInfo:{}},o.fun={},o.CONST={ALERT_METHOD_ARR:[{key:"API告警",value:"api",tip:"请求成功状态码在 [网关设置>基本设置] 页面设置,返回非成功状态码则视为请求失败;API的告警阀值在API编辑页面设置"}],ALERT_PROTOCOL_ARR:[{key:"不设置任何协议",value:0},{key:"SSL协议",value:1},{key:"TLS协议",value:2}],alertPeriodTypeQuery:[{key:"1分钟",value:0},{key:"5分钟",value:1},{key:"15分钟",value:2},{key:"30分钟",value:3},{key:"60分钟",value:4}]},o.service={authority:i};var r={alertInfo:{}},s={};o.fun.startAlert=function(){o.data.isEdit&&(o.ajaxResponse.alertInfo.alertStatus=o.ajaxResponse.alertInfo.alertStatus?0:1)},o.fun.changeNotice=function(e){e.$last&&o.ajaxResponse.alertInfo[o.data.menu+"AlertInfo"].userEmail.push({value:""})},o.fun.authorityToEdit=function(){o.data.isEdit=!0,o.ajaxResponse.alertInfo.apiAlertInfo.userEmail[o.ajaxResponse.alertInfo.apiAlertInfo.userEmail.length-1].value&&o.ajaxResponse.alertInfo.apiAlertInfo.userEmail.push({value:""})},o.fun.changeAlertMenu=function(e){o.data.menu=e},o.fun.deleteNotice=function(e){o.ajaxResponse.alertInfo[o.data.menu+"AlertInfo"].userEmail.splice(e.$index,1)},o.fun.checkIsValidEmail=function(e){return!/^[0-9A-Za-z-_.]+@[0-9a-z-]+\.[a-z]{2,20}(\.[a-z]{2,20}){0,1}$/.test(e)&&e},s.spliceUserEmailArr=function(e){var t=!0,n=!1,a=void 0;try{for(var i,r=e[Symbol.iterator]();!(t=(i=r.next()).done);t=!0){var s=i.value;o.ajaxResponse.alertInfo[s+"AlertInfo"].userEmail.length>1&&o.ajaxResponse.alertInfo[s+"AlertInfo"].userEmail.splice(o.ajaxResponse.alertInfo[s+"AlertInfo"].userEmail.length-1,1)}}catch(c){n=!0,a=c}finally{try{!t&&r["return"]&&r["return"]()}finally{if(n)throw a}}},s.setReceiverList=function(e){var t=[],n=!0,a=!1,i=void 0;try{for(var r,s=e[Symbol.iterator]();!(n=(r=s.next()).done);n=!0){var c=r.value;if(o.fun.checkIsValidEmail(c.value))return!1;c.value&&t.push(c.value)}}catch(l){a=!0,i=l}finally{try{!n&&s["return"]&&s["return"]()}finally{if(a)throw i}}return t.join(",")},o.fun.editAlert=function(){if(o.data.submitted=!0,a.ConfirmForm.$invalid)return void e.InfoModal("编辑失败,请检查信息是否填写完整!","error");var i={alertStatus:o.ajaxResponse.alertInfo.alertStatus,sender:o.ajaxResponse.alertInfo.sender,senderPassword:o.ajaxResponse.alertInfo.senderPassword,smtpAddress:o.ajaxResponse.alertInfo.smtpAddress,smtpPort:o.ajaxResponse.alertInfo.smtpPort,smtpProtocol:o.ajaxResponse.alertInfo.smtpProtocol,apiAlertInfo:angular.copy(o.ajaxResponse.alertInfo.apiAlertInfo)};return i.apiAlertInfo.receiverList=s.setReceiverList(i.apiAlertInfo.userEmail),i.apiAlertInfo.receiverList===!1?void e.InfoModal("编辑失败,请检查信息是否填写完整!","error"):(delete i.apiAlertInfo.userEmail,i.apiAlertInfo=JSON.stringify(i.apiAlertInfo),void n.Config.AlertEdit(i).$promise.then(function(n){switch(n.statusCode){case t.COMMON.SUCCESS:e.InfoModal("修改成功!","success"),o.data.isEdit=!1,s.spliceUserEmailArr(["api","node","redis"]),angular.copy(o.ajaxResponse.alertInfo,r.alertInfo)}}))},o.fun.cancleAlert=function(){o.data.isEdit=!1,o.data.userEmail=angular.copy(r.userEmail),o.ajaxResponse.alertInfo=angular.copy(r.alertInfo)},s.splitMailStr=function(e){var t=[];return e.split(",").map(function(e,n){t.push({value:e})}),t},o.$onInit=function(){n.Config.AlertInfo().$promise.then(function(e){switch(e.statusCode){case t.COMMON.SUCCESS:o.ajaxResponse.alertInfo=e.gatewayConfig||{alertStatus:0,sender:"",senderPassword:"",smtpAddress:"",smtpPort:"",smtpProtocol:0,apiAlertInfo:{alertPeriodType:0,receiverList:"",alertAddr:""}},o.ajaxResponse.alertInfo.apiAlertInfo.userEmail=s.splitMailStr(o.ajaxResponse.alertInfo.apiAlertInfo.receiverList),angular.copy(o.ajaxResponse.alertInfo,r.alertInfo)}})}}angular.module("eolinker").component("alertSetting",{templateUrl:"app/ui/content/alert/setting/index.html",controller:e}),e.$inject=["$rootScope","CODE","GatewayResource","$scope","Authority_CommonService"]}(),function(){"use strict";function e(e,t,n,a,i){var o=this;o.data={pagination:{maxSize:10,pageSize:50,page:0,msgCount:0}},o.ajaxResponse={query:[]},o.component={menuObject:{},listRequireObject:null},o.fun={};var r={},s={};o.service={authority:i},o.fun.init=function(){return r.initLoadAjax()},r.initLoadAjax=function(){var e={pageSize:o.data.pagination.pageSize,page:o.data.pagination.page+1},a=o.ajaxResponse.query||[];return s.isQuerying=!0,n.global.ajax.Query_AlertMessage=t.AlertMessage.Query(e),n.global.ajax.Query_AlertMessage.$promise.then(function(e){o.ajaxResponse.query=a.concat(e.alertMessageList||[]),o.data.pagination.msgCount=e.page.totalNum||0,o.data.pagination.page++,s.isQuerying=!1}),n.global.ajax.Query_AlertMessage.$promise},r.scrollLoading=function(){var e={hasItem:o.ajaxResponse.query&&0!==o.ajaxResponse.query.length,hasNextPage:o.data.pagination.page0?(i.data.hasParent=!0,i.data.query=s.getChildGroup(t)):i.data.wantToSelect=!1,r.resetGroup(t)},r.clearText=function(){i.data.q=""},i.fun.click=function(e){e.stopPropagation();var t={};try{t.point=e.target.classList[0]}catch(n){t.point="default"}switch(t.point){case"select-multistage-btn-clear-text":r.clearText();break;case"select-multistage-btn-close":i.data.wantToSelect=!1;break;case"select-multistage-btn-back":r.goToParent();break;case"select-multistage-btn-item":t.index=e.target.getAttribute("eo-attr-index"),t.query=[],i.data.query.map(function(e,n){i.fun.filter(e)&&t.query.push(e)}),r.clickGroup(t.query[t.index]);break;case"select-multistage-btn-item-span":t.index=e.target.parentNode.getAttribute("eo-attr-index"),t.query=[],i.data.query.map(function(e,n){i.fun.filter(e)&&t.query.push(e)}),r.clickGroup(t.query[t.index])}},r.initial=function(){(i.data.query||[]).length<=0||(o=l.groupCommon.fun.generalGroupInfo({list:i.data.query}),i.input[i.input.value]<=0?(c.initialObject.query=s.getChildGroup(0),c.initialObject.textList=l.groupCommon.fun.getGroupPath({currentGroupID:c.initialObject.query[0][i.input.value],groupInfo:o}),i.data.hasParent=!1,c.selectGroup=o.groupObj[c.initialObject.query[0][i.input.value]]):(c.initialObject.query=s.getBrotherGroup(i.input[i.input.value]),c.initialObject.textList=c.initialObject.textList=l.groupCommon.fun.getGroupPath({currentGroupID:i.input[i.input.value],groupInfo:o}),c.selectGroup=o.groupObj[i.input[i.input.value]],i.data.hasParent=!!c.selectGroup.parentGroupID),r.resetInitial())},r.resetInitial=function(){i.output={},i.data.query=angular.copy(c.initialObject.query),i.data.textList=angular.copy(c.initialObject.textList);var e="";for(var t in i.data.textList)e=e+(e?">":"")+i.data.textList[t][i.input.key];
-i.output["new"]=i.output.original={text:e,value:i.data.textList[i.data.textList.length-1][i.input.value]}},c.broadcast=t.$on("$ResetInitial_SelectMultistageCommonComponent",r.resetInitial),e.global.$watch.push(t.$watch("$ctrl.input.query",function(){i.input.query&&(i.data.query=i.input.query,r.initial())})),t.$on("$destroy",function(){c.broadcast()})}angular.module("eolinker").component("selectMultistageCommonComponent",{templateUrl:"app/component/common/select/multistage/index.html",bindings:{input:"<",disabled:"<",output:"="},controller:e}),e.$inject=["$rootScope","$scope","$document","Group_MultistageService"]}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(){"use strict";function indexController($scope,$state){var vm=this;vm.data={info:{sortForm:{containment:".group-form-ul",child:{containment:".child-group-form-ul"},grandson:{containment:".third-level-group-form-ul"}}},fun:{more:null,common:null}};var fun={};vm.data.fun.more=function(e){e.$event.stopPropagation(),e.item.listIsClick=!0},vm.data.fun.common=function(extend,arg){if(extend){var template={params:arg};switch(_typeof(extend.params)){case"string":return eval("extend.fun("+extend.params+")");default:for(var key in extend.params)null==extend.params[key]?template.params[key]=arg[key]:template.params[key]=extend.params[key];return extend.fun(template.params)}}},fun.show=function(){!vm.mainObject.showRouterList||vm.mainObject.showRouterList.indexOf($state.current.name)>-1?(vm.mainObject.baseFun.init&&vm.mainObject.baseFun.init(),vm.data.info.show=!0):vm.data.info.show=!1},vm.$onInit=function(){fun.show(),$scope.$on("$stateChangeSuccess",function(){fun.show()})}}angular.module("eolinker").component("groupCommonComponent",{templateUrl:"app/component/common/group/old/index.html",controller:indexController,bindings:{authorityObject:"<",funObject:"<",sortObject:"<",mainObject:"<",list:"<"}}),indexController.$inject=["$scope","$state"]}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(){"use strict";function indexController(){var vm=this;vm.data={selectAllMore:!1,listOrderBy:{}},vm.fun={};var fun={},privateFun={};fun.generateHtml=function(e,t){var n={html:""};switch(e){case"select":n.html='{{$ctrl.otherObject.batch.indexAddress[item."+vm.mainObject.item.primaryKey+"]?'':' '}} "}return n.html},vm.fun.showMore=function(e){var t={};try{t.point=e.$event.target.classList[0]}catch(n){t.point="default"}switch(t.point){case"more-btn":case"more-btn-icon":e.$event.stopPropagation(),e.item.clickMore=!e.item.clickMore}},vm.fun.autoSortFun=function(e){if(!(e.listItem.sort!==!0||vm.mainObject.setting.batch&&(vm.otherObject.batch.isOperating&&"open"!==vm.mainObject.setting.batchInitStatus||vm.otherObject.batchMenu&&vm.otherObject.batchMenu.isOperating))){var t={orderBy:e.item.sortOrderByVal};vm.data.listOrderBy.orderBy===e.item.sortOrderByVal?t.asc=0==e.item.asc?1:0:t.asc=e.item.asc;var n=vm.mainObject.baseFun.autoSortFun({listOrderBy:t});!n&&vm.mainObject.setting.sortStorageKey&&(vm.data.listOrderBy.orderBy===e.item.sortOrderByVal&&(e.item.asc=t.asc),vm.data.listOrderBy=t,window.localStorage.setItem(vm.mainObject.setting.sortStorageKey,angular.toJson(t)))}},privateFun.dragMouseup=function(e,t){vm.mainObject.setting.dragCacheObj[e]=t,window.localStorage.setItem(vm.mainObject.setting.dragCacheVar,JSON.stringify(vm.mainObject.setting.dragCacheObj))},vm.fun.range=function(e,t){return e=e||1,(!vm.list[t.$index+1]||(vm.list[t.$index+1].listDepth||0)<=(t.item.listDepth||0))&&e--,new Array(e)},fun.getTargetEvent=function(e,t){var n=e.getAttribute(t||"eo-attr-index");return n?e:fun.getTargetEvent(e.parentNode,t)},fun.getTargetIndex=function(e,t){var n=e.getAttribute(t||"eo-attr-index");return n?n:fun.getTargetIndex(e.parentNode,t)},fun.operateLevel=function(e,t,n){for(var a={operateName:angular.element(t).hasClass("ng-hide")?"removeClass":"addClass"},i=n,o=n;t&&e"+a.key+""}switch(vm.mainObject.setting.autoSort&&a.sort&&(vm.data.listOrderBy.orderBy===a.sortOrderByVal?a.asc=vm.data.listOrderBy.asc:a.asc="asc"===vm.mainObject.setting.sortDefaultVal.sortOrder?1:0),vm.mainObject.setting.draggable&&(a.draggableMainObject=Object.assign({},e,{mark:a.draggableCacheMark})),t.thItemHtml+='"+o+" \n "+(vm.mainObject.setting.autoSort&&a.sort?' ':"")+'\n
",n+=' ",a.type){case"depthHtml":vm.data.isDepth=!0,t.itemHtml+=' '+a.html+"
";break;default:t.itemHtml+='"+a.html+" \n")}})}vm.mainObject.item.operate&&(angular.forEach(vm.mainObject.item.operate.funArr,function(e,n){switch(e.type){case"more":angular.forEach(e.funArr,function(e,a){"html"==e.type?t.moreFunArrHtml+=e.html:t.moreFunArrHtml+='"+e.key+" "}),t.operateHtml+='{{$ctrl.mainObject.item.operate.funArr["+n+'].key}}
";break;case"html":t.operateHtml+=e.html;break;default:t.operateHtml+='",e.icon&&(t.operateHtml+=' '),t.operateHtml+=e.key+" "}}),t.operateHtml='"+t.operateHtml+"
");var s=(vm.mainObject.setting.batch?''+(vm.mainObject.setting.page?'\n
{{$ctrl.otherObject.batch.selectAll?"":" "}} \n
\n \n
':'
{{$ctrl.otherObject.batch.selectAll?"":" "}} ')+"
":"")+t.thItemHtml+''+(vm.mainObject.setting.operateThKey||"操作")+(" "+(vm.mainObject.setting.draggable?" ":"")),c=(vm.mainObject.setting.batch?' ':"")+n+(' '+(vm.mainObject.setting.draggable?" ":""));t.html=''+(t.itemHtml+t.operateHtml)+(vm.mainObject.setting.draggable?" ":"")+" ";try{t.html=t.html.replace("{{trExpression}}",vm.mainObject.setting.trExpression||""),t.html=t.html.replace("{{trNgClass}}",vm.mainObject.setting.trNgClass||"")}catch(l){}vm.data.tableHtml='"+(vm.mainObject.setting.page?'
\n
选择所有数据 (共{{$ctrl.pageObject.pageInfo.msgCount}}条) 选择可见数据 (共{{(($ctrl.pageObject.pageInfo.page*$ctrl.pageObject.pageInfo.pageSize+($ctrl.pageObject.pageInfo.extraOprNum||0))>$ctrl.pageObject.pageInfo.msgCount)?$ctrl.pageObject.pageInfo.msgCount:($ctrl.pageObject.pageInfo.pageSize*$ctrl.pageObject.pageInfo.page+($ctrl.pageObject.pageInfo.extraOprNum||0))}}条) \n
':"")+('
\n
':">")+(''+c+" ")+''+t.html+'
'+(vm.mainObject.setting.warning||"尚无任何内容")+"
"+(vm.mainObject.setting.defaultFoot?'
共{{$ctrl.list.length}}条记录
':"")+"
"+(vm.mainObject.setting.page?'':vm.mainObject.setting.fixFoot?'':"")+" "},fun.countItemSelectIsAll=function(e){if(e)if(vm.mainObject.setting.page){for(var t=!1,n=0;n-1&&a>t&&(t=a)}),t+2},privateFun.resetAfterChangeParentGroupID=function(e,t){e.parentGroupID!=t&&(groupInfo.groupObj[e.groupID].parentGroupID=t,0==t?(groupInfo.parentGroupPath[e.groupID]=[0],groupInfo.groupObj[e.groupID].groupDepth=1):(groupInfo.parentGroupPath[e.groupID]=[t].concat(groupInfo.parentGroupPath[t]),groupInfo.groupObj[e.groupID].groupDepth=groupInfo.groupObj[t].groupDepth+1),privateFun.resetChildGroup(e.groupID))},privateFun.isFatherGroupID=function(e){return 0!=e.child&&groupInfo.parentGroupPath[e.child].indexOf(e.parent)>-1},privateFun.spreed=function(e){vm.funObject.baseFun&&vm.funObject.baseFun.spreed?vm.funObject.baseFun.spreed(e):(e.list=vm.ajaxResponse.query,e.groupInfo=groupInfo,service.groupCommon.fun.spreed(e))},vm.fun.click=function(e){var t="";e=e||{};try{t=e.$event.target.classList[0]}catch(n){t="group"}switch(t){case"group-icon":e.item||(e.item=vm.ajaxResponse.query[$filter("findAttr")(e.$event.target,"data-index")]),privateFun.spreed(e);break;case"actural-group-box":break;default:if(!e.item){var a=$filter("findAttr")(e.$event.target,"data-index");e.item=vm.ajaxResponse.query[a],e.$index=a}var i=function(){service.groupCommon.generalFun.initGroupStatus({currentGroupID:e.item.groupID,groupInfo:groupInfo,list:vm.ajaxResponse.query})};vm.funObject.baseFun&&vm.funObject.baseFun.click?vm.funObject.baseFun.click(e,i):(vm.mainObject.baseInfo.current.groupID!=e.item.groupID&&($state.go($state.current.name,angular.merge({groupID:e.item.groupID},vm.requestObject?vm.requestObject.baseRequest:{})),vm.mainObject.baseInfo.current.groupID=e.item.groupID),i(),vm.funObject&&vm.funObject.clickCallback&&vm.funObject.clickCallback(e))}},vm.fun.sort=function(e){if(vm.mainObject.baseInfo.sort){e=e||{};var t={before:e.from.parentGroupID,after:null},n=angular.copy(groupInfo),a=e.from.groupID,i=e.to.groupID;if(!privateFun.isFatherGroupID({child:i,parent:a})){var o=groupInfo.locationArr.indexOf(a),r=groupInfo.locationArr.indexOf(i);switch(e.where){case"before":var s=service.groupCommon.generalFun.getNextNotChildGroup({currentGroupID:a,groupInfo:groupInfo}),c=s?groupInfo.locationArr.indexOf(s)-o:groupInfo.locationArr.length-o;if(o+c-1==r-1&&e.from.groupDepth==e.to.groupDepth)return;var l=privateFun.getDeepestGroupDepth(e.from.groupID);if(l+e.to.groupDepth-1>data.maxLevel)return void $rootScope.InfoModal("分组最多支持"+data.maxLevel+"级","error");t.after=e.to.parentGroupID;var u=groupInfo.locationArr.splice(o,c);r=groupInfo.locationArr.indexOf(i),u.forEach(function(e,t){groupInfo.locationArr.splice(r+t,0,e)}),groupInfo.childGroupPath[t.before].splice(groupInfo.childGroupPath[t.before].indexOf(a),1),groupInfo.childGroupPath[t.after].splice(groupInfo.childGroupPath[t.after].indexOf(i),0,a),privateFun.resetAfterChangeParentGroupID(e.from,t.after);break;case"in":var p=groupInfo.childGroupPath[t.before].indexOf(a)==groupInfo.childGroupPath[t.before].length-1;if(t.before==t.after&&p)return;var d=privateFun.getDeepestGroupDepth(e.from.groupID);if(d+e.to.groupDepth>data.maxLevel)return void $rootScope.InfoModal("分组最多支持"+data.maxLevel+"级","error");t.after=e.to.groupID;var m=service.groupCommon.generalFun.getNextNotChildGroup({currentGroupID:a,groupInfo:groupInfo}),f=m?groupInfo.locationArr.indexOf(m)-o:groupInfo.locationArr.length-o,h=groupInfo.locationArr.splice(o,f);groupInfo.childGroupPath[t.before].splice(groupInfo.childGroupPath[t.before].indexOf(a),1),r=service.groupCommon.generalFun.getGroupLastChildIndex({currentGroupID:t.after,groupInfo:groupInfo})+1,h.forEach(function(e,t){groupInfo.locationArr.splice(r+t,0,e)}),groupInfo.childGroupPath[t.after]=groupInfo.childGroupPath[t.after]||[],groupInfo.childGroupPath[t.after].push(a),privateFun.resetAfterChangeParentGroupID(e.from,t.after);break;case"after":if(o==r+1&&e.from.groupDepth==e.to.groupDepth)break;var g=privateFun.getDeepestGroupDepth(e.from.groupID);if(g+e.to.groupDepth-1>data.maxLevel)return void $rootScope.InfoModal("分组最多支持"+data.maxLevel+"级","error");t.after=e.to.parentGroupID;var v=service.groupCommon.generalFun.getNextNotChildGroup({currentGroupID:a,groupInfo:groupInfo});groupInfo.childGroupPath[t.before].splice(groupInfo.childGroupPath[t.before].indexOf(a),1);var b=v?groupInfo.locationArr.indexOf(v)-o:groupInfo.locationArr.length-o,$=groupInfo.locationArr.splice(o,b);r=groupInfo.locationArr.length,$.forEach(function(e,t){groupInfo.locationArr.splice(r+t,0,e)}),groupInfo.childGroupPath[t.after].push(a),privateFun.resetAfterChangeParentGroupID(e.from,t.after);break;default:return}service.groupCommon.generalFun.sortByLocationArr({list:vm.ajaxResponse.query,groupInfo:groupInfo});var y={groupOrder:null};y.groupOrder=[{parentGroupID:t.after,groupID:[a]}],t.after!=t.before&&y.groupOrder.push({parentGroupID:t.before}),angular.forEach(y.groupOrder,function(e){var t={};angular.forEach(groupInfo.childGroupPath[e.parentGroupID],function(e,n){t[e]=n}),e.groupOrder=t}),y.groupOrder=JSON.stringify(y.groupOrder),angular.merge(y,vm.requestObject.baseRequest),vm.requestObject.resource.Sort(y).$promise.then(function(a){switch(a.statusCode){case CODE.COMMON.SUCCESS:privateFun.reloadItem({parentGroupID:t,opGroup:e.from}),"in"==e.where&&service.groupCommon.generalFun.openGroup({currentGroupID:t.after,list:vm.ajaxResponse.query,groupInfo:groupInfo});break;default:$rootScope.InfoModal("排序失败,"+RESPONSE_TEXT.FAILURE,"error"),groupInfo=n,service.groupCommon.generalFun.resetGroupInfo(groupInfo),service.groupCommon.generalFun.sortByLocationArr({list:vm.ajaxResponse.query,groupInfo:groupInfo})}vm.service.cache.set(vm.ajaxResponse.query)})}}},privateFun.init=function(e){var t=angular.copy(vm.requestObject.baseRequest),n={response:null};vm.service.cache.clear(),data.requesting||(data.requesting=!0,$rootScope.global.ajax.Query_Group=vm.requestObject.resource.Query(t),$rootScope.global.ajax.Query_Group.$promise.then(function(e){switch(data.requesting=!1,e.statusCode){case CODE.COMMON.SUCCESS:vm.mainObject.baseInfo.queryName&&(e.groupList=e[vm.mainObject.baseInfo.queryName]),n.response=service.groupCommon.sort.init(e,vm.mainObject.baseInfo.current.groupID),vm.ajaxResponse.query=n.response.groupList,groupInfo=n.response.groupInfo,vm.funObject.callback&&vm.funObject.callback.querySuccess(vm.ajaxResponse.query)}}))},privateFun.edit=function(e,t){if("add-child"==e&&t.item.groupDepth>=data.maxLevel)return void $rootScope.InfoModal("分组最多支持"+data.maxLevel+"级","error");t=t||{};var n={title:("edit"==e?"编辑":"新建")+(t.item?"子分组":"分组"),data:"edit"==e?t.item:null,secondTitle:"分组名称"};$rootScope.GroupModal(n,function(a){a&&(angular.merge(a,vm.requestObject.baseRequest),"edit"==e?(a.groupID=t.item.groupID,$filter("Field_CommonFilter")("object",a,["$index"]),vm.requestObject.resource.Edit(a).$promise.then(function(e){switch(e.statusCode){case CODE.COMMON.SUCCESS:$rootScope.InfoModal(n.title+"成功!","success"),
-privateFun.init()}})):("add-child"==e&&(a.parentGroupID=t.item.groupID),$filter("Field_CommonFilter")("object",a,["$index","groupID"]),vm.requestObject.resource.Add(a).$promise.then(function(e){switch(e.statusCode){case CODE.COMMON.SUCCESS:$rootScope.InfoModal(n.title+"成功!","success"),privateFun.init()}})))})},privateFun["delete"]=function(e){e=e||{};var t=Object.assign({},{groupID:e.item.groupID},vm.requestObject.baseRequest),n=e.modal;$rootScope.EnsureModal(n.title,!1,n.message,{},function(n){n&&vm.requestObject.resource.Delete(t).$promise.then(function(t){switch(t.statusCode){case CODE.COMMON.SUCCESS:var n=privateFun.judgeItemRelation(e.item.groupID,vm.mainObject.baseInfo.current.groupID);service.groupCommon.fun.deleteGroup({currentGroup:e.item,list:vm.ajaxResponse.query,groupInfo:groupInfo}),vm.service.cache.set(vm.ajaxResponse.query),$rootScope.InfoModal("分组删除成功!","success"),e.callback?e.callback(e,angular.copy(t),{nowGroupWithDelteItemRelation:n}):$state.params.groupID==e.item.groupID?(vm.mainObject.baseInfo.current[vm.mainObject.baseInfo.id]=e.item.parentGroupID||-1,$state.go($state.current.name,angular.merge({groupID:e.item.parentGroupID||-1},vm.requestObject?vm.requestObject.baseRequest:{}))):privateFun.reloadItem({parentGroupID:{before:e.item.parentGroupID,after:0},opGroup:e.item});break;default:$rootScope.InfoModal("分组删除失败,"+RESPONSE_TEXT.FAILURE,"error")}})})},vm.fun.more=function(e){var t="";e.$event.stopPropagation(),e.item.listIsClick=!0,vm.data.listIsClick=!0;try{t=e.$event.target.classList[0]}catch(n){t="group"}switch(t){case"more-icon":break;case"active":break;default:var a=$filter("findAttr")(e.$event.target,"data-child-index");vm.fun.common(vm.mainObject.itemFun[a],e)}},vm.fun.common=function(extend,arg){if(extend){var tmpParam=arg||{};switch(extend.fun||(extend.fun=privateFun[extend.funName]),_typeof(extend.params)){case"string":return eval("extend.fun("+extend.params+")");default:for(var key in extend.params)null==extend.params[key]?tmpParam[key]=arg[key]:tmpParam[key]=extend.params[key];return extend.fun(tmpParam,privateFun.init)}}},vm.$onInit=function(){"modal"!=vm.mainObject.baseInfo.type&&(vm.service.cache.isShrink=!1),vm.mainObject.baseInfo.initGroupDepth=0==vm.mainObject.baseInfo.initGroupDepth?0:1,"cancelRequest"!=vm.mainObject.baseInfo.status&&privateFun.init()},privateFun.watchResetFlag=$scope.$watch("$ctrl.mainObject.baseInfo.resetFlag",function(){switch(vm.mainObject.baseInfo.status){case"cancelRequest":vm.ajaxResponse.query=vm.list,groupInfo=service.groupCommon.fun.generalGroupInfo({list:vm.ajaxResponse.query}),service.groupCommon.generalFun.initGroupStatus({currentGroupID:vm.mainObject.baseInfo.current.groupID,groupInfo:groupInfo,list:vm.ajaxResponse.query});break;default:vm.requestObject&&privateFun.init()}}),vm.$onDestroy=function(){privateFun.watchResetFlag()}}angular.module("eolinker").component("groupDefaultCommonComponent",{templateUrl:"app/component/common/group/default/index.html",controller:indexController,bindings:{list:"<",authorityObject:"<",funObject:"<",requestObject:"<",mainObject:"<"}}),indexController.$inject=["$scope","$rootScope","$state","$filter","Group_MultistageService","GroupService","CODE","RESPONSE_TEXT"]}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(){"use strict";function e(e){var t=this,n={editor:null,fun:{init:null}};n.fun.readOnly=function(){n.editor.setReadOnly(t.readOnly)},n.fun.render=function(){t.setVariable?n.editor.session.setValue(t.setModel[t.setVariable]||""):n.editor.session.setValue(t.setModel||"")},n.fun.initJavascriptConfig=function(){n.editor.session.setMode("ace/mode/javascript"),n.editor.setAutoScrollEditorIntoView(!0)},n.fun.autoCompleteCustom=function(e,t,n,a,i){var o={define:[{meta:"custom",caption:"eo.img",value:"eo.img",score:7},{meta:"custom",caption:"eo.file",value:"eo.file",score:7},{meta:"custom",caption:"eo.execute",value:"eo.execute",score:6},{meta:"custom",caption:"eo.stop",value:"eo.stop",score:5},{meta:"custom",caption:"eo.info",value:"eo.info",score:4},{meta:"custom",caption:"eo.md5",value:"eo.md5",score:3},{meta:"custom",caption:"eo.sha1",value:"eo.sha1",score:2},{meta:"custom",caption:"eo.sha256",value:"eo.sha256",score:1},{meta:"env",caption:"env.baseUrl",value:"env.baseUrl",score:1},{meta:"env",caption:"env.headers",value:"env.headers",score:1},{meta:"env",caption:"env.extraParams",value:"env.extraParams",score:1},{meta:"env",caption:"env.globalParams",value:"env.globalParams",score:1}]};return 0===a.length?i(null,[]):i(null,o.define)},t.$onInit=function(){switch(n.editor=ace.edit(t.id||"ace-editor-ams-component-js"),n.editor.setOptions({minLines:t.minLine||5,maxLines:30,enableLiveAutocompletion:!0}),n.editor.setShowPrintMargin(!1),n.editor.setTheme("ace/theme/monokai"),n.editor.getSession().on("change",function(a){t.setVariable?t.setModel[t.setVariable]=n.editor.getValue():t.setModel=n.editor.getValue(),e.$root&&e.$root.$$phase||e.$apply()}),t.type){case"javascript":n.fun.initJavascriptConfig();try{ace.require("ace/ext/language_tools")}catch(a){}break;case"automated-javascript":n.fun.initJavascriptConfig();try{ace.require("ace/ext/language_tools").addCompleter({getCompletions:n.fun.autoCompleteCustom})}catch(a){}break;default:n.editor.session.setMode("ace/mode/rust")}e.$on("$InsertText_AceEditorAms"+(t.id||""),function(e,t){n.editor.insert(t)}),e.$on("$Maunal_AceEditorAms"+(t.id||""),function(e,t){switch(_typeof(t||"")){case"object":n.editor.session.setValue(t.data||"");break;default:n.editor.session.setValue(t||"")}}),e.$on("$ResetAceEditor_AmsEditor"+(t.id||""),function(){n.editor.session.setValue("")})},e.$watch("$ctrl.watchModel",n.fun.render),e.$watch("$ctrl.readOnly",n.fun.readOnly),e.$on("$stateChangeStart",function(){n.editor&&n.editor.destroy()}),t.$onDestroy=function(){n.editor&&n.editor.destroy()}}angular.module("eolinker").component("aceEditorAmsComponent",{controller:e,template:'
',bindings:{setVariable:"<",setModel:"=",type:"@",watchModel:"<",readOnly:"<",id:"@",minLine:"@"}}),e.$inject=["$scope"]}(),function(){angular.module("eolinker").component("eoNavbar",{templateUrl:"app/ui/navbar/nav0/index.html"})}(),function(){function e(e,t,n,a,i,o,r){var s=this,c={},l={authority:i};s.service={navbar:r,sidebar:a},s.data={showLogout:/home/.test(t.current.name),userInfo:null},s.fun={},s.fun.changePassword=function(){o.Gateway_ChangePasswordModal()},s.fun.logout=function(){n.User.LoginOut().$promise.then(function(n){switch(n.statusCode){case e.COMMON.SUCCESS:s.service.navbar.info.navigation={},t.go("index")}})},c.init=function(){s.data.showLogout&&(o.global.ajax.Info_User=n.User.Info(),o.global.ajax.Info_User.$promise.then(function(e){s.service.navbar.userInfo=s.data.userInfo=e.userInfo,l.authority.fun.setPermission("default",e.userInfo||{userType:0})}))}()}angular.module("eolinker").component("eoNavbar1",{templateUrl:"app/ui/navbar/nav1/index.html",controller:e}),e.$inject=["CODE","$state","CommonResource","Sidebar_CommonService","Authority_CommonService","$rootScope","NavbarService"]}(),function(){angular.module("eolinker").config(["$stateProvider","RouteHelpersProvider",function(e,t){e.state("home.setting",{url:"/setting",template:"
"}).state("home.setting.log",{url:"/log",template:" "}).state("home.setting.basic",{url:"/",template:" "})}])}(),function(){"use strict";angular.module("eolinker").config(["$stateProvider","RouteHelpersProvider",function(e,t){e.state("home.plugin",{url:"/plugin",template:"
",containerRouter:!0}).state("home.plugin.default",{url:"/",template:" "}).state("home.plugin.operate",{url:"/operate/:status?pluginName",template:" ",resolve:t.resolveFor("ACE_EDITOR")})}])}(),function(){"use strict";angular.module("eolinker").config(["$stateProvider","RouteHelpersProvider",function(e,t){e.state("home.project",{url:"/project",template:"
",containerRouter:!0}).state("home.project.default",{url:"/",template:" "}).state("home.project.api",{url:"/api?projectID?projectName",template:" ",containerRouter:!0}).state("home.project.api.default",{url:"/?groupID",template:' ',needExtraNav:!0}).state("home.project.api.operate",{url:"/operate/:status?apiID?groupID",template:" ",needExtraNav:!0})}])}(),function(){"use strict";angular.module("eolinker").config(["$stateProvider","RouteHelpersProvider",function(e,t){e.state("home.monitor",{url:"/monitor",template:"
"}).state("home.monitor.global",{url:"/",template:" "})}])}(),function(){"use strict";function e(e,t,n,a,i,o){var r=this;r.data={submitted:!1,password:{isShow:!1}},r.ajaxRequest={loginCall:"",loginPassword:"",verifyCode:""},r.fun={},r.fun.confirm=function(){var e={loginCall:r.ajaxRequest.loginCall,loginPassword:i.createHash(r.ajaxRequest.loginPassword||"")};e.loginCall&&e.loginPassword?t.Guest.Login(e).$promise.then(function(t){switch(t.statusCode){case a.COMMON.SUCCESS:window.localStorage.setItem("LOGINCALL",e.loginCall),n.go("home.monitor.global")}}):r.data.submitted=!0},r.fun.changeView=function(){r.ajaxRequest.loginPassword&&(r.data.password.isShow=!r.data.password.isShow)}}angular.module("eolinker").config(["$stateProvider","RouteHelpersProvider",function(e,t){e.state("index",{url:"/",auth:!0,template:" "})}]).component("login",{templateUrl:"app/ui/content/login/index.html",controller:e}),e.$inject=["$scope","CommonResource","$state","CODE","md5","$rootScope"]}(),function(){"use strict";angular.module("eolinker").config(["$stateProvider","RouteHelpersProvider",function(e,t){e.state("home.cluster",{url:"/cluster",template:"
",containerRouter:!0}).state("home.cluster.default",{url:"/",template:" "}).state("home.cluster.node",{url:"/node?clusterName",template:" ",needExtraNav:!0}).state("home.cluster.node.default",{url:"/:cluster?groupID",template:' ',needExtraNav:!0})}])}(),function(){"use strict";angular.module("eolinker").config(["$stateProvider","RouteHelpersProvider",function(e,t){e.state("home.balance",{url:"/balance",template:"
",containerRouter:!0}).state("home.balance.service",{url:"/service",template:" "}).state("home.balance.list",{url:"/list",template:"
"}).state("home.balance.list.default",{url:"/",template:' '}).state("home.balance.list.operate",{url:"/:status?balanceName",template:' ',resolve:t.resolveFor("ACE_EDITOR")})}])}(),function(){"use strict";angular.module("eolinker").config(["$stateProvider","RouteHelpersProvider",function(e,t){e.state("home.gpedit",{url:"/gpedit",template:"
",containerRouter:!0}).state("home.gpedit.default",{url:"/overview",template:" "}).state("home.gpedit.common",{url:"/list",template:" "}).state("home.gpedit.common.list",{url:"/?groupID",template:' '}).state("home.gpedit.inside",{url:"/inside/:groupType?strategyID?groupID?strategyName",template:" ",containerRouter:!0}).state("home.gpedit.inside.setting",{url:"/setting",template:" "}).state("home.gpedit.inside.api",{url:"/api",template:"
",containerRouter:!0}).state("home.gpedit.inside.api.default",{url:"/",template:" "}).state("home.gpedit.inside.api.operate",{url:"/operate",template:" "}).state("home.gpedit.inside.api.plugin",{url:"/plugin/:apiID",template:" ",resolve:t.resolveFor("ACE_EDITOR")}).state("home.gpedit.inside.auth",{url:"/auth",template:" "}).state("home.gpedit.inside.plugin",{url:"/plugin",template:"
",containerRouter:!0}).state("home.gpedit.inside.plugin.gpedit",{url:"/gpedit",template:" ",sidebarIndex:1}).state("home.gpedit.inside.plugin.operate",{url:"/operate/:status?pluginName?chineseName",template:' ',resolve:t.resolveFor("ACE_EDITOR")})}])}(),function(){"use strict";angular.module("eolinker").config(["$stateProvider","RouteHelpersProvider",function(e,t){e.state("home.alert",{url:"/alert",template:"
",containerRouter:!0}).state("home.alert.list",{url:"/list",template:" "}).state("home.alert.setting",{url:"/",template:" "})}])}(),function(){"use strict";function e(e,t,n){n.Gateway_CopyApiModal=function(e,n){var a=t.open({animation:!0,templateUrl:"Gateway_CopyApiModal",controller:"Gateway_CopyApiModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.Gateway_GpeditApiPluginModal=function(e,n){var a=t.open({animation:!0,templateUrl:"Gateway_GpeditApiPluginModal",controller:"Gateway_GpeditApiPluginModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.Gateway_ServiceModal=function(e,n){var a=t.open({animation:!0,templateUrl:"Gateway_ServiceModal",controller:"Gateway_ServiceModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.MixInputModal=function(e,n){var a=t.open({animation:!0,templateUrl:"MixInputModal",controller:"MixInputModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.Gateway_NodeCheckErrorReportModal=function(e,n){var a=t.open({animation:!0,templateUrl:"Gateway_NodeCheckErrorReportModal",controller:"Gateway_NodeCheckErrorReportModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.Gateway_ChangePasswordModal=function(e,n){var a=t.open({animation:!0,templateUrl:"Gateway_ChangePasswordModal",controller:"Gateway_ChangePasswordModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.GatewayGpeditDefaultModal=function(e,n){var a=t.open({animation:!0,templateUrl:"GatewayGpeditDefaultModal",controller:"GatewayGpeditDefaultModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.GatewayClusterModal=function(e,n){var a=t.open({animation:!0,templateUrl:"GatewayClusterModal",controller:"GatewayClusterModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.ExportModal=function(e,n){var a=t.open({animation:!0,templateUrl:"ExportModal",controller:"ExportModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.CommonChangePasswordModal=function(e,n){var a=t.open({animation:!0,templateUrl:"CommonChangePasswordModal",controller:"CommonChangePasswordModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.ImportModal=function(e,n){var a=t.open({animation:!0,templateUrl:"ImportModal",controller:"ImportModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.Common_SingleInputModal=function(e,n){var a=t.open({animation:!0,templateUrl:"Common_SingleInputModal",controller:"Common_SingleInputModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.Common_LoginModal=function(e){var n=t.open({animation:!0,templateUrl:"Common_LoginModal",controller:"Common_LoginModalCtrl"});return n.result.then(e),n},n.RequestParamDetailModal=function(e,n){var a=t.open({animation:!0,templateUrl:"RequestParamDetailModal",controller:"RequestParamDetailModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.RequestParamEditModal=function(e,n){var a=t.open({animation:!0,templateUrl:"RequestParamEditModal",controller:"RequestParamEditModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.ResponseParamEditModal=function(e,n){var a=t.open({animation:!0,templateUrl:"ResponseParamEditModal",controller:"ResponseParamEditModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.ResponseParamDetailModal=function(e,n){var a=t.open({animation:!0,templateUrl:"ResponseParamDetailModal",controller:"ResponseParamDetailModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.ExpressionBuilderModal=function(e,n){var a=t.open({animation:!0,templateUrl:"ExpressionBuilderModal",controller:"ExpressionBuilderModalCtrl",resolve:{data:function(){return e}}});a.result.then(n)},n.InfoModal=function(e,n,a){var i=t.open({animation:!0,templateUrl:"InfoModal",controller:"InfoModalCtrl",displayClass:"modal-info-display",resolve:{info:function(){return e},type:function(){return n}}});i.result.then(a)},n.EnsureModal=function(e,n,a,i,o){var r=t.open({animation:!0,templateUrl:"EnsureModal",controller:"EnsureModalCtrl",resolve:{title:function(){return e},necessity:function(){return n},info:function(){return a},input:function(){return i}}});r.result.then(o)},n.GroupModal=function(e,n){var a=t.open({animation:!0,templateUrl:"GroupModal",controller:"GroupModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.SelectVisualGroupModal=function(e,n){var a=t.open({animation:!0,templateUrl:"SelectVisualGroupModal",controller:"SelectVisualGroupModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)},n.SingleSelectModal=function(e,n){var a=t.open({animation:!0,templateUrl:"SingleSelectModal",controller:"SingleSelectModalCtrl",resolve:{input:function(){return e}}});a.result.then(n)}}angular.module("eolinker.modal",["ui.bootstrap.modal"]).directive("eoModal",[function(){return{restrict:"AE",templateUrl:"app/modal/index.html",controller:e}}]),e.$inject=["$scope","$uibModal","$rootScope"]}(),function(){"use strict";function e(e,t,n,a,i,o){n.fun={},n.input=o,n.CONST={PROTOCOL_ARR:[{key:"HTTP",value:"http"},{key:"HTTPS",value:"https"}]},n.data={},n.component={pluginOprObj:{}};var r={};n.fun.cancel=function(){i.close(!1)},r.edit=function(e){var o=null;return o=t.Api.Copy(e.request).$promise,o.then(function(e){switch(e.statusCode){case a.COMMON.SUCCESS:i.close(!0);break;case"190005":n.data.requestMethod=!0,n.ConfirmForm.requestURL.$invalid=!0}}),o},r.confirm=function(){n.data.requestMethod=!1;var e={projectID:n.input.projectID,groupID:n.input.groupID,apiName:n.input.apiName,requestMethod:[],requestURL:n.input.requestURL,balanceName:n.input.balanceName,targetURL:n.input.targetURL,targetMethod:n.input.targetMethod,protocol:n.input.protocol,apiID:n.input.apiID};for(var t in n.input.requestMethodList)n.input.requestMethodList[t].checkbox&&e.requestMethod.push(n.input.requestMethodList[t].value);return e.requestMethod.length>0?e.requestMethod=e.requestMethod.join(","):n.data.requestMethod=!0,"-1"==n.input.targetMethod&&(e.isFollow=!0,delete e.targetMethod),e},n.fun.confirm=function(){var t=r.confirm(),a=null;return n.data.submitted=!0,n.ConfirmForm.$valid&&!n.data.requestMethod?a=r.edit({request:t}):e.InfoModal("API复制失败,请检查信息是否填写完整!","error"),a}}function t(e,t,n,a){t.fun={},t.input=a,t.component={pluginOprObj:{}},t.fun.cancel=function(){n.close(!1)},t.fun.confirm=function(){t.component.pluginOprObj.trigger="save"},e.global.$watch.push(t.$watch("component.pluginOprObj.accept",function(){switch(t.component.pluginOprObj.accept){case"saveSuccess":n.close(!0)}},!0))}function n(e,t,n,a,i,o,r){function s(){c.ajaxDriverQuery()}e.input={title:r.title,opr:r.opr},e.data={},e.CONST={SERVICE_TYPE_ARR:[{key:"静态服务",value:"static",tip:"IP地址在网关直接配置"},{key:"服务发现",value:"discovery",tip:"IP地址在网关通过服务发现的方式配置"}]},e.ajaxResponse=angular.copy(r.ajaxResponse),e.component={listBlockObj:{setting:{munalAddRow:!0},tdList:[{type:"text",thKey:"范围",modelKey:"title","class":"w_150"},{type:"input",thKey:"接入地址",modelKey:"value"}]}},e.fun={},e.fun.cancel=function(){o.close(!1)},e.fun.confirm=function(){if(e.data.submitted=!0,e.ConfirmForm.$invalid)return void n.InfoModal("请检查信息是否填写完整","error");var a={name:e.ajaxResponse.serviceData.name};"static"===e.ajaxResponse.serviceData.type?a.driver="static":(a.driver=e.ajaxResponse.serviceData.driver,a.config=e.ajaxResponse.serviceData.config,a.clusterConfig={},e.ajaxResponse.clusterQuery.map(function(e){a.clusterConfig[e.name]=e.value}),a.clusterConfig=JSON.stringify(a.clusterConfig));var s=i.ServiceDiscovery[r.opr](a).$promise;return s.then(function(e){switch(e.statusCode){case t.COMMON.SUCCESS:n.InfoModal(r.title+"成功","success"),o.close(!0)}}),s};var c={},l={cache:a};c.ajaxDriverQuery=function(){var t=l.cache.get("EO_GOKU_DRIVER_LIST");t?e.ajaxResponse.driverQuery=t:i.ServiceDiscovery.DriverQuery().$promise.then(function(t){e.ajaxResponse.driverQuery=t.data||[],l.cache.set(e.ajaxResponse.driverQuery,"EO_GOKU_DRIVER_LIST")})},s()}function a(e,t,n){e.input=n,e.fun={},e.fun.cancel=function(){t.close(!1)}}function i(e,t,n,a,i,o,r){t.data={input:{},interaction:{request:{oldPassword:"",newPassword:""}},fun:{confirm:null}},t.data.fun.confirm=function(){var r={request:{oldPassword:e.createHash(t.data.interaction.request.oldPassword),newPassword:e.createHash(t.data.interaction.request.newPassword)}};t.editForm.$valid&&i.User.ChangePassword(r.request).$promise.then(function(e){switch(e.statusCode){case o.COMMON.SUCCESS:a.InfoModal("修改成功","success"),n.close(!0)}})},t.cancel=function(){n.close(!1)}}function o(e,t,n){e.data={title:n.title,group:n.group},e.output=angular.copy(n.item),e.fun={},e.fun.confirm=function(){e.ConfirmForm.$valid&&t.close(e.output)},e.fun.cancel=function(){t.close(!1)}}function r(e,t,n){e.data={title:n.title,group:n.group,checkStatus:"init"},e.output=angular.copy(n.item),e.fun={},e.fun.confirm=function(){e.ConfirmForm.$valid&&t.close(e.output)},e.fun.cancel=function(){t.close(!1)}}angular.module("eolinker.modal").directive("eoGatewayModal",[function(){return{restrict:"AE",templateUrl:"app/modal/branch/gateway/index.html"}}]).controller("Gateway_ServiceModalCtrl",n).controller("Gateway_NodeCheckErrorReportModalCtrl",a).controller("GatewayClusterModalCtrl",r).controller("GatewayGpeditDefaultModalCtrl",o).controller("Gateway_ChangePasswordModalCtrl",i).controller("Gateway_GpeditApiPluginModalCtrl",t).controller("Gateway_CopyApiModalCtrl",e),e.$inject=["$rootScope","GatewayResource","$scope","CODE","$uibModalInstance","input"],t.$inject=["$rootScope","$scope","$uibModalInstance","input"],n.$inject=["$scope","CODE","$rootScope","Cache_CommonService","GatewayResource","$uibModalInstance","input"],a.$inject=["$scope","$uibModalInstance","input"],i.$inject=["md5","$scope","$uibModalInstance","$rootScope","CommonResource","CODE","input"],o.$inject=["$scope","$uibModalInstance","input"],r.$inject=["$scope","$uibModalInstance","input"]}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(){"use strict";function indexController(){var vm=this;vm.fun={},vm.fun.common=function(extend,arg){var tmpParam={};switch(_typeof(extend.params)){case"string":return eval("extend.fun("+extend.params+")");default:for(var key in extend.params)null==extend.params[key]?tmpParam[key]=arg[key]:tmpParam[key]=extend.params[key];return extend.fun(tmpParam)}}}angular.module("eolinker").component("overviewProductComponent",{templateUrl:"app/component/product/overview/index.html",controller:indexController,bindings:{listAuthorityObject:"<",authorityObject:"<",mainObject:"<",otherObject:"<"}}),indexController.$inject=[]}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(){"use strict";function e(e,t,n,a,i,o){e.input=o,e.fun={},e.data={submitted:!1,admin:"",datePickerObject:{request:{startTime:o.datePickerObject&&o.datePickerObject.startTime?new Date(o.datePickerObject.startTime):"",endTime:o.datePickerObject&&o.datePickerObject.endTime?new Date(o.datePickerObject.endTime):""},show:!1}},e.component={selectPersonCommonComponentObject:{}};var r={singleTextObject:angular.copy(o.singleTextObject)},s={};e.fun.showSearchList=function(t){t.stopPropagation(),e.data.showSearchList=!e.data.showSearchList},e.fun.searchMemberList=function(t,n){n.stopPropagation(),e.data.showSearchList=!0,e.input.singleTextObject.selectOptions=[],r.singleTextObject.selectOptions.map(function(n,a){s.filterMemberList(n,t)&&e.input.singleTextObject.selectOptions.push(n)})},e.fun.datePickerSelect=function(t){e.data.datePickerObject.request.startTime?e.data.datePickerObject.request.endTime?o.datePickerObject.notSameDay&&e.data.datePickerObject.request.startTime.getTime()==e.data.datePickerObject.request.endTime.getTime()?(n.InfoModal("开始和结束日期不能是同一天,请重新选择!","error"),e.data.datePickerObject.request.endTime=""):(t&&t.$event.stopPropagation(),e.data.datePickerObject.show=!1):n.InfoModal("请选择"+e.input.datePickerObject.title+"结束日期","error"):n.InfoModal("请选择"+e.input.datePickerObject.title+"开始日期","error")},s.filterMemberList=function(e,t){return(e.inviteCall||"").indexOf(t)>-1||(e.memberNickName||"").indexOf(t)>-1||(e.userNickName||"").indexOf(t)>-1},e.fun.confirm=function(){var r={request:angular.copy(o.request||{}),promise:null};if(e.data.submitted=!0,e.ConfirmForm.$valid){if(o.textArray.map(function(e,t){r.request[e.key]=e.value}),o.datePickerObject){if(!e.data.datePickerObject.request.startTime)return void n.InfoModal("请选择"+e.input.datePickerObject.title+"开始日期","error");if(!e.data.datePickerObject.request.endTime)return void n.InfoModal("请选择"+e.input.datePickerObject.title+"结束日期","error");if(o.datePickerObject.notSameDay&&e.data.datePickerObject.request.startTime.getTime()==e.data.datePickerObject.request.endTime.getTime())return n.InfoModal("开始和结束日期不能是同一天,请重新选择!","error"),void(e.data.datePickerObject.request.endTime="");r.request.startTime=i.filter(e.data.datePickerObject.request.startTime,"yyyy-M!-dd"),r.request.endTime=i.filter(e.data.datePickerObject.request.endTime,"yyyy-M!-dd")}if(o.singleTextObject&&e.component.selectPersonCommonComponentObject.value&&(r.request[o.singleTextObject.key]=e.component.selectPersonCommonComponentObject.value),o.ensure)n.EnsureModal(o.ensureInfo.title,o.ensureInfo.necessity,o.ensureInfo.info,o.ensureInfo.input||{},function(e){if(e){if(!o.resource)return void t.close(Object.assign({},r.request));r.promise=o.resource(r.request).$promise,r.promise.then(function(e){switch(e.statusCode){case a.COMMON.SUCCESS:t.close(Object.assign({},r.request,e))}})}});else{if(o.promiseFun){if(r.promise=o.promiseFun(Object.assign({},r.request)),!r.promise)return}else{if(!o.resource)return void t.close(Object.assign({},r.request));r.promise=o.resource(r.request).$promise}r.promise.then(function(e){switch(e.statusCode){case a.COMMON.SUCCESS:t.close(Object.assign({},r.request,e))}})}}return r.promise},e.fun.cancel=function(){t.close(!1)}}function t(e,t,n,a,i,o){e.info={projectHashKey:o.params.projectHashKey},e.data={exportType:0,granularityList:[{name:"天",active:0},{name:"小时",active:1}],granularity:0},e.input=i,e.fun={};var r={};e.fun.changeMenu=function(t,n){switch(t){case"granularity":e.data.granularity=n.item.active}},r.response=function(a){switch(a.response.statusCode){case n.COMMON.SUCCESS:e.$broadcast("$DumpDirective_Click_"+a["switch"].toString(),{response:a.response,fileName:e.input.fileName,window:a.window}),t.close(!0);break;default:a.window&&a.window.close()}},e.fun.dumpDirective=function(t){var n={promise:null,request:i.request,window:null};return n.request.granularity=e.data.granularity,n.request.fileType="excel",n.promise=i.resource.Download(n.request).$promise,n.promise.then(function(e){r.response({response:e,"switch":"export-by-one-key",window:n.window})}),n.promise},e.fun.cancel=function(){t.close(!1)}}function n(e,t,n){e.data={input:{},fun:{cancel:null,confirm:null}};var a={fun:{init:null}};e.data.fun.confirm=function(){e.editForm.$invalid||e.data.input.inputObject.confirmNewPassword!=e.data.input.inputObject.key||t.close({key:e.data.input.inputObject.key})},e.data.fun.cancel=function(){t.close(!1)},a.fun.init=function(){angular.copy(n,e.data.input)}()}function a(e,t,n){e.data={title:n.title,query:n.query,position:n.position},e.output={$index:"0"},e.ok=function(){t.close(e.output)},e.cancel=function(){t.close(!1)}}function i(e,t,n,a,i,o){e.title=o.title,e.secondTitle=o.secondTitle||"分组名称",e.modalType=o.modalType,e.data={initialGroupData:[],apiGroup:null},e.interaction={request:{}},e.fun={};var r={},s={groupCommon:i},c={};e.fun.initGroup=function(){var t={promise:null,groupList:[]};return t.promise=o.resource(o.request).$promise,t.promise.then(function(n){if(n.groupList.unshift({groupID:0,parentGroupID:-1,groupName:"根目录",groupDepth:0}),e.interaction.request.groupID=0,t.response=s.groupCommon.sort.init(n,0,{initGroupDepth:0}),c=t.response.groupInfo,o.item.groupID)switch(_typeof(o.item.groupID)){case"object":angular.copy(o.item.groupID).map(function(e,n){s.groupCommon.fun.deleteGroup({currentGroup:c.groupObj[e],list:t.response.groupList,groupInfo:c})});break;default:s.groupCommon.fun.deleteGroup({currentGroup:c.groupObj[o.item.groupID],list:t.response.groupList,groupInfo:c})}e.list=t.response.groupList,e.component.groupCommonObject.mainObject.baseInfo.resetFlag=!e.component.groupCommonObject.mainObject.baseInfo.resetFlag}),t.promise},r.click=function(t){e.interaction.request.groupID=t.item.groupID,e.interaction.request.groupName=t.item.groupName,s.groupCommon.generalFun.initGroupStatus({currentGroupID:t.item.groupID,initGroupDepth:"projectGroup"==o.modalType?0:1,groupInfo:c,list:e.list})},r.init=function(){o.staticQuery=o.staticQuery||[],e.list=o.list||[],o.current=o.current||{},e.component={groupCommonObject:{funObject:{unTop:!0,baseFun:{click:r.click}},mainObject:{baseInfo:{initGroupDepth:"projectGroup"==o.modalType?0:1,status:"cancelRequest",name:"groupName",id:"groupID",current:e.interaction.request,hasIcon:o.hasIcon},staticQuery:o.staticQuery||[]}}},"projectGroup"!=o.modalType&&(o.staticQuery.length?e.interaction.request.groupID=o.current.groupID||o.staticQuery[0].groupID:e.interaction.request.groupID=o.current.groupID>0?o.current.groupID:o.list[0].groupID,c=s.groupCommon.fun.generalGroupInfo({list:e.list}),e.interaction.request.groupID>0&&(e.interaction.request.groupName=c.groupObj[e.interaction.request.groupID].groupName))}(),e.fun.confirm=function(){t.close({groupID:e.interaction.request.groupID,groupName:e.interaction.request.groupName,groupInfo:c})},e.fun.cancel=function(){t.close(!1)}}function o(e,t,n,a,i){e.data={title:i.title},e.fun={},e.fun.getFile=function(t){e.$broadcast("$Init_LoadingCommonComponent",{file:t.$file[0]})},e.fun["import"]=function(e){var a={request:new FormData,promise:null};for(var o in i.request)a.request.append(o,i.request[o]);return a.request.append("file",e.file),a.promise=i.resource(a.request).$promise,a.promise.then(function(e){switch(e.statusCode){case n.COMMON.SUCCESS:t.close(!0)}}),a.promise},e.fun.cancel=function(){t.close(!1)}}function r(e,t,n){e.data={input:angular.copy(n)},e.fun={},e.fun.ok=function(){e.editGroupForm.$invalid||t.close({text:e.data.input.text})},e.fun.cancel=function(){t.close(!1)}}function s(e,t,n,a,i,o){e.data={info:{submitted:!1},interaction:{request:{loginCall:"",loginPassword:""}},fun:{close:null,confirm:null}};e.data.fun.close=function(){o.close(!1)},e.data.fun.confirm=function(){var r={request:{loginCall:e.data.interaction.request.loginCall,loginPassword:a.createHash(e.data.interaction.request.loginPassword)}};e.confirmForm.$valid?(e.data.info.submitted=!1,
-n.global.ajax.Login_Guest=i.Guest.Login(r.request),n.global.ajax.Login_Guest.$promise.then(function(e){switch(e.statusCode){case t.COMMON.SUCCESS:o.close({loginCall:r.request.loginCall})}})):e.data.info.submitted=!0}}function c(e,t,n,a,i,o){e.title=n,e.necessity=a,e.info={message:i||"此操作无法恢复,确认操作?",btnType:o.btnType||0,btnMessage:o.btnMessage||"删除",btnGroup:o.btnGroup||[],hideDefaultBtn:o.hideDefaultBtn,timer:{limit:o.timeLimit,value:o.timeLimit/1e3,fun:null},btnCancelMessage:o.btnCancelMessage||"取消"},e.fun={};var r={fun:{init:null}};e.data={input:{}},r.fun.init=function(){angular.copy(o,e.data.input),3==e.info.btnType&&(e.info.timer.fun=setInterval(function(){0==e.info.timer&&clearInterval(e.info.timer.fun),e.info.timer.value--,e.$root&&e.$root.$$phase||e.$apply()},1e3))}(),e.fun.btnClick=function(e){e.confirm(),t.close(!1)},e.ok=function(){e.sureForm.$valid||!e.necessity?t.close(!0):e.submited=!0},e.cancel=function(){clearInterval(e.info.timer.fun),t.close(!1)}}function l(e,t,n,a,i){e.type=i||"info",e.info=a;var o=n(function(){t.close(!0)},1500,!0);e.$on("$destroy",function(){o&&n.cancel(o)})}function u(e,t,n){e.title=n.title,e.placeholder=n.placeholder||"1~32位字符串",e.secondTitle=n.secondTitle||"分组",e.required=!n.hasOwnProperty("required")||n.required,e.info={groupName:"",groupID:"",$index:"0",isAdd:!0},e.params={query:[{groupName:"--不设置一级分组--",groupID:"0"}].concat(n.group),status:n.status||"first-level"},e.fun={},e.fun.change=function(t){if(t||(e.info.parentGroupID="0"),"0"==e.info.grandParentGroupID)return void(e.params.secondLevelQuery=[{groupName:"--不设置二级分组--",groupID:"0"}]);for(var a in n.group)n.group[a].groupID==e.info.grandParentGroupID&&(e.params.secondLevelQuery=[{groupName:"--不设置二级分组--",groupID:"0"}].concat(n.group[a].childGroupList))};(function(){switch(n.data&&(e.info={groupName:n.data.groupName,groupID:n.data.groupID,isAdd:!1}),angular.merge(e.info,n.parentObject),n.status){case"third-level":e.fun.change(!0)}})();e.ok=function(){e.editGroupForm.$valid?t.close(e.info):e.submited=!0},e.cancel=function(){t.close(!1)}}function p(e,t,n,a,i){function o(){a&&(e.info={databaseHashKey:i,tableID:a.tableID,tableName:a.tableName,tableDesc:a.tableDesc,isAdd:!1})}e.title=n,e.info={databaseHashKey:i,tableID:"",tableName:"",tableDesc:"",isAdd:!0},o(),e.ok=function(){e.editTableForm.$valid?t.close(e.info):e.submited=!0},e.cancel=function(){t.close(!1)}}angular.module("eolinker.modal").directive("eoCommonModal",[function(){return{restrict:"AE",templateUrl:"app/modal/branch/common/index.html"}}]).controller("Common_LoginModalCtrl",s).controller("Common_SingleInputModalCtrl",r).controller("InfoModalCtrl",l).controller("EnsureModalCtrl",c).controller("GroupModalCtrl",u).controller("TableModalCtrl",p).controller("ImportModalCtrl",o).controller("SelectVisualGroupModalCtrl",i).controller("SingleSelectModalCtrl",a).controller("CommonChangePasswordModalCtrl",n).controller("ExportModalCtrl",t).controller("MixInputModalCtrl",e),e.$inject=["$scope","$uibModalInstance","$rootScope","CODE","uibDateParser","input"],t.$inject=["$scope","$uibModalInstance","CODE","$rootScope","input","$state"],n.$inject=["$scope","$uibModalInstance","input"],a.$inject=["$scope","$uibModalInstance","input"],i.$inject=["$scope","$uibModalInstance","$state","GroupService","Group_MultistageService","input"],o.$inject=["$scope","$uibModalInstance","CODE","$rootScope","input"],r.$inject=["$scope","$uibModalInstance","input"],s.$inject=["$scope","CODE","$rootScope","md5","CommonResource","$uibModalInstance"],c.$inject=["$scope","$uibModalInstance","title","necessity","info","input"],l.$inject=["$scope","$uibModalInstance","$timeout","info","type"],u.$inject=["$scope","$uibModalInstance","input"],p.$inject=["$scope","$uibModalInstance","title","info","databaseHashKey"]}(),function(){"use strict";function e(){var e={};try{e.isShrink=JSON.parse(window.localStorage.getItem("EO_CONFIG_SIDEBAR_SHRINK_STATUS"))||!1}catch(t){e.isShrink=!1}return e}angular.module("eolinker").factory("Sidebar_CommonService",e),e.$inject=[]}(),function(){"use strict";function e(e,t,n,a){var i=this;i.data={current:null,itemSpreedObject:{}},i.fun={},i.service={"default":n,sidebar:a},i.fun.initMenu=function(e){if(t.current.name===e.item.sref||t.current.name.indexOf(e.item.sref+".")>-1){if(i.data.current=e.item,e.item.childList&&e.item.childList.length>0&&(i.data.itemSpreedObject[e.item.sref]=1),i.mainObject.baseInfo.unNav||e.item.unNav)return void(i.service["default"].info.navigation={});if(e.item.childList){i.service["default"].info.navigation={query:i.mainObject.baseInfo.navigation||[{name:e.item.name}]};for(var n=0;n-1||t.current.name.indexOf(a.otherSref)>-1){i.service["default"].info.navigation.current=a.name;break}}}else i.service["default"].info.navigation.query=i.mainObject.baseInfo.navigation||null,i.service["default"].info.navigation.current=e.item.name}},i.fun.clickMenu=function(e,n,a){if(n.click){var o=n.click({item:n});if(o===!0)return}if("text"!=n.mark&&(window.sessionStorage.removeItem("COMMON_SEARCH_TIP"),"disabled"!=n.permissionKey||i.permissionObject[n.permission].disabled!=n.permissionValue)){if(a)i.service["default"].info.navigation={query:i.mainObject.baseInfo.navigation||[{name:a.name}],current:n.name};else if(n.childList&&n.childList.length>0)return void(1==i.data.itemSpreedObject[n.sref]?delete i.data.itemSpreedObject[n.sref]:i.data.itemSpreedObject[n.sref]=1);if(i.data.current=a||n,i.mainObject.baseInfo.unNav)i.service["default"].info.navigation={};else if(n.childList)i.service["default"].info.navigation={query:i.mainObject.baseInfo.navigation||[{name:n.name}],current:n.childList[0].name};else switch(e){case"child":i.service["default"].info.navigation.current=n.name;break;default:i.service["default"].info.navigation={query:i.mainObject.baseInfo.navigation||null,current:n.name}}n.childSref?n.otherChildSref&&t.params.spaceKey?t.go(n.otherChildSref,n.otherParams):t.go(n.childSref,n.params):n.sref&&t.go(n.sref,n.params)}},e.$on("$stateChangeSuccess",function(){if(i.data.current&&t.current.name.indexOf(i.data.current.sref)===-1&&t.current.sidebarIndex){for(var e=0,n=0;n-1){e=n;break}}i.fun.initMenu({item:i.mainObject.baseInfo.menu[e]})}if(t.current.navName)try{i.service["default"].info.navigation.current=t.current.navName}catch(o){}t.current.needExtraNav||(i.service["default"].info.navigation.extra=null)}),i.fun.shrinkSidebar=function(){i.service.sidebar.isShrink=!i.service.sidebar.isShrink,window.localStorage.setItem("EO_CONFIG_SIDEBAR_SHRINK_STATUS",i.service.sidebar.isShrink)},e.$on("$HomeProjectInsideSidebarShrink",function(){i.service.sidebar.isShrink=!0,e.$root&&e.$root.$$phase||e.$apply()}),e.$on("$ResetSidebarActiveStatus_SidebarComponent",function(e,t){i.fun.initMenu({item:i.mainObject.baseInfo.menu[t]})})}angular.module("eolinker").component("sidebarCommonComponent",{templateUrl:"app/component/common/sidebar/index.html",controller:e,bindings:{mainObject:"<",powerObject:"<",permissionObject:"<"}}),e.$inject=["$scope","$state","NavbarService","Sidebar_CommonService"]}(),function(){"use strict";function e(e,t,n){var a=this;a.data={balance:{general:{title:"注意事项",titleStyle:{"float":"none"},"class":"warning-ul common-ul",content:'1. 静态后端支持:IP+端口或域名,如:127.0.0.1:8080 或 www.eolinker.com 权重范围:0-999 2. 静态IP列表,IP与权重之间使用空格分隔,多个IP之间使用英文分号分隔,例如:127.1.1.1:8080 10; 3. 若IP不加权重,则默认该IP权重为1。例如:“ip1:1111 ; ip2:2222 10” ,这里的ip1权重为1,ip2权重为10
'}},plug:{general:{title:"注意事项",titleStyle:{"float":"none"},"class":"warning-ul common-ul",content:'1. 如需让自定义的插件生效,必须先重启/重载网关。
2. 检测插件仅针对自定义插件,用于检测该自定义插件是否可用 '},operate:{title:"温馨提示","class":"warning-ul common-ul",content:"新增自定义插件后,请立即对该插件进行检测,确保插件可用后再重载或重启网关节点,以使插件生效 "},official:{title:"温馨提示","class":"warning-ul common-ul",content:"若要使网关类型插件的最新配置生效,保存后须 重载/重启 网关节点 "}},gepditAuth:{general:{title:"温馨提示","class":"warning-ul common-ul",content:'尚未对访问策略设置鉴权方式,请在 策略插件 处添加相应的鉴权插件'}},alertConfig:{general:{title:"告警提示","class":"warning-ul common-ul",content:"返回非成功状态码则视为请求失败;API的告警阀值在API编辑页面设置 "}},authorityConfig:{general:{title:"权限提示","class":"warning-ul common-ul",content:"系统管理员以及管理员用户拥有最高读写操作权限,因此不会出现在权限管理的列表中,列表仅会列出普通成员 "}}},a.service={$window:t}}angular.module("eolinker").component("tipCommonComponent",{templateUrl:"app/component/common/tip/index.html",controller:e,bindings:{version:"@",status:"@",user:"@",interaction:"<"}}),e.$inject=["$scope","$window","$state"]}(),function(){"use strict";function e(e,t){var n=this,a={fun:{$Destory:null,dataProcessing:null,$LoadingInit:null},info:{broadcast:null}};n.data={info:{isEnd:!0}},a.fun.dataProcessing=function(e){n.data.info.isEnd=!1;var t={promise:n.fun({arg:e})};t.promise?t.promise["finally"](function(){n.data.info.isEnd=!0,n.data.tips=null}):(n.data.info.isEnd=!0,n.data.tips=null)},a.fun.$LoadingInit=function(e,t){t=t,n.data.tips=t?t.tips:"载入",a.fun.dataProcessing(t)},a.fun.$Destory=function(){a.info.broadcast()},n.$onInit=function(t){n.interaction=n.interaction||{request:{},response:{}},n.interaction.request.delay||a.fun.dataProcessing(t),a.info.broadcast=e.$on("$Init_LoadingCommonComponent",a.fun.$LoadingInit),e.$on("$destroy",a.fun.$Destory)}}angular.module("eolinker").component("loadingCommonComponent",{template:'
正在{{$ctrl.data.tips||"载入"}} ',controller:e,bindings:{fun:"&",interaction:"<"}}),e.$inject=["$scope","$state"]}(),function(){"use strict";function e(e,t){var n=this,a={info:{templet:{button:' {{$ctrl.data.info.clipboard.text}} ',input:'{{$ctrl.data.info.clipboard.text}} ',textarea:'{{$ctrl.data.info.clipboard.text}} '},clipboard:null},fun:{init:null,reset:null,$destory:null}};n.data={info:{html:null,clipboard:{isClick:!1,success:!1,text:n.buttonHtml||"点击复制"}},fun:{click:null}},a.fun.reset=function(i){a.info.clipboard=new Clipboard(i["class"]),a.info.clipboard.on("success",function(a){n.data.info.clipboard.success=!0,n.data.info.clipboard.isClick=!0,n.isPopup?e.InfoModal("已复制到剪贴板","success"):n.data.info.clipboard.text="复制成功",t.$root&&t.$root.$$phase||t.$apply(),a.clearSelection()}),a.info.clipboard.on("error",function(a){n.data.info.clipboard.success=!1,n.data.info.clipboard.isClick=!0,n.isPopup?e.InfoModal("复制到剪贴板失败","error"):n.data.info.clipboard.text="复制失败",t.$root&&t.$root.$$phase||t.$apply()})},n.data.fun.click=function(){n.data.info.clipboard.isClick=!1},a.fun.$destroy=function(){a.info.clipboard.destroy()},n.$onInit=function(){switch(n.switchTemplet){case"0":n.data.info.html=a.info.templet.button;break;case"1":n.data.info.html=a.info.templet.input;break;case"2":n.data.info.html=a.info.templet.textarea;break;default:n.data.info.html=a.info.templet.input}t.$on("$destroy",a.fun.$destroy),a.fun.reset({"class":".copy-common-component-"+t.$id})}}angular.module("eolinker").component("copyCommonComponent",{template:' ',bindings:{copyModel:"<",buttonHtml:"@",isPopup:"@",switchTemplet:"@"},controller:e}),e.$inject=["$rootScope","$scope"]}(),function(){"use strict";angular.module("eolinker.directive",[])}(),function(){"use strict";angular.module("eolinker.directive").directive("watchDomCommonDirective",[function(){return{restrict:"A",scope:{bindId:"@",watchDomCommonDirective:"&"},link:function(e,t,n,a){var i={elem:document.getElementById(e.bindId),fun:{init:null}};i.fun.DOMSubtreeModified=function(){e.watchDomCommonDirective({input:i.elem.innerText})},i.fun.init=function(){angular.element(i.elem).bind("DOMSubtreeModified",i.fun.DOMSubtreeModified)}()}}}])}(),function(e,t){"use strict";function n(e){if(!("clientX"in e||"clientY"in e)){var t=e.touches||e.originalEvent.touches;t&&t.length&&(e.clientX=t[0].clientX,e.clientY=t[0].clientY),e.preventDefault()}}function a(e){if(e=e[0],e.previousElementSibling)return t.element(e.previousElementSibling);for(var n=e.previousSibling;null!=n&&1!=n.nodeType;)n=n.previousSibling;return t.element(n)}function i(e,t){var n=a(e);n.length>0?n.after(t):e.parent().prepend(t)}function o(e,n){if(e instanceof t.element&&(e=e[0]),null!==c)return e[c](n)}var r=[];t.module("eolinker.directive").directive("svGroupRoot",["$rootScope",function(e){function t(e,t,n){return n?e.x-t.x<0:e.y-t.y<0}function n(e){return s[e]}function a(e){delete s[e]}var i,s=Object.create(null);return{restrict:"A",controller:["$scope","$attrs","$interpolate","$parse",function(e,c,l,u){var p=l(c.svGroupRoot)(e)||e.$id;s[p]||(s[p]=[]);var d,m,f,h,g,v,b=this,$=!1,y=u(c.fun)(e);this.sortingInProgress=function(){return i},r.push(e.$watch(c.disabled,function(e,t){b.disabled=e})),e.$on("$destroy",function(){r.map(function(e,t){e()})}),this.$moveUpdate=function(a,r,s,l,y,x,j){if(!b.disabled){var w=s[0].getBoundingClientRect();"element"===a.tolerance&&(r={x:~~(w.left+w.width/2),y:~~(w.top+w.height/2)}),i=!0,d=[],m||(y?(m=y.clone(),m.removeClass("ng-hide")):(m=l.clone(),m.addClass("sv-group-placeholder"),m.css({height:s[0].height+"px",width:s[0].width+"px"})),l.after(m),l.addClass("ng-hide"),g=l,f=a,h=s,e.$root&&e.$root.$$phase||e.$apply()),h[0].reposition({x:r.x+document.body.scrollLeft-r.offset.x*w.width,y:r.y+document.body.scrollTop-r.offset.y*w.height}),n(p).forEach(function(e,n){if(null==a.containment||o(e.element,a.containment)||o(e.element,a.containment+" *")){var i=e.element[0].getBoundingClientRect(),s={x:~~(i.left+i.width/2),y:~~(i.top+i.height/2)};e.container||!e.element[0].scrollHeight&&!e.element[0].scrollWidth||d.push({element:e.element,top:i.top,view:e.getPart(),targetIndex:e.getIndex(),after:t(s,r,$)})}});var I=h[0].getBoundingClientRect(),O=m[0].getBoundingClientRect(),C=I.top+I.height/2,k=I.height/4;d.push({top:O.top,element:m,placeholder:!0}),d.sort(function(e,t){return e.top-t.top});var S=x.model(x.scope)[j].groupDepth,_=1==S?"10px":2*(S-1)+"em";d.forEach(function(t,n){var a=x.model(x.scope)[t.targetIndex],i=function(){t.placeholder||(d[d.length-1].element.removeClass("sv-group-candidate-bottom"),t.element.removeClass("sv-group-candidate-top sv-group-candidate"))},o=!1;if(c.disabledModelKey&&a){var r=u(c.disabledModelKey)(e);if(r)if("string"==typeof r){if(a[r])return void i()}else{var s=!0,l=!1,p=void 0;try{for(var m,f=r[Symbol.iterator]();!(s=(m=f.next()).done);s=!0){var g=m.value;if(a[g])return void i()}}catch(b){l=!0,p=b}finally{try{!s&&f["return"]&&f["return"]()}finally{if(l)throw p}}}}if(c.disabledInAndAfterModelKey&&a){var $=u(c.disabledInAndAfterModelKey)(e);if($)if("string"==typeof $)a[$]&&(o=!0);else{var y=!0,j=!1,w=void 0;try{for(var O,D=$[Symbol.iterator]();!(y=(O=D.next()).done);y=!0){var E=O.value;if(a[E]){o=!0;break}}}catch(b){j=!0,w=b}finally{try{!y&&D["return"]&&D["return"]()}finally{if(j)throw w}}}}if(C>(n-1>-1?d[n-1].top+I.height-k:d[0].top-k)&&Ct.top+k&&Cd[d.length-1].top+I.height-k;o&&(A||R)?(i(),v=null):A?t.placeholder?(v=null,h.children().css({"padding-left":_})):(v=t,v.where="in",S=x.model(x.scope)[v.targetIndex].groupDepth,h.children().css({"padding-left":2*S+"em"}),t.element.addClass("sv-group-candidate")):R?t.placeholder?(v=null,h.children().css({"padding-left":_})):(v=t,v.where="after",S=x.model(x.scope)[v.targetIndex].groupDepth,h.children().css({"padding-left":1==S?"10px":2*(S-1)+"em"}),t.element.removeClass("sv-group-candidate-top sv-group-candidate"),d[d.length-1].element.addClass("sv-group-candidate-bottom")):i()})}},this.$drop=function(t,n,a){function o(){if(i=!1,m.remove(),h.remove(),g.removeClass("ng-hide"),d=void 0,m=void 0,a=void 0,h=void 0,g=void 0,v){v.element.removeClass("sv-group-candidate sv-group-candidate-top sv-group-candidate-bottom");var o=v.targetIndex;c.fun&&y({originIndex:n,targetIndex:o,where:v.where,from:t.model(t.scope)[n],to:t.model(t.scope)[o],groupList:t.model(t.scope)})}v=void 0,e.$root&&e.$root.$$phase||e.$apply()}if(!b.disabled&&m)if(a.revert){var r=m[0].getBoundingClientRect(),s=h[0].getBoundingClientRect(),l=Math.sqrt(Math.pow(s.top-r.top,2)+Math.pow(s.left-r.left,2)),u=+a.revert*l/200;u=Math.min(u,+a.revert),["-webkit-","-moz-","-ms-","-o-",""].forEach(function(e){"undefined"!=typeof h[0].style[e+"transition"]&&(h[0].style[e+"transition"]="all "+u+"ms ease")}),setTimeout(o,u)}else o()},this.addToSortableElements=function(e){n(p).push(e)},this.removeFromSortableElements=function(e){var t=n(p),i=t.indexOf(e);i>-1&&(t.splice(i,1),0===t.length&&a(p))}}]}}]).directive("svGroupPart",["$parse",function(e){return{restrict:"A",require:"^svGroupRoot",controller:["$scope",function(e){e.$svCtrl=this,this.getPart=function(){return e.part},this.$drop=function(t,n){e.$sortableRoot.$drop(e.part,t,n)}}],scope:!0,link:function(t,n,a,i){if(!a.svGroupPart)throw new Error("no model provided");var o=e(a.svGroupPart);if(!o.assign)throw new Error("model not assignable");t.part={id:t.$id,element:n,model:o,scope:t},t.$sortableRoot=i;var r={element:n,getPart:t.$svCtrl.getPart,container:!0};i.addToSortableElements(r),t.$on("$destroy",function(){i.removeFromSortableElements(r)})}}}]).directive("svGroupElement",["$parse","$rootScope",function(e,a){return{restrict:"A",require:["^svGroupPart","^svGroupRoot"],controller:["$scope",function(e){e.$svCtrl=this}],link:function(o,r,s,c){function u(e){function a(e){l.move=e.pageY,l.down-l.move>-5&&l.down-l.move<5||c[1].disabled||(n(e),h||(i(r,s),h=!0),c[1].$moveUpdate(d,{x:e.clientX,y:e.clientY,offset:x},s,r,y,c[0].getPart(),o.$index))}if(n(e),!(c[1].sortingInProgress()||c[1].disabled||0!=e.button&&"mousedown"===e.type)){h=!1,d=t.extend({},{tolerance:"pointer",revert:200},d);var s,l={down:e.pageY},u=r,p=r[0].getBoundingClientRect();$||($=c[0].helper),y||(y=c[0].placeholder),$?(s=$.clone(),s.removeClass("ng-hide"),s.css({left:p.left+document.body.scrollLeft+"px",top:p.top+document.body.scrollTop+"px"}),u.addClass("sv-visibility-hidden")):(s=u.clone(),s.addClass("sv-group-helper").css({left:p.left+document.body.scrollLeft+"px",top:p.top+document.body.scrollTop+"px",width:p.width+"px"}));var v=0;s[0].reposition=function(e){g&&clearInterval(g);var n=(e.x,e.y),a=s[0].getBoundingClientRect(),i=document.body,o=t.element(document.getElementsByClassName(d.parentContainment)),r=o[0].getBoundingClientRect();f&&(n>r.top-a.height&&nr.height+r.top-a.height&&n=o[0].scrollHeight-r.height&&clearInterval(g)},70))),this.style.top=n-i.scrollTop+"px"};var x={x:(e.clientX-p.left)/p.width,y:(e.clientY-p.top)/p.height};m.addClass("sv-sorting-in-progress"),m.bind("mousemove",a).on("mouseup touchend touchcancel",function j(e){b&&b(),g&&clearInterval(g),m.off("mousemove",a),h&&c[0].$drop(o.$index,d),m.removeClass("sv-sorting-in-progress"),r.removeClass("sv-visibility-hidden"),m.off("mouseup touchend touchcancel",j)})}}var p={element:r,getPart:c[0].getPart,getIndex:function(){return o.$index}},d=e(s.svGroupElement)(o),m=null;if(d.containment){m=l.call(r,d.containment);var f=m[0].getBoundingClientRect()}c[1].addToSortableElements(p),o.$on("$destroy",function(){c[1].removeFromSortableElements(p)});var h,g=(t.element(document.body),null),v=r,b=e(s.mouseUp)(o);v.on("mousedown touchstart",u),a.global.$watch.push(o.$watch("$svCtrl.handle",function(e){e&&(v.off("mousedown touchstart",u),v=e,v.on("mousedown touchstart",u))}));var $,y}}}]).directive("svGroupHandle",function(){return{require:"?^svGroupElement",link:function(e,t,n,a){a&&(a.handle=t.add(a.handle))}}});var s=document.documentElement,c=s.matches?"matches":s.matchesSelector?"matchesSelector":s.webkitMatches?"webkitMatches":s.webkitMatchesSelector?"webkitMatchesSelector":s.msMatches?"msMatches":s.msMatchesSelector?"msMatchesSelector":s.mozMatches?"mozMatches":s.mozMatchesSelector?"mozMatchesSelector":null;if(null==c)throw"This browser doesn't support the HTMLElement.matches method";var l=t.element.prototype.closest||function(e){for(var n=this[0].parentNode;n!==document.documentElement&&!n[c](e);)n=n.parentNode;return n[c](e)?t.element(n):t.element()};"function"!=typeof t.element.prototype.add&&(t.element.prototype.add=function(e){var n,a=t.element();for(e=t.element(e),n=0;n=e.mainObject.setting.minHeight&&(o[0].style.height=n+"px",e.$root&&e.$root.$$phase||e.$apply()),!1},s.setWidth=function(t){var n=t.movementX,a=o[0].clientWidth+n-15;if(!(a<=e.mainObject.setting.minWidth)){l=a+"px";for(var i=0;i*{cursor:col-resize!important;user-select: none;}'),document.onmousemove=s.setWidth}return document.onmouseup=function(){document.onmousemove=null,document.onmouseup=null;var n=document.getElementById("eo_tmp_drag");angular.element(n).remove(),t.releaseCapture&&t.releaseCapture(),e.mainObject&&e.mainObject.baseFun&&e.mainObject.baseFun.mouseup&&e.mainObject.baseFun.mouseup(e.mainObject.mark,l)},t.setCapture&&t.setCapture(),!1}),i()}}}])}(),function(){"use strict";angular.module("eolinker.directive").directive("innerHtmlCommonDirective",["$compile","Cache_CommonService","$rootScope",function(e,t,n){return{restrict:"AE",scope:{html:"<",innerHtmlCommonDirective:"@"},link:function(a,i,o,r){n.global.$watch.push(a.$watch(o.html?"html":"innerHtmlCommonDirective",function(){var n={html:o.html?a.html:a.innerHtmlCommonDirective,elemFunName:"append"};if(n.html)switch(o.remove&&i.empty(),"front"==o.position&&(n.elemFunName="prepend"),o.status){case"unbind-angular":i[n.elemFunName](n.html);break;case"cache":i[n.elemFunName](t.get(o.cacheVariable));break;default:try{i[n.elemFunName](e(n.html)(a.$parent))}catch(r){i[n.elemFunName](e(""+n.html+" ")(a.$parent))}}}))}}}])}(),function(){"use strict";angular.module("eolinker.directive").directive("datepickerTimesDirective",["$document","$rootScope",function(e,t){return{restrict:"AE",transclude:!0,templateUrl:"app/directive/common/datepicker/index.html",scope:{interaction:"=",datepickerTimesDirective:"&"},link:function(n,a,i,o){n.data={datePicker:{duration:{option:{dateDisabled:null,formatYear:"yy",startingDay:1}}}},n.request={startTime:"",endTime:""},n.fun={};var r={};n.fun.confirm=function(e){e&&e.$event.stopPropagation(),n.interaction.request.startTime=n.request.startTime,n.interaction.request.endTime=n.request.endTime,n.datepickerTimesDirective()},n.fun.close=function(e){e&&e.$event.stopPropagation(),n.interaction.show=!1},e.on("click",function(e){n.fun.close(),n.$root&&n.$root.$$phase||n.$apply()}),n.data.datePicker.duration.option.customClass=function(e){if("day"===e.mode&&e.date.getMonth()!==e.currentMonth)return"uib-day-disabled"},r.init=function(){n.request.startTime=n.interaction.request.startTime,n.request.endTime=n.interaction.request.endTime},r.init(),t.global.$watch.push(n.$watch("interaction.show",function(){n.interaction.show&&(r.init(),n.$broadcast("$RESET_DATEPICKER"))}))}}}])}(),function(){"use strict";angular.module("eolinker").directive("copyCommonDirective",["$rootScope","Cache_CommonService",function(e,t){return{restrict:"A",scope:{copyModel:"<"},link:function(n,a,i,o){var r={elem:null},s={},c={cache:t};s.btnFun=function(t){t.stopPropagation(),r.elem.value=n.copyModel||(i.cacheVariable?c.cache.get(i.cacheVariable):""),r.elem.select(),r.elem.click();try{document.execCommand("copy")?e.InfoModal("复制成功","success"):e.InfoModal("复制失败","error")}catch(a){e.InfoModal("复制失败","error")}},s.init=function(){r.elem=document.getElementById("template_textarea_js")||document.createElement("textarea"),r.elem.setAttribute("style","position:fixed,left:0,top:0,opacity:0;height:0;width:0;"),r.elem.setAttribute("id","template_textarea_js"),document.body.appendChild(r.elem),a.bind(i.buttonFunction||"click",s.btnFun)}(),n.$on("$destory",function(){document.body.removeChild(r.elem)})}}}])}(),function(){function e(e,t){var n,a=this;a.data={component:{sidebarCommonObject:{}},info:{current:null,menu:[{name:"监控面板",sref:"home.monitor",childSref:"home.monitor.global",icon:"icon-jiankong_o",power:-1,status:"un-spreed"},{name:"网关节点",sref:"home.cluster",childSref:"home.cluster.default",icon:"icon-yingyongAPP_o",power:-1},(n={name:"注册方式与负载",sref:"home.balance",icon:"icon-renwuzhongxin_o",childSref:"home.balance.service"},_defineProperty(n,"childSref","home.balance.list.default"),_defineProperty(n,"power",-1),_defineProperty(n,"childList",[{name:"服务注册方式",sref:"home.balance.service"},{name:"负载配置",sref:"home.balance.list",childSref:"home.balance.list.default",params:{cluster:"default"}}]),n),{name:"接口管理",sref:"home.project",icon:"icon-lianjie_o",childSref:"home.project.default",power:-1},{name:"访问策略",sref:"home.gpedit",icon:"icon-yuechi_o",power:-1,childSref:"home.gpedit.default"},{name:"告警设置",sref:"home.alert",childSref:"home.alert.setting",icon:"icon-anquan_o",power:-1,status:"un-spreed",childList:[{name:"告警设置",sref:"home.alert.setting"},{name:"告警列表",sref:"home.alert.list"}]},{name:"扩展插件",sref:"home.plugin",childSref:"home.plugin.default",icon:"icon-cengji_o",power:-1},{name:"网关设置",sref:"home.setting",childSref:"home.setting.basic",icon:"icon-quanjushezhi_o",power:-1,status:"un-spreed",childList:[{name:"基本设置",sref:"home.setting.basic"},{name:"日志设置",sref:"home.setting.log"}]}]}},a.service={authority:t},a.$onInit=function(){a.shrinkObject.isShrink=!1,a.data.component.sidebarCommonObject={mainObject:{baseInfo:{menu:a.data.info.menu}}}}}angular.module("eolinker").component("eoSidebar",{template:' ',controller:e,bindings:{shrinkObject:"<"}}),e.$inject=["$scope","Authority_CommonService"]}(),function(){"use strict";function e(){var e={navigation:{query:[],current:""}};return{info:e}}angular.module("eolinker").factory("NavbarService",e),e.$inject=[]}(),function(){"use strict";function e(e,t,n,a){var i=this;i.data={info:{shrinkObject:{},sidebarShow:null},fun:{$Home_ShrinkSidebar:null,init:null}},i.service={group:t,sidebar:a},i.data.fun.init=function(e){/inside/.test(n.current.name)?i.data.info.sidebarShow=!1:i.data.info.sidebarShow=!0},i.data.fun.init({key:window.location.href}),e.$on("$locationChangeSuccess",function(){/inside/.test(n.current.name.toLowerCase())?i.data.info.sidebarShow=!1:i.data.info.sidebarShow=!0})}angular.module("eolinker").config(["$stateProvider","RouteHelpersProvider",function(e,t){e.state("home",{url:"/home",template:' ',containerRouter:!0,resolve:t.resolveFor("DATEPICKER")})}]).component("home",{templateUrl:"app/ui/content/index.html",controller:e}),e.$inject=["$scope","GroupService","$state","Sidebar_CommonService"]}(),function(){"use strict";angular.module("eolinker.service",[])}(),function(){"use strict";function e(e){var t={group:null},n={};return n.get=function(){return t.group},n.set=function(n,a){t.group=n,a&&e.$broadcast("$SidebarFinish")},n.clear=function(){t.group=null},n}function t(e){var n={requestGroupOrder:[],time:{},service:e,generalFun:{},fun:{clear:null,spreed:null,operate:null},sort:{operate:null,init:null}},a={},i={locationArr:[],parentGroupPath:{},childGroupPath:{0:[]},groupObj:{}};return n.generalFun.resetGroupInfo=function(e){i=e?e:{locationArr:[],parentGroupPath:{},childGroupPath:{0:[]},groupObj:{}}},n.generalFun.getNextNotChildGroup=function(e){n.generalFun.resetGroupInfo(e.groupInfo||i);var t=i.groupObj[e.currentGroupID],o=i.childGroupPath[t.parentGroupID].indexOf(t.groupID);return o!=i.childGroupPath[t.parentGroupID].length-1?i.childGroupPath[t.parentGroupID][o+1]:a.getNextNotParentGroup(t)},n.generalFun.getGroupLastChildIndex=function(e){n.generalFun.resetGroupInfo(e.groupInfo||i);var t=i.childGroupPath[e.currentGroupID]||[];if(t.length){var a=n.generalFun.getNextNotChildGroup({currentGroupID:t[t.length-1]}),o=i.locationArr.indexOf(a);return o==-1?i.locationArr.length-1:o-1}return i.locationArr.indexOf(e.currentGroupID)},a.getNextNotParentGroup=function(e){if(!(e.groupDepth<2)){var t=i.groupObj[e.parentGroupID],n=i.childGroupPath[t.parentGroupID],o=n[n.indexOf(e.parentGroupID)+1];return o?o:a.getNextNotParentGroup(t)}},a.insertGroupToParentLast=function(e){if(e.parentGroupID){var t=n.generalFun.getGroupLastChildIndex({currentGroupID:e.parentGroupID});i.locationArr.splice(t+1,0,e.groupID)}else i.locationArr.push(e.groupID)},a.orderByGroupOrder=function(e){if(!angular.equals({},n)){var t=e.groupInfo,n={};try{n=JSON.parse(e.response.groupOrder)}catch(a){}var i=[],o=0==t.locationArr.length?"reset":"child";if(angular.forEach(n,function(e,t){i[e]=Number(t)}),"reset"!=o){var r=t.locationArr.indexOf(e.response.groupID)+1;t.childGroupPath[e.response.groupID]=[]}else t.childGroupPath[0]=[],e.response.groupID=0;angular.forEach(i,function(n,a){if(n in t.groupObj){var i=t.groupObj[n];i.parentGroupID==e.response.groupID&&("reset"!=o?(t.parentGroupPath[n]=[e.response.groupID].concat(t.parentGroupPath[e.response.groupID]||0),t.childGroupPath[e.response.groupID].push(n),t.locationArr.splice(r,0,n),r++):(t.parentGroupPath[n]=[0],t.childGroupPath[0].push(n),t.locationArr.push(n)))}})}},n.generalFun.openGroup=function(e){
-i=e.groupInfo||i,t=i.locationArr.indexOf(e.currentGroupID),e.list[t].isOpen=!0,angular.forEach(i.childGroupPath[e.currentGroupID],function(n,a){t=i.locationArr.indexOf(n),t!=-1&&(e.list[t].hideStatus=!1)})},a.closeGroup=function(e){angular.forEach(i.childGroupPath[e.currentGroupID],function(n,o){t=i.locationArr.indexOf(n),e.list[t].isOpen=!1,e.list[t].hideStatus=!0,i.childGroupPath[n]&&(e.currentGroupID=n,a.closeGroup(e))})},a.deleteChildGroup=function(e){i.childGroupPath[e]&&i.childGroupPath[e].length&&angular.forEach(i.childGroupPath[e],function(e,t){a.deleteChildGroup(e)}),i.groupObj[e]=null,i.childGroupPath[e]=[],i.parentGroupPath[e]=[]},n.generalFun.sortByLocationArr=function(e){n.generalFun.resetGroupInfo(e.groupInfo||i),angular.forEach(i.locationArr,function(t,n){e.list[n]=i.groupObj[t]});var t=e.list.length-i.locationArr.length;t>0&&e.list.splice(i.locationArr.length,t)},n.fun.deleteGroup=function(e){n.generalFun.resetGroupInfo(e.groupInfo);var t=i.locationArr.indexOf(e.currentGroup.groupID),o=n.generalFun.getNextNotChildGroup({currentGroupID:e.currentGroup.groupID}),r=o?i.locationArr.indexOf(o)-t:i.locationArr.length-t;i.locationArr.splice(t,r),i.childGroupPath[e.currentGroup.parentGroupID].splice(i.childGroupPath[e.currentGroup.parentGroupID].indexOf(e.currentGroup.groupID),1),i.parentGroupPath[e.currentGroup.groupID]=[],i.groupObj[e.currentGroup.groupID]=null,a.deleteChildGroup(e.currentGroup.groupID),n.generalFun.sortByLocationArr({list:e.list})},n.generalFun.initGroupStatus=function(e){if(e.list&&e.list.length){var t=0==e.initGroupDepth?0:1;n.generalFun.resetGroupInfo(e.groupInfo||i);var a=Number(e.currentGroupID);if("reset"==e.status&&angular.forEach(e.list,function(e,n){e.isOpen=!1,e.groupDepth>t&&(e.hideStatus=!0)}),0==t||!(a<0||0==a)&&a in i.groupObj){var o=(i.groupObj[a],0);o=i.locationArr.indexOf(a),e.list[o].hideStatus=!1,e.list[o].isOpen=!0,0!=a&&angular.forEach(i.parentGroupPath[a],function(n,a){(n||0==t)&&(o=i.locationArr.indexOf(n),e.list[o].isOpen=!0,e.list[o].hideStatus=!1,angular.forEach(i.childGroupPath[n],function(t,n){o=i.locationArr.indexOf(t),e.list[o].hideStatus=!1}))}),angular.forEach(i.childGroupPath[a],function(t,n){o=i.locationArr.indexOf(t),e.list[o].hideStatus=!1})}}},n.fun.generalGroupInfo=function(e){n.generalFun.resetGroupInfo();var t=e.list;return angular.forEach(t,function(e,t){e.groupDepth=e.groupDepth,i.groupObj[e.groupID]=e}),angular.forEach(t,function(e,t){e.groupID=Number(e.groupID),e.parentGroupID=Number(e.parentGroupID||0),i.locationArr.indexOf(e.groupID)==-1&&(e.parentGroupID?(a.insertGroupToParentLast(e),i.parentGroupPath[e.groupID]=[e.parentGroupID].concat(i.parentGroupPath[e.parentGroupID]),i.childGroupPath[e.parentGroupID]?i.childGroupPath[e.parentGroupID].push(e.groupID):i.childGroupPath[e.parentGroupID]=[e.groupID]):(i.parentGroupPath[e.groupID]=[0],i.childGroupPath[0].push(e.groupID),i.locationArr.push(e.groupID)))}),i},n.sort.init=function(e,t,o){var r=[];if(o=o||{},n.generalFun.resetGroupInfo(),r=o.responseKey?e[o.responseKey]:e.groupList,!r)return{groupList:[],groupInfo:{}};var s={output:[]};return s.sortArr=r.sort(function(e,t){return e.groupDepth-t.groupDepth}),angular.forEach(r,function(e,t){e.isOpen=!1,e.groupDepth=e.groupDepth||0,i.groupObj[e.groupID]=e}),a.orderByGroupOrder({groupInfo:i,response:e}),angular.forEach(s.sortArr,function(e,t){e.groupID=Number(e.groupID),e.parentGroupID=Number(e.parentGroupID||0),i.locationArr.indexOf(e.groupID)==-1&&(e.parentGroupID?(a.insertGroupToParentLast(e),i.parentGroupPath[e.groupID]=[e.parentGroupID].concat(i.parentGroupPath[e.parentGroupID]),i.childGroupPath[e.parentGroupID]?i.childGroupPath[e.parentGroupID].push(e.groupID):i.childGroupPath[e.parentGroupID]=[e.groupID]):(i.parentGroupPath[e.groupID]=[0],i.childGroupPath[0].push(e.groupID),i.locationArr.push(e.groupID))),a.orderByGroupOrder({groupInfo:i,response:e})}),angular.forEach(i.locationArr,function(e,t){s.output.push(i.groupObj[e])}),n.generalFun.initGroupStatus({currentGroupID:t,status:"reset",initGroupDepth:o.initGroupDepth,list:s.output}),{groupList:s.output,groupInfo:i}},n.fun.spreed=function(e){e.$event&&e.$event.stopPropagation(),n.generalFun.resetGroupInfo(e.groupInfo);var t={currentGroupID:e.item.groupID,list:e.list};if(e.item.isOpen){var o=i.locationArr.indexOf(e.item.groupID);e.list[o].isOpen=!1,a.closeGroup(t)}else n.generalFun.openGroup(t)},n.fun.clear=function(){n.service.clear()},n.fun.getGroupPath=function(e){n.generalFun.resetGroupInfo(e.groupInfo);var t={output:[]},a=e.currentGroupID,o=i.groupObj[a];return i.parentGroupPath[a]&&i.parentGroupPath[a].length?(angular.forEach(i.parentGroupPath[a],function(e,n){if(e){var a=i.groupObj[e];t.output.unshift({groupName:a.groupName,groupID:a.groupID})}}),t.output.push({groupName:o.groupName,groupID:o.groupID}),t.output):[]},n}angular.module("eolinker.service").factory("Group_MultistageService",t).factory("GroupService",e),e.$inject=["$rootScope"],t.$inject=["GroupService"]}(),function(){"use strict";function e(){var e={info:{cache:null,statusCache:null},fun:{get:null,set:null}};return e.fun.clear=function(t){if(t)try{e.info.statusCache[t]=null}catch(n){}else e.info.cache=null},e.fun.get=function(t){if(t){try{return e.info.statusCache[t]}catch(n){return null}return e.info.statusCache}return e.info.cache},e.fun.set=function(t,n){if(n)try{e.info.statusCache[n]=t}catch(a){e.info.statusCache={},e.info.statusCache[n]=t}else e.info.cache=t},e.fun}angular.module("eolinker").factory("Cache_CommonService",e),e.$inject=[]}(),function(){"use strict";function e(){var e={permission:{"default":null}},t={};return t.clear=function(t){e.permission[t]=null},t.setPermission=function(t,n){switch(t){case"default":switch(n.userType){case 0:e.permission["default"]={authorityManagement:{edit:!0,look:!0},teammateManagement:{edit:!0,editManager:!0},apiManagement:{edit:!0},loadBalance:{edit:!0},strategyManagement:{edit:!0},nodeManagement:{edit:!0},pluginManagement:{edit:!0},gatewayConfig:{edit:!0},alertManagement:{edit:!0}};break;case 1:e.permission["default"]={authorityManagement:{edit:!0,look:!0},teammateManagement:{edit:!0,editManager:!1},apiManagement:{edit:!0},loadBalance:{edit:!0},strategyManagement:{edit:!0},nodeManagement:{edit:!0},pluginManagement:{edit:!0},gatewayConfig:{edit:!0},alertManagement:{edit:!0}};break;case 2:e.permission["default"]=n.permission}}},{permission:e.permission,fun:t}}angular.module("eolinker").factory("Authority_CommonService",e),e.$inject=[]}(),angular.module("ui.bootstrap.stackedMap",[]).factory("$$stackedMap",function(){return{createNew:function(){var e=[];return{add:function(t,n){e.push({key:t,value:n})},get:function(t){for(var n=0;n0&&(t=$.top().value,t.modalDomEl.toggleClass(t.windowTopClass||"",e))}function p(){if(h&&c()===-1){var e=g;d(h,g,function(){e=null}),h=void 0,g=void 0}}function d(e,n,a,i){function r(){r.done||(r.done=!0,t(e,{event:"leave"}).start().then(function(){e.remove(),i&&i.resolve()}),n.$destroy(),a&&a())}var s,c=null,l=function(){return s||(s=o.defer(),c=s.promise),function(){s.resolve()}};return n.$broadcast(x.NOW_CLOSING_EVENT,l),o.when(c).then(r)}function m(e){if(e.isDefaultPrevented())return e;var t=$.top();if(t)switch(e.which){case 27:t.value.keyboard&&(e.preventDefault(),i.$apply(function(){x.dismiss(t.key,"escape key press")}));break;case 9:x.loadFocusElementList(t);var n=!1;e.shiftKey?(x.isFocusInFirstItem(e)||x.isModalFocused(e,t))&&(n=x.focusLastFocusableElement()):x.isFocusInLastItem(e)&&(n=x.focusFirstFocusableElement()),n&&(e.preventDefault(),e.stopPropagation())}}function f(e,t,n){return!e.value.modalScope.$broadcast("modal.closing",t,n).defaultPrevented}var h,g,v,b="modal-open",$=s.createNew(),y=r.createNew(),x={NOW_CLOSING_EVENT:"modal.stack.now-closing"},j=0,w="a[href], area[href], input:not([disabled]), button:not([disabled]),select:not([disabled]), textarea:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable=true]";return i.$watch(c,function(e){g&&(g.index=e)}),n.on("keydown",m),i.$on("$destroy",function(){n.off("keydown",m)}),x.open=function(t,o){var r=n[0].activeElement,s=o.openedClass||b;u(!1),$.add(t,{deferred:o.deferred,renderDeferred:o.renderDeferred,closedDeferred:o.closedDeferred,modalScope:o.scope,backdrop:o.backdrop,keyboard:o.keyboard,openedClass:o.openedClass,windowTopClass:o.windowTopClass,animation:o.animation,appendTo:o.appendTo}),y.put(s,t);var l=o.appendTo,p=c();if(!l.length)throw new Error("appendTo element not found. Make sure that the element passed is in DOM.");p>=0&&!h&&(g=i.$new(!0),g.modalOptions=o,g.index=p,h=angular.element('
'),h.attr("backdrop-class",o.backdropClass),o.animation&&h.attr("modal-animation","true"),a(h)(g),e.enter(h,l));var d=angular.element("
');d.attr({"template-url":o.windowTemplateUrl,"window-class":o.windowClass,"window-top-class":o.windowTopClass,size:o.size,animate:"animate"}).html(o.content),o.animation&&d.attr("modal-animation","true"),e.enter(a(d)(o.scope),l).then(function(){o.scope.$$uibDestructionScheduled||e.addClass(l,s)}),$.top().value.modalDomEl=d,$.top().value.modalOpener=r,x.clearFocusListCache()},x.close=function(e,t){var n=$.get(e);return n&&f(n,t,!0)?(n.value.modalScope.$$uibDestructionScheduled=!0,n.value.deferred.resolve(t),l(e,n.value.modalOpener),!0):!n},x.dismiss=function(e,t){var n=$.get(e);return n&&f(n,t,!1)?(n.value.modalScope.$$uibDestructionScheduled=!0,n.value.deferred.reject(t),l(e,n.value.modalOpener),!0):!n},x.dismissAll=function(e){for(var t=this.getTop();t&&this.dismiss(t.key,e);)t=this.getTop()},x.getTop=function(){return $.top()},x.modalRendered=function(e){var t=$.get(e);t&&t.value.renderDeferred.resolve()},x.focusFirstFocusableElement=function(){return v.length>0&&(v[0].focus(),!0)},x.focusLastFocusableElement=function(){return v.length>0&&(v[v.length-1].focus(),!0)},x.isModalFocused=function(e,t){if(e&&t){var n=t.value.modalDomEl;if(n&&n.length)return(e.target||e.srcElement)===n[0]}return!1},x.isFocusInFirstItem=function(e){return v.length>0&&(e.target||e.srcElement)===v[0]},x.isFocusInLastItem=function(e){return v.length>0&&(e.target||e.srcElement)===v[v.length-1]},x.clearFocusListCache=function(){v=[],j=0},x.loadFocusElementList=function(e){if((void 0===v||!v.length)&&e){var t=e.value.modalDomEl;t&&t.length&&(v=t[0].querySelectorAll(w))}},x}]).provider("$uibModal",function(){var e={options:{animation:!0,backdrop:!0,keyboard:!0},$get:["$rootScope","$q","$document","$templateRequest","$controller","$uibResolve","$uibModalStack",function(t,n,a,i,o,r,s){function c(e){return e.template?n.when(e.template):i(angular.isFunction(e.templateUrl)?e.templateUrl():e.templateUrl)}var l={},u=null;l.getPromiseChain=function(){return u};var p=function(){var e=document.activeElement;try{e.blur()}catch(t){}};return l.open=function(i){function l(){return b}p();var d=n.defer(),m=n.defer(),f=n.defer(),h=n.defer(),g={result:d.promise,opened:m.promise,closed:f.promise,rendered:h.promise,close:function(e){return s.close(g,e)},dismiss:function(e){return s.dismiss(g,e)}};if(i=angular.extend({},e.options,i),i.resolve=i.resolve||{},i.appendTo=i.appendTo||a.find("body").eq(0),!i.template&&!i.templateUrl)throw new Error("One of template or templateUrl options is required.");var v,b=n.all([c(i),r.resolve(i.resolve,{},null,null)]);return v=u=n.all([u]).then(l,l).then(function(e){var n=i.scope||t,a=n.$new();a.$close=g.close,a.$dismiss=g.dismiss,a.$on("$destroy",function(){a.$$uibDestructionScheduled||a.$dismiss("$uibUnscheduledDestruction")});var r,c={};i.controller&&(c.$scope=a,c.$uibModalInstance=g,angular.forEach(e[1],function(e,t){c[t]=e}),r=o(i.controller,c),i.controllerAs&&(i.bindToController&&(r.$close=a.$close,r.$dismiss=a.$dismiss,angular.extend(r,n),angular.isFunction(r.$onInit)&&r.$onInit()),a[i.controllerAs]=r)),s.open(g,{scope:a,deferred:d,renderDeferred:h,closedDeferred:f,content:e[0],animation:i.animation,backdrop:i.backdrop,keyboard:i.keyboard,backdropClass:i.backdropClass,windowTopClass:i.windowTopClass,windowClass:i.windowClass,windowTemplateUrl:i.windowTemplateUrl,size:i.size,openedClass:i.openedClass,appendTo:i.appendTo,displayClass:i.displayClass}),m.resolve(!0)},function(e){m.reject(e),d.reject(e)})["finally"](function(){u===v&&(u=null)}),g},l}]};return e}),function(){"use strict";angular.module("eolinker.filter",[])}(),function(){"use strict";angular.module("eolinker.filter").filter("Field_CommonFilter",[function(){var e={fun:{main:null}};return e.fun.array=function(e){},e.fun.object=function(e,t){for(var n in e){e[n];t.indexOf(n)>-1&&(e[n]=null)}return e},e.fun.main=function(t,n,a){switch(t){case"array":return e.fun.array(n);case"object":return e.fun.object(n,a)}},e.fun.main}])}(),function(){"use strict";function e(e,t){e.config({debug:!1,events:!0,modules:t.MODULES})}angular.module("eolinker").config(e),e.$inject=["$ocLazyLoadProvider","APP_REQUIRES"]}(),function(){"use strict";function e(e,t,n,a,i){var o={fun:{init:null}};o.fun.init=function(){t.interceptors.push(["$injector",function(e){return e.get("AuthInterceptor")}]),n.html5Mode(!1).hashPrefix(""),a.otherwise("/")},o.fun.init()}function t(){}angular.module("eolinker").config(e).run(t),e.$inject=["$stateProvider","$httpProvider","$locationProvider","$urlRouterProvider","RouteHelpersProvider"],t.$inject=[]}(),function(){"use strict";function e(e){var t={info:{query:{MODULES:e.MODULES,SCRIPTS:{}}},fun:{basepath:null,resolveFor:null,$get:null}};return t.fun.$get=function(){return{basepath:t.fun.basepath,resolveFor:t.fun.resolveFor}},t.fun.basepath=function(e){return"app/"+e},t.fun.resolveFor=function(){var e=arguments;return{deps:["$ocLazyLoad","$q",function(n,a){function i(e){return"function"==typeof e?r.then(e):r.then(function(){var t=o(e);return t?n.load(t):$.error("Route resolve: Bad resource name ["+e+"]")})}function o(e){if(t.info.query.MODULES)for(var n in t.info.query.MODULES)if(t.info.query.MODULES[n].name&&t.info.query.MODULES[n].name===e)return t.info.query.MODULES[n];return t.info.query.SCRIPTS&&t.info.query.SCRIPTS[e]}for(var r=a.when(1),s=0,c=e.length;s0?window.document.title=t.list.join("-")+(t.list.length>=1?"-":"")+a.info.title.root:window.document.title=a.info.title.root}),e.$on(n.SYSTEM_ERROR,function(e){})}angular.module("eolinker").run(e),e.$inject=["$rootScope","$state","AUTH_EVENTS"]}(),function(){"use strict";function e(e,t,n,a){var i={info:{core:angular.module("eolinker")}};i.info.core.controller=e.register,i.info.core.directive=t.directive,i.info.core.filter=n.register,i.info.core.factory=a.factory,i.info.core.service=a.service,i.info.core.constant=a.constant,i.info.core.value=a.value}angular.module("eolinker").config(e),e.$inject=["$controllerProvider","$compileProvider","$filterProvider","$provide"]}(),function(){"use strict";function e(e,t,n){var a=this;a.data={text:"",query:null,searchInputElem:null,inputElem:n[0].getElementsByClassName("input-text"),q:""},a.fun={};var i={},o={originalElemCount:0};a.fun.inputMousedown=function(e){e&&e.stopPropagation(),a.data.currentElementCount=o.originalElemCount-1,i.clearText()},a.fun.searchChange=function(){var e=angular.copy(a.input.query);return a.data.currentElementCount=o.originalElemCount,a.data.q?void(a.data.query=e.filter(function(e,t){return(e[a.input.key]||"").toLowerCase().indexOf((a.data.q||"").toLowerCase())>-1?e:void 0})):void(a.data.query=e)},a.fun.divFocus=function(){a.fun.inputMousedown(),a.data.inputElem[0].focus()},a.fun.keydown=function(e){switch(a.data.hasOwnProperty("currentElementCount")||(a.data.currentElementCount=o.originalElemCount-1),e.keyCode){case 38:a.data.currentElementCount=a.data.currentElementCount<=o.originalElemCount?((a.data.query||[]).length||1)-1:a.data.currentElementCount-1,a.data.currentElementCount==o.originalElemCount?a.data.searchInputElem&&(a.data.searchFocusStatus=!0,a.data.searchInputElem[0].click(),a.data.searchInputElem[0].focus()):4==a.data.currentElementCount&&a.data.inputElem[0].focus(),t.$root&&t.$root.$$phase||t.$apply();break;case 40:e.preventDefault(),a.data.currentElementCount++,a.data.currentElementCount==(a.data.query||[]).length&&(a.data.currentElementCount=o.originalElemCount),a.data.currentElementCount==o.originalElemCount?a.data.searchInputElem&&(a.data.searchFocusStatus=!0,a.data.searchInputElem[0].click(),a.data.searchInputElem[0].focus()):0==a.data.currentElementCount&&a.data.inputElem[0].focus(),t.$root&&t.$root.$$phase||t.$apply();break;case 13:return e.preventDefault(),a.data.currentElementCount>=0&&(i.select(a.data.query[a.data.currentElementCount],a.data.currentElementCount),"true"!==a.multiple&&a.data.inputElem[0].blur(),t.$root&&t.$root.$$phase||t.$apply()),!1}},i.clearText=function(){a.data.q="",a.data.query=a.input.query},i.select=function(e,t){a.output=a.output||{};var n=a.output[a.modelKey];if("true"===a.multiple)if(a.output[a.modelKey]=a.output[a.modelKey]||{},e[a.input.value]in a.output[a.modelKey]){if(a.required&&!(Object.keys(a.output[a.modelKey]).length>1))return;delete a.output[a.modelKey][e[a.input.value]],a.data.text="",angular.forEach(a.output[a.modelKey],function(e,t){a.data.text=a.data.text+(a.data.text?",":"")+e})}else a.output[a.modelKey][e[a.input.value]]=e[a.input.key],a.data.text=a.data.text+(a.data.text?",":"")+e[a.input.key];else a.data.text=e[a.input.key],a.output[a.modelKey]=e[a.input.value];n!==a.output[a.modelKey]&&a.inputChangeFun&&a.inputChangeFun()},a.fun.clear=function(e){e.stopPropagation(),"true"===a.multiple?(a.data.text="",a.output[a.modelKey]={}):(a.data.text="",a.output=a.output||{},a.output[a.modelKey]=null),a.inputChangeFun&&a.inputChangeFun()},a.fun.domClick=function(e){e.stopPropagation()},a.fun.listMouseDown=function(e){e.stopPropagation();var t={};try{t.point=e.target.classList[0]}catch(n){t.point="default"}switch(t.point){case"select-btn-item":case"sd_check_box":"true"===a.multiple&&(e.preventDefault(),a.data.containerFocus=!0),t.index=e.target.getAttribute("eo-attr-index"),i.select(Object.assign({},a.data.query[t.index]),t.index)}},a.fun.searchActiveStatus=function(e){a.data.searchFocusStatus=e},i.initial=function(){if(a.data.text="",void 0!==a.input.initialData)if("true"===a.multiple)angular.forEach(a.input.initialData,function(e,t){t&&(a.data.text+=(a.data.text?",":"")+e,a.output[a.modelKey][t]=e)});else for(var e in a.data.query){var t=a.data.query[e];if(t[a.input.value]==a.input.initialData){a.data.text=t[a.input.key],a.output=a.output||{},a.output[a.modelKey]=t[a.input.value];break}}},e.global.$watch.push(t.$watch("$ctrl.input.query+$ctrl.input.initialData",function(){a.input.query&&(a.data.query=a.input.query,a.data.query.length>=5?(o.originalElemCount=-1,a.data.searchInputElem=n[0].getElementsByClassName("input-search")):o.originalElemCount=0,i.initial())})),a.$onInit=function(){a.modelKey=a.modelKey||"value",n.bind("keydown",a.fun.keydown)}}angular.module("eolinker").component("selectDefaultCommonComponent",{templateUrl:"app/component/selectDefault/index.html",bindings:{input:"<",output:"=",required:"@",multiple:"@",modelKey:"@",inputChangeFun:"&",disabled:"<",mainObject:"<"},controller:e}),e.$inject=["$rootScope","$scope","$element"]}(),function(){"use strict";function e(e){}angular.module("eolinker").component("progressBarCommonComponent",{templateUrl:"app/component/progressBar/index.html",controller:e,bindings:{mainObject:"<",modelKey:"=",list:"<"}}),e.$inject=["$scope"]}(),function(){"use strict";function e(e,t){var n=this,a={broadcast:null},i={};n.data={isEnd:!0},i.dataProcessing=function(e){n.data.isEnd=!1;var t={promise:n.fun({arg:e})};t.promise?t.promise["finally"](function(){n.data.isEnd=!0}):n.data.isEnd=!0},i.$Destory=function(){a.broadcast()},i.$LoadingInit=function(e,t){i.dataProcessing(t)},n.$onInit=function(t){n.interaction=n.interaction||{request:{},response:{}},n.interaction.request.delay||i.dataProcessing(t),a.broadcast=e.$on("$Init_LoadingPartCommonComponent",i.$LoadingInit),e.$on("$destroy",i.$Destory)}}angular.module("eolinker").component("loadingPartCommonComponent",{templateUrl:"app/component/loadingPart/index.html",controller:e,bindings:{fun:"&",interaction:"<"}}),e.$inject=["$scope","$state"]}(),function(){"use strict";function e(){var e=this;e.fun={},e.fun.clickMenu=function(t){e.cancleBindFun?e.output[e.modelKey]=t:e.bindFun({arg:t})}}angular.module("eolinker").component("menuRadioCommonComponent",{templateUrl:"app/component/menuRadio/index.html",controller:e,bindings:{output:"=",list:"<",modelKey:"@",bindFun:"&",cancleBindFun:"@",disabled:"<"}}),e.$inject=[]}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(){"use strict";function indexController(){var vm=this;vm.fun={common:null},vm.component={blockListObject:{listItem:{baseFun:{teardownWhenCheckboxIsClick:function(e,t){var n={};t.map(function(t){e.indexAddress.hasOwnProperty(t.value)?n[t.value]=e.indexAddress[t.value]:n[t.value]=0}),window.localStorage.setItem(vm.mainObject.setting.listItemStorageName,JSON.stringify(n))}},setting:{trClass:"hover-tr-lbcc"},tdList:[{type:"checkbox",isWantedToExposeObject:!0,checkboxClickAffectTotalItem:!0,activeKey:"value",activeValue:1},{thKey:"列表项",type:"text",modelKey:"key"}]}}},vm.fun.common=function(extend,arg){if(extend){var template={params:arg};switch(_typeof(extend.params)){case"string":return eval("extend.default("+extend.params+")");default:for(var key in extend.params)null==extend.params[key]?template.params[key]=arg[key]:template.params[key]=extend.params[key];return extend["default"](template.params)}}},vm.fun.search=function(e){e.item.keyword=e.item.keyword||"",e.$event&&e.$event.stopPropagation(),e.item.tapShow=!0,e.item.fun(e)},vm.fun.batchCancel=function(){vm.mainObject.setting.batchInitFun()},vm.fun.batchDefault=function(){vm.otherObject.batch.isOperating=!0,vm.mainObject.baseFun&&vm.mainObject.baseFun.batchDefault&&vm.mainObject.baseFun.batchDefault()},vm.$onInit=function(){vm.mainObject.setting.batch&&vm.mainObject.setting.batchInitFun()}}angular.module("eolinker").component("menuDefaultCommonComponent",{templateUrl:"app/component/menuDefault/index.html",controller:indexController,bindings:{authorityObject:"<",otherObject:"=",activeObject:"<",showObject:"<",mainObject:"<",blockListObject:"="}}),indexController.$inject=[]}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(){"use strict";function e(){var e={},t={};return t.deepCopy=function(e){return JSON.parse(JSON.stringify(e||[]))},t.loopGenerateList=function(e,n){var a={output:[]};try{for(var i in e){var o=e[i];if(n.fun){var r=n.fun(o,n.listDepth);if(r)switch(Object.prototype.toString.call(r)){case"[object Array]":a.output=a.output.concat(r);continue;default:o=r}}n.munalConstructListDepth||(o.listDepth=n.listDepth),a.output.push(o),o.childList&&o.childList.length>0&&(a.output=a.output.concat(t.loopGenerateList(t.deepCopy(o.childList),Object.assign({},n,{listDepth:n.listDepth+1}))),delete o.childList)}}catch(s){}return a.output},e.initReadonlyTableList=function(e,n){n=n||{};var a=t.deepCopy(e);return n.listDepth=0,a=t.loopGenerateList(a,n)},t.organizeLevelAsChildList=function(e,n,a){n=n||{};for(var i={outList:[],length:0},o=!1;n.indexe[n.index].listDepth){o=!0;break}continue}}if(o)break;if(null!==i.optionFunStatus&&(n.index++,i.outList.push(r)),n.index===e.length||r.listDepth>e[n.index].listDepth)break;if(r.listDepthe[n.index].listDepth)break}}return i.outList},e.formatNestList=function(e,n){n=n||{},n.index=0;var a=t.deepCopy(e);return a?t.organizeLevelAsChildList(a,n):a},e.initEditTableList=function(e,n){n=n||{};var a=t.deepCopy(e);if((n.fun||n.isLoop)&&(n.listDepth=n.listDepth||0,a=t.loopGenerateList(a,n)),!n.munalHideOperateColumn){if(n.lastFilterKey&&a.length>0&&!a[a.length-1][n.lastFilterKey])return a;a.push(Object.assign({},{listDepth:0},n.itemStructure))}return a},e}angular.module("eolinker").factory("ListBlock_CommonComponentService",e),e.$inject=[]}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(){"use strict";function indexController($rootScope,$scope){var vm=this,fun={};vm.data={sortForm:{parentContainment:"tbody-div",containment:".tbody-div"},sortAuthorityVar:"",sort:!1,isEditTable:!1,html:"",partHtml:{},movePart:null,checkboxTdObject:{selectAll:!1,indexAddress:{},query:[]}},vm.fun={};var data={radioOriginalIndex:0,movePart:null};vm.fun.sort=function(e){var t=data.movePart;if(vm.data.sort&&(!vm.mainObject.setting.hasOwnProperty("unSortIndex")||vm.mainObject.setting.unSortIndex!==e.targetIndex)){switch(e.where){case"before":case"in":case"after":break;default:return}e=e||{};var n={list:[],oldList:angular.copy(vm.mainObject.setting.isPartModule?vm.list[t]:vm.list),index:e.originIndex+1,targetIndex:e.targetIndex};n.list.push(Object.assign({},e.from,{listDepth:"in"===e.where?e.to.listDepth+1:e.to.listDepth,isHide:!("in"!==e.where||!e.to.isShrink)}));var a=function(){var t=n.oldList[n.index];"in"===e.where?t.listDepth=e.to.listDepth+t.listDepth-e.from.listDepth+1:t.listDepth=t.listDepth-(e.from.listDepth-e.to.listDepth),n.list.push(t),n.index++};if(vm.mainObject.baseFun.sortPartLastIndex)for(;n.indexe.from.listDepth);)a();else for(;n.indexe.from.listDepth;)a();if(!(e.targetIndex>e.originIndex&&e.targetIndexe.originIndex&&(e.targetIndex=e.targetIndex-(n.index-e.originIndex)+1,n.targetIndex=e.targetIndex-1),n.targetIndex<0))){var i=null;switch(e.where){case"before":i=e.originIndex=4)return;vm.mainObject.baseFun.sortIn&&vm.mainObject.baseFun.sortIn(n.oldList[n.targetIndex]),i=e.originIndex-1&&(tmp.point="input-checkbox")}catch(e){tmp.point="default"}if(!/container-tbd/.test(tmp.point))if(/^(btn-)|(fbtn-)|(cbtn-)/.test(tmp.point)){if(tmp.itemIndex=parseInt(fun.getTargetIndex($event.target)),tmp.btnObject=vm.mainObject.tdList[fun.getTargetIndex($event.target,"eo-attr-td-index")].btnList[fun.getTargetIndex($event.target,"eo-attr-btn-index")],tmp.btnObject.isUnWantToStopPropagation||$event.stopPropagation(),"btn-funItem"===tmp.point&&(tmp.btnObject=tmp.btnObject.funArr[fun.getTargetIndex($event.target,"eo-attr-btn-fun-index")]),tmp.btnObject.fun){var inputArg={item:vm.mainObject.setting.isPartModule?vm.list[inputPartIndex][tmp.itemIndex]:vm.list[tmp.itemIndex],$index:tmp.itemIndex};switch(/^(fbtn-)/.test(tmp.point)&&(inputArg.callback=vm.fun.watchFormLastChange),_typeof(tmp.btnObject.param)){case"string":return void eval("tmp.btnObject.fun("+tmp.btnObject.param+")");default:return void tmp.btnObject.fun(Object.assign(inputArg,tmp.btnObject.param))}}switch(tmp.point){case"btn-delete":case"cbtn-delete":fun.deleteItem(tmp.itemIndex);break;case"btn-addChild":fun.addChildItem({item:vm.list[tmp.itemIndex],$index:tmp.itemIndex});break;case"btn-insert":fun.insertItem({item:vm.list[tmp.itemIndex],$index:tmp.itemIndex})}}else{switch($event.stopPropagation(),data.checkboxClickAffectTotalItem&&vm.data.checkboxTdObject.isOperating?tmp.point="input-checkbox":data.radioClickAffectTotalItem&&(tmp.point="input-radio"),tmp.point){case"input-checkbox":fun.clickCheckbox(vm.mainObject.tdList[data.checkboxTdIndex],fun.getTargetIndex($event.target),inputPartIndex);break;case"relational-checkbox":fun.clickCheckbox(vm.mainObject.tdList[data.relationalCheckboxTdIndex],fun.getTargetIndex($event.target),inputPartIndex);break;case"input-radio":if(tmp.tdObject=vm.mainObject.tdList[data.radioTdIndex],tmp.itemIndex=fun.getTargetIndex($event.target),tmp.tdObject.disabledModelKey&&vm.list[tmp.itemIndex][tmp.tdObject.disabledModelKey])return;(data.radioOriginalIndex||0).toString()===tmp.itemIndex&&tmp.tdObject.isCanBeCancle?(vm.list[tmp.itemIndex][tmp.tdObject.modelKey]=!vm.list[tmp.itemIndex][tmp.tdObject.modelKey],data.radioOriginalIndex=0):(vm.list[data.radioOriginalIndex][tmp.tdObject.modelKey]=!1,vm.list[tmp.itemIndex][tmp.tdObject.modelKey]=!0,data.radioOriginalIndex=tmp.itemIndex)}!vm.data.checkboxTdObject.isOperating&&vm.mainObject.baseFun.trClick&&(tmp.itemIndex=parseInt(fun.getTargetIndex($event.target)),vm.mainObject.baseFun.trClick({item:vm.list[tmp.itemIndex],$index:tmp.itemIndex}))}},vm.fun.selectAll=function(e){var t=vm.mainObject.tdList[e],n="checkbox"===t.type?vm.data.checkboxTdObject:t,a=t.authority;if(!a||vm.authorityObject[a]){var i={modelKey:t.modelKey,activeKey:t.activeKey};switch(n.selectAll=!n.selectAll,t.type){case"relationalCheckbox":t.checkIsValidToRelateAll(n.selectAll)&&vm.fun.selectAll(data.checkboxTdIndex)}if(i.modelKey){if(!n.selectAll&&1===vm.list.length&&vm.mainObject.setting.isStaticFirstIndex)return void(n.selectAll=!0);for(var o in vm.list)vm.mainObject.setting.isStaticFirstIndex&&"0"===o||(vm.list[o][i.modelKey]=n.selectAll);data.queryLength=n.selectAll?(vm.list||[]).length:0,vm.mainObject.baseFun.clickCheckbox&&vm.mainObject.baseFun.clickCheckbox((n.selectAll?"plus":"minus")+"-all")}else{var r=vm.data.checkboxTdObject.indexAddress,s=vm.data.checkboxTdObject.query.length;if(vm.data.checkboxTdObject.indexAddress={},vm.data.checkboxTdObject.query=[],vm.data.checkboxTdObject.selectAll){if(vm.mainObject.setting.isPartModule)for(var c in vm.list){var l=vm.list[c];for(var u in l)vm.data.checkboxTdObject.query.push(l[u][i.activeKey]),vm.data.checkboxTdObject.indexAddress[l[u][i.activeKey]]=t.hasOwnProperty("activeValue")?t.activeValue:parseInt(u)+1}else if(vm.mainObject.setting.disabledSelectModelKey)for(var p in vm.list)vm.list[p][vm.mainObject.setting.disabledSelectModelKey]!==vm.mainObject.setting.disabledSelectVal&&(vm.data.checkboxTdObject.query.push(vm.list[p][i.activeKey]),vm.data.checkboxTdObject.indexAddress[vm.list[p][i.activeKey]]=t.hasOwnProperty("activeValue")?t.activeValue:parseInt(p)+1);else{var d=[];if(d=vm.mainObject.setting&&vm.mainObject.setting.isScrollLoad?vm.otherObject.allQuery:vm.list,vm.mainObject.baseFun.checkIsValidItem)for(var m in d)null!==d[m][i.activeKey]&&vm.mainObject.baseFun.checkIsValidItem({item:d[m],indexAddress:r,isSelectAll:!0})&&(vm.data.checkboxTdObject.query.push(d[m][i.activeKey]),vm.data.checkboxTdObject.indexAddress[d[m][i.activeKey]]=t.hasOwnProperty("activeValue")?t.activeValue:parseInt(m)+1);else for(var f in d)null!==d[f][i.activeKey]&&(vm.data.checkboxTdObject.query.push(d[f][i.activeKey]),vm.data.checkboxTdObject.indexAddress[d[f][i.activeKey]]=t.hasOwnProperty("activeValue")?t.activeValue:parseInt(f)+1)}vm.mainObject.baseFun.clickCheckbox&&vm.mainObject.baseFun.clickCheckbox("plus-all",{oldLength:s,currentLenght:vm.data.checkboxTdObject.query.length})}else vm.mainObject.baseFun.cancelToSelectAll?vm.mainObject.baseFun.cancelToSelectAll():vm.mainObject.baseFun.clickCheckbox&&vm.mainObject.baseFun.clickCheckbox("minus-all",{oldLength:s});vm.mainObject.baseFun.teardownWhenCheckboxIsClick&&vm.mainObject.baseFun.teardownWhenCheckboxIsClick(vm.data.checkboxTdObject,vm.list)}}},fun.getLastItemIndex=function(e,t){for(var n=e+1;n=(t[n].listDepth||0))return n;n++}return n},fun.checkIsLastItem=function(e,t){for(var n=e+1;nt[n].listDepth)return n;n++}return n},vm.fun.watchFormLastChange=function(e,t){if(!vm.mainObject.setting.munalAddRow&&!e.item.cancleAutomaticAddRow)if(vm.data.isDepth){if(!vm.mainObject.setting.munalHideOperateColumn||0!==e.$index){var n=fun.checkIsLastItem(e.$index,vm.list);n===!1||vm.mainObject.setting.illegalAutomaticAddRowModelKey&&(!vm.mainObject.setting.illegalAutomaticAddRowModelKey||e.item.hasOwnProperty(vm.mainObject.setting.illegalAutomaticAddRowModelKey))||vm.list.splice(n,0,Object.assign({},{listDepth:e.item.listDepth},vm.mainObject.itemStructure))}}else e.$index===vm.list.length-1&&vm.list.splice(e.$index+1,0,Object.assign({},{listDepth:e.item.listDepth},vm.mainObject.itemStructure));vm.mainObject.baseFun.watchFormLastChange&&vm.mainObject.baseFun.watchFormLastChange(e),t&&t(e)},$scope.importFile=function(e){e.$index=this.$parent.$index,vm.mainObject.baseFun.importFile(e)},vm.fun.shrinkList=function(e){e.stopPropagation();var t={};t.targetDom=fun.getTargetEvent(e.target),t.itemIndex=fun.getTargetIndex(e.target),vm.list[t.itemIndex].isShrink=!vm.list[t.itemIndex].isShrink,fun.operateLevel(t.targetDom.getAttribute("eo-attr-depth"),t.targetDom.nextElementSibling,parseInt(t.itemIndex)+1)},vm.fun.range=function(e,t){return e=e||1,(!vm.list[t.$index+1]||(vm.list[t.$index+1].listDepth||0)<=(t.item.listDepth||0))&&e--,new Array(e)},vm.fun.sortMouseDown=function(e,t){vm.mainObject.setting.unsortableVar&&vm.otherObject&&vm.otherObject[vm.mainObject.setting.unsortableVar]||(data.mouseEventElem=angular.element(e.target),data.mouseEventElem.bind("mousemove",function(){vm.data.movePart=t}))},vm.fun.mouseUp=function(){data.mouseEventElem&&data.mouseEventElem.unbind("mousemove"),data.movePart=vm.data.movePart,vm.data.movePart=null},fun.operateLevel=function(e,t,n){for(var a={operateName:angular.element(t).hasClass("ng-hide")?"removeClass":"addClass"},i=n,o=n;t&&e';for(var i in n){var o=n[i];a+=''+(o.key||o.html)+" "}a+=""}return a},fun.initItemHtml=function(e,t){var n="",a="";switch(e.type){case"depthText":vm.data.isDepth=!0,a+=''+e.thKey+"
",n+='";break;case"depthHtml":vm.data.isDepth=!0,a+=''+e.thKey+"
",n+='";break;case"depthInput":vm.data.isEditTable=!0,vm.data.isDepth=!0,a+=''+e.thKey+"
",n+='"+fun.parseFloatBtnGroupHtml("input",t,e.btnList)+"
";break;case"html":if(a+='"+e.thKey+"
","string"==typeof e.html)n+='"+e.html+"
";else if(e.html){n=[];for(var i in e.html)n.push(''+e.html[i]+"
")}break;case"text":if(a+='"+(e.thKey||"")+"
","string"==typeof e.modelKey)n+='{{item."+e.modelKey+"}}
";else if(e.modelKey){n=[];for(var o in e.modelKey)n.push('{{item."+e.modelKey[o]+"}}
")}break;case"sort":vm.data.sort=!0,vm.data.sortAuthorityVar=e.authority||"",a+=""+(e.thKey||"")+"
",n+="";break;case"radio":data.radioClickAffectTotalItem=e.radioClickAffectTotalItem||!1,data.radioOriginalIndex=vm.mainObject.setting.radioOriginalType||0,data.radioTdIndex=t,a+=''+e.thKey+"
",n+='{{item.'+e.modelKey+'?"":""}}
';break;case"relationalCheckbox":data.relationalCheckboxTdIndex=t,$rootScope.global.$watch.push($scope.$watch("$ctrl.list",fun.watchRelationalCheckboxChange,!0));var r=e.authority?"ng-class=\"{'disable-checkbox':!$ctrl.authorityObject."+e.authority+'}" ':"";a+='{{$ctrl.mainObject.tdList["+t+'].selectAll?"":" "}} '+(e.thKey?''+e.thKey+" ":"")+"
",n+='{{item."+e.modelKey+'?"":""}}
';break;case"checkbox":data.checkboxClickAffectTotalItem=e.checkboxClickAffectTotalItem||!1,data.checkboxTdIndex=t,$rootScope.global.$watch.push($scope.$watch("$ctrl.data.checkboxTdObject.isOperating",fun.watchCheckboxChange)),e.wantToWatchListLength&&$rootScope.global.$watch.push($scope.$watch("$ctrl.list.length",fun.watchCheckboxChange,!0)),e.modelKey&&$rootScope.global.$watch.push($scope.$watch("$ctrl.list",fun.watchCheckboxChange,!0)),e.isWantedToExposeObject&&(vm.data.checkboxTdObject=vm.activeObject=Object.assign({},vm.data.checkboxTdObject,vm.activeObject)),vm.data.checkboxTdObject.isOperating=!vm.data.checkboxTdObject.hasOwnProperty("isOperating")||vm.data.checkboxTdObject.isOperating;var s=e.authority?"ng-class=\"{'disable-checkbox':!$ctrl.authorityObject."+e.authority+'}" ':"";a+='{{$ctrl.data.checkboxTdObject.selectAll?"":" "}} '+(e.thKey?''+e.thKey+" ":"")+"
",n+='"+(e.modelKey?"{{item."+e.modelKey+'?"":""}}':"{{$ctrl.data.checkboxTdObject.indexAddress[item."+e.activeKey+']?"":""}}')+"
";break;case"cbtn":case"btn":a+=""+(e.thKey||"操作")+"
",n+="';for(var c in e.btnList){var l=e.btnList[c],u="";switch(l.type){case"more":for(var p in l.funArr){var d=l.funArr[p];u+='
'+d.key+"
"}n+='
";break;case"html":n+="
"+l.html+"
";break;default:n+='
'+(l.key||l.html)+" "}}n+="
";break;case"selectMulti":vm.data.isEditTable=!0,a+='"+e.thKey+"
",n+='
';break;case"select":vm.data.isEditTable=!0,a+='"+e.thKey+"
",n+='
';break;case"input":vm.data.isEditTable=!0,a+='"+e.thKey+"
",n+='";break;case"autoComplete":vm.data.isEditTable=!0,a+=''+e.thKey+"
",n+=''+(e.errorTip||"请填写"+e.thKey)+"
"+fun.parseFloatBtnGroupHtml("acp",t,e.btnList)+"
";break;case"autoCompleteAndFile":vm.data.isEditTable=!0;var m="",f=e.filePlaceholder||"请选择文件",h=e.fileBtnText||"选择文件";m=e.munalDefineFileFun?''+h+" ":''+h+" ",a+=''+e.thKey+"
",n+=''+m+'
'+fun.parseFloatBtnGroupHtml("acp",t,e.btnList)+"
"}return{thHtml:a,tdHtml:n}},fun.initPartHtml=function(){for(var e={html:new Array(vm.mainObject.setting.partNum),thHtml:""},t=0;t';try{e.html[t]=e.html[t].replace("{{trClass}}",vm.mainObject.setting.trClass||"").replace("{{trNgClass}}",vm.mainObject.setting.trNgClass||"").replace("{{trDirective}}",vm.mainObject.setting.trDirective||"").replace("{{trExpression}}",vm.mainObject.setting.trExpression||"")}catch(n){}}for(var a in vm.mainObject.tdList){var i=vm.mainObject.tdList[a],o=fun.initItemHtml(i,a);e.thHtml+=o.thHtml.replace("{{class}}",i["class"]||"");for(var r in e.html)"string"==typeof o.tdHtml?e.html[r]+=o.tdHtml.replace("{{class}}",i["class"]||""):e.html[r]+=o.tdHtml[r].replace("{{class}}",i["class"]||"")}for(var s in e.html)vm.data.partHtml[vm.mainObject.setting.partModule[s]]=e.html[s]+"
";vm.data.thHtml=e.thHtml},fun.initHtml=function(){var e={html:"",thHtml:""},t='';try{t=t.replace("{{trClass}}",vm.mainObject.setting.trClass||"").replace("{{trNgClass}}",vm.mainObject.setting.trNgClass||"").replace("{{trDirective}}",vm.mainObject.setting.trDirective||"")}catch(n){}for(var a in vm.mainObject.tdList){var i=vm.mainObject.tdList[a],o=fun.initItemHtml(i,a);e.thHtml+=o.thHtml.replace("{{class}}",i["class"]||""),t+=o.tdHtml.replace("{{class}}",i["class"]||"").replace("{{placeholder}}",i.placeholder?'placeholder="'+i.placeholder+'"':"")}e.html=(vm.mainObject.setting.isForm?'
':"')+('
');try{e.html=e.html.replace("{{trExpression}}",vm.mainObject.setting.trExpression||"")}catch(n){}vm.data.html=e.html+(vm.mainObject.extraTrHtml||"")+t+"
"+(vm.mainObject.setting.isForm?" ":"
"),vm.data.thHtml=e.thHtml},vm.$onInit=function(){vm.mainObject&&(vm.mainObject.setting=vm.mainObject.setting||{},vm.mainObject.baseFun=vm.mainObject.baseFun||{},vm.mainObject.setting.isPartModule?fun.initPartHtml():fun.initHtml())},fun.watchRelationalCheckboxChange=function(){if(!((vm.list||[]).length<=0)){var e=vm.mainObject.tdList[data.relationalCheckboxTdIndex],t=e.modelKey;data.queryLength=0;for(var n in vm.list)vm.list[n][t]&&data.queryLength++;(vm.list||[]).length===data.queryLength?e.selectAll=!0:e.selectAll=!1}},fun.watchCheckboxChange=function(){if((!((vm.list||[]).length<=0)||vm.mainObject.setting.isPartModule)&&vm.data.checkboxTdObject.isOperating){var e=vm.mainObject.tdList[data.checkboxTdIndex].modelKey;if(data.queryLength=0,e){for(var t in vm.list)vm.list[t][e]&&data.queryLength++;(vm.list||[]).length===data.queryLength?vm.data.checkboxTdObject.selectAll=!0:vm.data.checkboxTdObject.selectAll=!1}else{if(vm.mainObject.setting.isPartModule)for(var n in vm.list)data.queryLength+=(vm.list[n]||[]).length;else data.queryLength=(vm.list||[]).length;vm.data.checkboxTdObject.query=[];for(var a in vm.data.checkboxTdObject.indexAddress)vm.data.checkboxTdObject.query.push(vm.mainObject.setting.checkboxKeyIsNum?parseInt(a):a);(vm.data.checkboxTdObject.query||[]).length>=data.queryLength?vm.data.checkboxTdObject.selectAll=!0:vm.data.checkboxTdObject.selectAll=!1}}}}angular.module("eolinker").component("listBlockCommonComponent",{templateUrl:"app/component/listBlock/index.html",controller:indexController,bindings:{otherObject:"=",authorityObject:"<",mainObject:"<",list:"=",activeObject:"=",pageObject:"<"}}),indexController.$inject=["$rootScope","$scope"]}(),function(){"use strict";function indexController($scope,$element){var vm=this;vm.data={query:[],inputElem:$element[0].getElementsByClassName("input-text-acac"),inputIsFocus:!1},vm.fun={};var data={originalElemCount:0},privateFun={};vm.fun.modelChange=function(){if(vm.data.inputIsFocus=!0,vm.inputChangeFun(),privateFun.clearSelectItem(),vm.model[vm.keyName]){vm.data.query=[];var tmpIndex=0;angular.forEach(vm.array,function(val,key){var pattern="/^"+vm.model[vm.keyName].toLowerCase()+"/";try{eval(pattern).test(val.toLowerCase())?(vm.data.query.splice(tmpIndex,0,val),tmpIndex++):val.toLowerCase().indexOf(vm.model[vm.keyName].toLowerCase())>-1&&vm.data.query.push(val)}catch(EVAL_ERR){}}),vm.data.query.length<=0&&(vm.data.viewIsShow=!1)}else vm.data.query=vm.array},vm.fun.changeSwitch=function(e){vm.readOnly||(vm.data.inputIsFocus=e,vm.data.inputIsFocus&&(vm.data.query=vm.array),vm.data.inputElem[0].focus())},vm.fun.changeText=function(e){vm.data.inputIsFocus=!1,vm.model[vm.keyName]=e,vm.inputChangeFun()},privateFun.clearSelectItem=function(){data.originalElemCount=0,vm.data.currentElementCount=data.originalElemCount-1},vm.fun.inputBlur=function(e){e.stopPropagation(),vm.data.inputIsFocus=!1},vm.fun.inputFocus=function(e){e.stopPropagation(),privateFun.clearSelectItem()},vm.fun.keydown=function(e){switch(vm.data.hasOwnProperty("currentElementCount")||(vm.data.currentElementCount=data.originalElemCount-1),e.keyCode){case 38:vm.data.currentElementCount=vm.data.currentElementCount<=data.originalElemCount?((vm.data.query||[]).length||1)-1:vm.data.currentElementCount-1,$scope.$root&&$scope.$root.$$phase||$scope.$apply();break;case 40:e.preventDefault(),vm.data.currentElementCount++,vm.data.currentElementCount===(vm.data.query||[]).length&&(vm.data.currentElementCount=data.originalElemCount),$scope.$root&&$scope.$root.$$phase||$scope.$apply();break;case 13:return e.preventDefault(),vm.data.currentElementCount>=0&&(vm.fun.changeText(vm.data.query[vm.data.currentElementCount],vm.data.currentElementCount),$scope.$root&&$scope.$root.$$phase||$scope.$apply()),!1}}}angular.module("eolinker").component("autoCompleteComponent",{templateUrl:"app/component/autoComplete/index.html",controller:indexController,bindings:{mainObject:"<",readOnly:"<",placeholder:"@",keyName:"@",required:"<",array:"<",model:"=",inputChangeFun:"&"}}),indexController.$inject=["$scope","$element"]}(),function(e,t){"use strict";function n(e,t){return e.className.indexOf(t)>-1?e:!!e.parentElement&&n(e.parentElement,t)}t.module("eolinker.directive").directive("moveTipDirective",["$rootScope","$compile","$filter",function(e,a,i){return{restrict:"A",scope:{},link:function(o,r,s,c){var l=i("uuidFilter")(),u=''+(s.tipsObject?"{{"+s.tipsObject+"}}":s.tipsText)+'
';t.element(document.body).append(a(u)(o.$parent));
-var p=t.element(document.getElementsByClassName(s.parentClassName)),d=null,m=0,f={},h=null,g=null;try{f=JSON.parse(s.tipsStyle)}catch(v){}e.global.$watch.push(o.$watch(s.tipsDisabled,function(e,t){g=e})),d=t.element(document.getElementsByClassName("move-tip-directive"+l)[0]),p.on("mouseover",function(e){if(m||(m=d[0].offsetHeight),h=s.ableClassName?n(e.target,s.ableClassName):e.target,!g&&e.target.className.indexOf(s.disableClassName)==-1&&(!s.ableClassName||s.ableClassName&&h)){var t=h.getBoundingClientRect();d.css({left:t.left+(Number(f.left)||0)+"px",top:t.top+(Number(f.top)||0)-m+5+"px",visibility:"visible"})}else d.css({visibility:"hidden"})}),d.on("mouseover",function(e){d.css({visibility:"visible"})}),d.on("mouseleave",function(e){d.css({visibility:"hidden"})}),p.on("mouseleave",function(e){d.css({visibility:"hidden"})}),o.$on("$destroy",function(){d.remove()})}}}])}(window,window.angular),function(){"use strict";angular.module("eolinker.directive").directive("tipDirective",["$compile","$filter","$timeout",function(e,t,n){return{restrict:"AE",transclude:!0,templateUrl:"app/directive/tip/index.html",scope:{input:"@"},link:function(e,a,i,o){e.data={input:{marginLeft:i.marginLeft||-5},uuid:t("uuidFilter")(),element:null};var r={timer:null},s={};s.$destroy=function(){r.timer&&n.cancel(r.timer)},r.timer=n(function(){e.data.element=document.getElementById("tip-directive-js-"+e.data.uuid),angular.element(e.data.element).append(e.input)}),e.$on("$destroy",s.$destroy)}}}])}(),function(){"use strict";angular.module("eolinker.directive").value("THROTTLE_MILLISECONDS",null).directive("infiniteScroll",["$rootScope","$window","$interval","THROTTLE_MILLISECONDS",function(e,t,n,a){return{scope:{infiniteScroll:"&",infiniteScrollContainer:"=",infiniteScrollDistance:"=",infiniteScrollDisabled:"=",infiniteScrollCancel:"=",infiniteScrollUseDocumentBottom:"=",infiniteScrollListenForEvent:"@"},link:function(i,o,r){function s(e){return!!e&&n(function(){return v()},0)}var c,l,u,p,d,m,f,h,g,v,b,$,y,x,j,w,I,O,C,k;return k=angular.element(t),j=null,w=null,p=null,d=null,$=!0,C=!1,O=null,u=!1,l=0,b=function(e){return e=e[0]||e,isNaN(e.offsetHeight)?e.document.documentElement.clientHeight:e.offsetHeight},y=function(e){if(e[0].getBoundingClientRect&&!e.css("none"))return e[0].getBoundingClientRect().top+x(e)},x=function(e){return e=e[0]||e,isNaN(window.pageYOffset)?e.document.documentElement.scrollTop:e.ownerDocument.defaultView.pageYOffset},v=function(){var t,a,r,s,c;if(d===k){t=b(d)+x(d[0].document.documentElement);var l=b(o);r=y(o)+l}else{t=b(d),a=0,void 0!==y(d)&&(a=y(d));var l=b(o);r=y(o)-a+l}return C&&(r=b((o[0].ownerDocument||o[0].document).documentElement)),s=r-t,c=s<=b(d)*j*.1&&r,c?(p=!0,w?i.$$phase||e.$$phase?i.infiniteScroll():i.$apply(i.infiniteScroll):void 0):(u&&n.cancel(u),p=!1)},I=function(e,t){var a,i,o;return o=null,i=0,a=function(){return i=(new Date).getTime(),n.cancel(o),o=null,e.call()},function(){var r,s;return r=(new Date).getTime(),s=t-(r-i),s<=0?(n.cancel(o),o=null,i=r,e.call()):o?void 0:o=n(a,s,1)}},null!=a&&(v=I(v,a)),i.$on("$destroy",function(){if(d.unbind("scroll",v),null!=O&&(O(),O=null),u)return n.cancel(u)}),h=function(e){return j=parseFloat(e)||0},i.$watch("infiniteScrollDistance",h),h(i.infiniteScrollDistance),f=function(e){if(w=!e,w&&p)return p=!1,v()},i.$watch("infiniteScrollDisabled",f),f(i.infiniteScrollDisabled),g=function(e){return C=e},i.$watch("infiniteScrollUseDocumentBottom",g),g(i.infiniteScrollUseDocumentBottom),c=function(e){if(null!=d&&d.unbind("scroll",v),d=e,null!=e)return d.bind("scroll",v)},c(k),i.infiniteScrollListenForEvent&&(O=e.$on(i.infiniteScrollListenForEvent,v)),m=function(e){if(null!=e&&0!==e.length){if(e.nodeType&&1===e.nodeType?e=angular.element(e):"function"==typeof e.append?e=angular.element(e[e.length-1]):"string"==typeof e&&(e=angular.element(document.querySelector(e))),null!=e)return c(e);throw new Error("invalid infinite-scroll-container attribute.")}},i.$watch("infiniteScrollContainer",m),i.$watch("infiniteScrollCancel",function(e){if(e){if(d.unbind("scroll",v),null!=O&&(O(),O=null),u)return n.cancel(u)}else c(angular.element(o.parent()))}),m(i.infiniteScrollContainer||[]),null!=r.infiniteScrollParent&&null==r.infiniteScrollCancel&&c(angular.element(o.parent())),null!=r.infiniteScrollImmediateCheck&&($=i.$eval(r.infiniteScrollImmediateCheck)),u=s($)}}}])}(),function(){"use strict";angular.module("eolinker.directive").directive("dropDownMenuCommonDirective",["$rootScope",function(e){return{restrict:"AE",scope:{dirDisable:"<"},link:function(t,n,a,i){t.data={elemArr:n[0].getElementsByClassName("eo_more_btn")};var o={};o.initWatchDom=function(){e.global.$watch.push(t.$watch("data.elemArr.length",function(){if(t.data.elemArr){var e=Array.prototype.slice.call(t.data.elemArr);e.map(function(e){var t=e;angular.element(t).bind("click",function(e){t.focus()})})}}))};(function(){/macintosh|mac os x/i.test(navigator.userAgent)&&!/Chrome/i.test(navigator.userAgent)&&(o.initWatchDom(),t.$on("$stateChangeStart",function(){t.data.elemArr=null}),t.$on("$stateChangeSuccess",function(){t.data.elemArr||(t.data.elemArr=n[0].getElementsByClassName("eo_more_btn"),o.initWatchDom())}))})()}}}])}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(){"use strict";function e(e,t,n,a,i,o,r){var s={info:{auth:null},fun:{request:null,response:null,responseError:null}};return s.fun.request=function(e){return e},s.fun.response=function(s){if(s.data){e.$broadcast({901:a.UNAUTHENTICATED,401:a.UNAUTHORIZED}[s.data.code],s);try{if(!/^\/nodeHttpServer/.test(s.config.url)&&"object"==_typeof(s.data))switch(s.data=JSON.parse(o("HtmlFilter")(angular.toJson(s.data))),s.data.statusCode){case r.COMMON.UNLOGIN:if(/(home)|(transaction)|(guide)/.test(window.location.href))return e.$broadcast("$LoginAgain_Core",s.config),n.reject("Sorry, the current status is not logged in. If you want to continue the operation, please login first!");break;case r.COMMON.SUCCESS:break;default:if(t.indexOf(s.data.statusCode)===-1){var c=i[s.data.statusCode];c?e.InfoModal(c,"error"):s.data.statusCode&&e.InfoModal(s.data.resultDesc||"操作失败,请稍候再试!","error"),s.data.statusCode=r.COMMON.HAD_WARNING}}}catch(l){s.data=s.data,e.$broadcast(a.SYSTEM_ERROR)}}return n.resolve(s)},s.fun.responseError=function(t){return e.$broadcast(a.SYSTEM_ERROR),n.reject(t)},s.fun}angular.module("eolinker").factory("AuthInterceptor",e),e.$inject=["$rootScope","FILTER_WARNING_CODE_ARR_COMMON_CONST","$q","AUTH_EVENTS","ERR_CODE_ARR_COMMON_CONST","$filter","CODE"]}(),function(){"use strict";angular.module("eolinker.resource",[])}(),function(){"use strict";function e(e,t){var n,a={info:{api:[],method:"POST"}};return a.info.api.ConfigLog=e(t+"config/log/:operate",{},{Console:{params:{operate:"console"},method:"GET",cancellable:!0},SetConsole:{params:{operate:"console"},method:"PUT",cancellable:!0},Node:{params:{operate:"node"},method:"GET",cancellable:!0},SetNode:{params:{operate:"node"},method:"PUT",cancellable:!0},Access:{params:{operate:"access"},method:"GET",cancellable:!0},SetAccess:{params:{operate:"access"},method:"PUT",cancellable:!0}}),a.info.api.ServiceDiscovery=e(t+"balance/service/:operate",{},{DriverQuery:{params:{operate:"drivers"},method:"GET",cancellable:!0},Query:{params:{operate:"list"},method:"GET",cancellable:!0},Info:{params:{operate:"info"},method:"GET",cancellable:!0},Add:{params:{operate:"add"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"delete"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"save"},method:a.info.method,cancellable:!0},SimpleQuery:{params:{operate:"simple"},method:a.info.method,cancellable:!0}}),a.info.api.Cluster=e(t+"cluster/:operate",{},{Query:{params:{operate:"list"},method:"GET",cancellable:!0},SimpleQuery:{params:{operate:"simpleList"},method:"GET",cancellable:!0}}),a.info.api.AlertMessage=e(t+"alert/msg/:operate",{},{Query:{params:{operate:"getList"},method:a.info.method,cancellable:!0},Empty:{params:{operate:"clear"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"delete"},method:a.info.method,cancellable:!0}}),a.info.api.Monitor=e(t+"monitor/gateway/:operate",{},{Info:{params:{operate:"getSummaryInfo"},method:a.info.method,cancellable:!0},Refresh:{params:{operate:"refreshInfo"},method:a.info.method,cancellable:!0},Download:{params:{operate:"download"},method:a.info.method,cancellable:!0}}),a.info.api.Config=e(t+"gateway/config/:mark/:operate",{},{BaseInfo:{params:{mark:"base",operate:"getInfo"},method:a.info.method,cancellable:!0},AlertInfo:{params:{mark:"alert",operate:"getInfo"},method:a.info.method,cancellable:!0},BaseEdit:{params:{mark:"base",operate:"edit"},method:a.info.method,cancellable:!0},AlertEdit:{params:{mark:"alert",operate:"edit"},method:a.info.method,cancellable:!0}}),a.info.api.ImportAms=e(t+"import/ams/:operate",{},{Project:{params:{operate:"project"},method:a.info.method,cancellable:!0,transformRequest:angular.identity,headers:{"Content-Type":void 0}},Api:{params:{operate:"api"},method:a.info.method,cancellable:!0,transformRequest:angular.identity,headers:{"Content-Type":void 0}},Group:{params:{operate:"group"},method:a.info.method,cancellable:!0,transformRequest:angular.identity,headers:{"Content-Type":void 0}}}),a.info.api.Project=e(t+"project/:operate/:target",{},{Query:{params:{operate:"getList"},method:"GET",cancellable:!0},Add:{params:{operate:"add"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"batchDelete"},method:a.info.method,cancellable:!0},Info:{params:{operate:"getInfo"},method:a.info.method,cancellable:!0},QueryAndGroup:{params:{operate:"strategy",target:"getList"},method:a.info.method,cancellable:!0}}),a.info.api.Api=e(t+"apis/:mark/:operate",{},{IDQuery:{params:{mark:"id",operate:"getList"},method:"GET",cancellable:!0},Query:{params:{operate:"getList"},method:"GET",cancellable:!0},Copy:{params:{operate:"copy"},method:a.info.method,cancellable:!0},Add:{params:{operate:"add"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"batchDelete"},method:a.info.method,cancellable:!0},ChangeGroup:{params:{operate:"batchEditGroup"},method:a.info.method,cancellable:!0},Info:{params:{operate:"getInfo"},method:a.info.method,cancellable:!0}}),a.info.api.ApiGroup=e(t+"apis/group/:operate",{},{Query:{params:{operate:"getList"},method:a.info.method,cancellable:!0},Add:{params:{operate:"add"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"delete"},method:a.info.method,cancellable:!0},Info:{params:{operate:"getInfo"},method:a.info.method,cancellable:!0}}),a.info.api.Auth=e(t+"auth/:operate",{},{Edit:{params:{operate:"editInfo"},method:a.info.method,cancellable:!0},Info:{params:{operate:"getInfo"},method:a.info.method,cancellable:!0},Status:{params:{operate:"getStatus"},method:a.info.method,cancellable:!0}}),a.info.api.Node=e(t+"node/:operate",{},{Query:{params:{operate:"getList"},method:a.info.method,cancellable:!0},Add:{params:{operate:"add"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},ChangeGroup:{params:{operate:"batchEditGroup"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"batchDelete"},method:a.info.method,cancellable:!0},Info:{params:{operate:"getInfo"},method:a.info.method,cancellable:!0},Reload:{params:{operate:"batchReload"},method:a.info.method,cancellable:!0},Restart:{params:{operate:"batchRestart"},method:a.info.method,cancellable:!0},Start:{params:{operate:"batchStart"},method:a.info.method,cancellable:!0},Stop:{params:{operate:"batchStop"},method:a.info.method,cancellable:!0}}),a.info.api.NodeGroup=e(t+"node/group/:operate",{},{Query:{params:{operate:"getList"},method:a.info.method,cancellable:!0},Add:{params:{operate:"add"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"delete"},method:a.info.method,cancellable:!0}}),a.info.api.Strategy=e(t+"strategy/:mark/:operate",{},(n={IDQuery:{params:{mark:"id",operate:"getList"},method:"GET",cancellable:!0},Info:{params:{operate:"getInfo"},method:"GET",cancellable:!0},Query:{params:{operate:"getList"},method:"GET",cancellable:!0},Add:{params:{operate:"add"},method:a.info.method,cancellable:!0},Copy:{params:{operate:"copy"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"batchDelete"},method:a.info.method,cancellable:!0},ChangeGroup:{params:{operate:"batchEditGroup"},method:a.info.method,cancellable:!0}},_defineProperty(n,"Info",{params:{operate:"getInfo"},method:a.info.method,cancellable:!0}),_defineProperty(n,"Start",{params:{operate:"batchStart"},method:a.info.method,cancellable:!0}),_defineProperty(n,"Stop",{params:{operate:"batchStop"},method:a.info.method,cancellable:!0}),n)),a.info.api.StrategyGroup=e(t+"strategy/group/:operate",{},{Query:{params:{operate:"getList"},method:a.info.method,cancellable:!0},Add:{params:{operate:"add"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"delete"},method:a.info.method,cancellable:!0}}),a.info.api.StrategyApi=e(t+"strategy/api/:mark/:operate",{},{IDQuery:{params:{mark:"id",operate:"getList"},method:"GET",cancellable:!0},UnassignIDQuery:{params:{mark:"id",operate:"getNotInList"},method:"GET",cancellable:!0},All:{params:{operate:"getNotInList"},method:a.info.method,cancellable:!0},Query:{params:{operate:"getList"},method:"GET",cancellable:!0},Add:{params:{operate:"add"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"batchDelete"},method:a.info.method,cancellable:!0},Info:{params:{operate:"getInfo"},method:a.info.method,cancellable:!0},ChangeTarget:{params:{operate:"batchEditTarget"},method:a.info.method,cancellable:!0}}),a.info.api.Balance=e(t+"balance/:operate",{},{CheckIsExistInCluster:{params:{operate:"exits"},method:a.info.method,cancellable:!0},Query:{params:{operate:"getList"},method:a.info.method,cancellable:!0},Add:{params:{operate:"add"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"batchDelete"},method:a.info.method,cancellable:!0},Info:{params:{operate:"getInfo"},method:a.info.method,cancellable:!0},SimpleQuery:{params:{operate:"simple"},method:a.info.method,cancellable:!0}}),a.info.api.Plugin=e(t+"plugin/:mark/:operate",{},{TagQuery:{params:{operate:"getListByType"},method:a.info.method,cancellable:!0},Query:{params:{operate:"getList"},method:a.info.method,cancellable:!0},Add:{params:{operate:"add"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"delete"},method:a.info.method,cancellable:!0},Info:{params:{operate:"getInfo"},method:a.info.method,cancellable:!0},Start:{params:{operate:"start"},method:a.info.method,cancellable:!0},Stop:{params:{operate:"stop"},method:a.info.method,cancellable:!0},BatchStop:{params:{operate:"batchStop"},method:a.info.method,cancellable:!0},BatchStart:{params:{operate:"batchStart"},method:a.info.method,cancellable:!0},Check:{params:{operate:"check",mark:"availiable"},method:a.info.method,cancellable:!0}}),a.info.api.PluginStrategy=e(t+"plugin/strategy/:operate",{},{Query:{params:{operate:"getList"},method:a.info.method,cancellable:!0},Add:{params:{operate:"addPluginToStrategy"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"batchDelete"},method:a.info.method,cancellable:!0},Info:{params:{operate:"getInfo"},method:a.info.method,cancellable:!0},Start:{params:{operate:"batchStart"},method:a.info.method,cancellable:!0},Stop:{params:{operate:"batchStop"},method:a.info.method,cancellable:!0}}),a.info.api.GpeditPluginApi=e(t+"strategy/api/plugin/:operate",{},{Query:{params:{operate:"getList"},method:a.info.method,cancellable:!0}}),a.info.api.PluginApi=e(t+"plugin/api/:mark/:operate",{},{QueryByStrategy:{params:{mark:"notAssign",operate:"getList"},method:a.info.method,cancellable:!0},Query:{params:{operate:"getListByStrategy"},method:a.info.method,cancellable:!0},Add:{params:{operate:"addPluginToApi"},method:a.info.method,cancellable:!0},Edit:{params:{operate:"edit"},method:a.info.method,cancellable:!0},Delete:{params:{operate:"batchDelete"},method:a.info.method,cancellable:!0},Info:{params:{operate:"getInfo"},method:a.info.method,cancellable:!0},Start:{params:{operate:"batchStart"},method:a.info.method,cancellable:!0},Stop:{params:{operate:"batchStop"},method:a.info.method,cancellable:!0}}),a.info.api}angular.module("eolinker.resource").factory("GatewayResource",e),e.$inject=["$resource","serverUrl"]}(),function(){"use strict";function e(e,t){var n={info:{api:[],method:"POST"}};return n.info.api.Guest=e(t+"guest/:operate",{},{Check:{params:{operate:"checkLogin"},method:n.info.method,cancellable:!0},Login:{params:{operate:"login"},method:n.info.method,cancellable:!0}}),n.info.api.User=e(t+"user/:mark/:operate",{},{Info:{params:{operate:"getInfo"},method:n.info.method,cancellable:!0},LoginOut:{params:{operate:"logout"},method:n.info.method,cancellable:!0},ChangePassword:{params:{mark:"password",operate:"edit"},method:n.info.method,cancellable:!0}}),n.info.api}angular.module("eolinker.resource").factory("CommonResource",e),e.$inject=["$resource","serverUrl"]}(),function(){"use strict";angular.module("eolinker.filter").filter("HtmlFilter",function(){return function(e){var t={htmlDecode:function(e){var t=document.createElement("div");t.innerHTML=e;var n=t.innerText||t.textContent;return t=null,n},htmlDecodeByRegExp:function(e){var t="";return 0==e.length?"":(t=e.replace(/</g,"<"),t=t.replace(/>/g,">"),t=t.replace(/&/g,"&"),t=t.replace(/ /g," "),t=t.replace(/"/g,'\\"'),t=t.replace(//g,""),t=t.replace(/(\\\\ufeff)/g,""))}};return t.htmlDecodeByRegExp(e)}})}(),function(){"use strict";angular.module("eolinker.filter").filter("findAttr",[function(e,t,n){return function(e,t,n){function a(e,t){n--;var i=e.getAttribute(t);return i?i:n?a(e.parentNode,t):void 0}return n=n||4,a(e,t)}}])}(),function(){"use strict";angular.module("eolinker.filter").filter("uuidFilter",[function(){var e={fun:{uuid:null}};return e.fun.uuid=function(){for(var e={array:[],hexSingal:"0123456789abcdef"},t=0;t<36;t++)e.array[t]=e.hexSingal.substr(Math.floor(16*Math.random()),1);return e.array[14]="4",e.array[19]=e.hexSingal.substr(3&e.array[19]|8,1),e.array[8]=e.array[13]=e.array[18]=e.array[23]="-",e.array.join("")},function(){return e.fun.uuid()}}]).filter("currentTimeFilter",[function(){return function(e,t){var n={};return t=t||{},n.getTime=function(){var n={info:{date:e?new Date(e):new Date,time:{year:null,month:null,day:null,hour:null,minute:null,second:null},string:null}};return n.info.time.year=n.info.date.getFullYear(),n.info.time.month=n.info.date.getMonth()+1,n.info.time.day=n.info.date.getDate(),n.info.time.hour=n.info.date.getHours(),n.info.time.minute=n.info.date.getMinutes(),n.info.time.second=n.info.date.getSeconds(),n.info.string=n.info.time.year+"-",n.info.time.month<10&&(n.info.string+="0"),n.info.string+=n.info.time.month+"-",n.info.time.day<10&&(n.info.string+="0"),n.info.string+=n.info.time.day+" ","day"==t.min?n.info.string:(n.info.time.hour<10&&(n.info.string+="0"),n.info.string+=n.info.time.hour+":",n.info.time.minute<10&&(n.info.string+="0"),n.info.string+=n.info.time.minute+":",n.info.time.second<10&&(n.info.string+="0"),n.info.string+=n.info.time.second,n.info.string)},n.getTime()}}]).filter("additionTimeFilter",[function(e,t){return function(e,t){var n={nowTime:null,afterTime:null};if(e)return n.nowTime=new Date(e[0]+"-"+e[1]+"-"+e[2]),t<12?n.nowTime.setDate(n.nowTime.getDate()+30*t):n.nowTime.setDate(n.nowTime.getDate()+t/12*365),n.afterTime=n.nowTime.getFullYear()+"年"+(n.nowTime.getMonth()+1)+"月"+n.nowTime.getDate()+"日",n.afterTime}}]).filter("durationTimeFilter",[function(e,t){return function(e,t){e=new Date(e),t=new Date(t);var n=t.getTime()-e.getTime(),a=Math.floor(n/864e5),i=n%864e5,o=Math.floor(i/36e5),r=i%36e5,s=Math.floor(r/6e4),c="";return c=s+"分"+c,c=o+"小时"+c,a>0&&(c=a+"天"+c),c}}])}(),function(){"use strict";angular.module("eolinker.constant",[])}(),function(){"use strict";angular.module("eolinker.constant").constant("APP_REQUIRES",{SCRIPTS:{},MODULES:[{name:"CLIPBOARD",files:["vendor/clipboard/dist/clipboard.min.js"]},{name:"ZEPTO",files:["vendor/zepto/zepto.min.js"]},{name:"ACE_EDITOR_AUTOCOMPLETE",files:["libs/ace-builds/src/ext-language_tools.js"]},{name:"ACE_EDITOR",files:["libs/ace-builds/src/ace.js"]},{name:"DATEPICKER",files:["libs/datepicker/lib/position.js","libs/datepicker/lib/dateparser.js","libs/datepicker/lib/datepicker.js","libs/datepicker/index.js"]}]})}(),function(){"use strict";angular.module("eolinker.constant").constant("AUTH_EVENTS",{LOGIN_SUCCESS:"auth-login-success",LOGIN_FAILED:"auth-login-failed",LOGOUT_SUCCESS:"auth-logout-success",SESSION_TIMEOUT:"auth-session-timeout",UNAUTHENTICATED:"auth-not-authenticated",UNAUTHORIZED:"auth-not-authorized",SYSTEM_ERROR:"something-wrong-system"}).constant("USER_ROLES",{USER:"guest"}).constant("PATH_INFO",{HOSTNAME:"nj.goku.com:1204",HOST:window.location.origin+"/",INHERIT_HOST:window.location.origin+window.location.pathname,MOCK:{DEFAULT:"http://result.goku.com/",HIGH:"http://mock.goku.com/"}})}(),function(){"use strict";angular.module("eolinker.constant").constant("RESPONSE_TEXT",{FAILURE:"请稍候再试或提交工单反馈"}).constant("ERROR_WARNING",{COMMON:"请稍候再试"}).constant("FILTER_WARNING_CODE_ARR_COMMON_CONST",["210000","230011","230000"]).constant("ERR_CODE_ARR_COMMON_CONST",{230005:"当前已存在相同地址的节点",260002:"当前已存在相同的负载名称",510009:"添加失败,人数已满!",280013:"操作失败,存在运行中的节点",340000:"当前无可下载的报表",120000:"旧密码错误",210001:"插件优先级非法",210002:"插件名称非法",210003:"插件优先级已经存在",210004:"插件名称已经存在",210005:"插件名称不存在",210009:"插件类型非法",190005:"当前请求方式下,该URL已存在!"}).constant("CODE",{COMMON:{HAD_WARNING:"xxxxxx",SUCCESS:"000000",UNLOGIN:"100001",SERVER_ERROR:"100000",UNAUTH:"100002"}})}(),function(){"use strict";angular.module("eolinker.directive").directive("uploadFileDirective",[function(){return{restrict:"AE",template:' ',scope:{fileType:"@",inputId:"@",uploadFileDirective:"&"}}}])}(),function(e,t){"use strict";function n(e){if(!("clientX"in e||"clientY"in e)){var t=e.touches||e.originalEvent.touches;t&&t.length&&(e.clientX=t[0].clientX,e.clientY=t[0].clientY),e.preventDefault()}}function a(e){if(e=e[0],e.previousElementSibling)return t.element(e.previousElementSibling);for(var n=e.previousSibling;null!=n&&1!=n.nodeType;)n=n.previousSibling;return t.element(n)}function i(e,t){var n=a(e);n.length>0?n.after(t):e.parent().prepend(t)}function o(e,n){if(e instanceof t.element&&(e=e[0]),null!==s)return e[s](n)}t.module("eolinker.directive").directive("svRoot",[function(){function e(e,t,n){return n?e.x-t.x<0:e.y-t.y<0}function t(e){return r[e]}function n(e){delete r[e]}var a,r=Object.create(null);return{restrict:"A",controller:["$scope","$attrs","$interpolate","$parse",function(s,c,l,u){var p=l(c.svRoot)(s)||s.$id;r[p]||(r[p]=[]);var d,m,f,h,g,v,b=!1,$=u(c.svOnSort);c.svOnStart=c.$$element[0].attributes["sv-on-start"],c.svOnStart=c.svOnStart&&c.svOnStart.value,c.svOnStop=c.$$element[0].attributes["sv-on-stop"],c.svOnStop=c.svOnStop&&c.svOnStop.value;var y=u(c.svOnStart),x=u(c.svOnStop),j=u(c.fun)(s);if(this.sortingInProgress=function(){return a},c.svGrid){if(b="true"===c.svGrid||"false"!==c.svGrid&&null,null===b)throw"Invalid value of sv-grid attribute"}else s.$watchCollection(function(){return t(p)},function(e){b=!1;var t=e.filter(function(e){return!e.container}).map(function(e){return{part:e.getPart().id,y:e.element[0].getBoundingClientRect().top}}),n=Object.create(null);t.forEach(function(e){n[e.part]?n[e.part].push(e.y):n[e.part]=[e.y]}),Object.keys(n).forEach(function(e){n[e].sort(),n[e].forEach(function(t,a){a0&&t===n[e][a+1]&&(b=!0)})})});this.$moveUpdate=function(n,r,c,l,u,$,x){var j=c[0].getBoundingClientRect();"element"===n.tolerance&&(r={x:~~(j.left+j.width/2),y:~~(j.top+j.height/2)}),a=!0,d=[],m||(u?(m=u.clone(),m.removeClass("ng-hide")):(m=l.clone(),m.addClass("sv-visibility-hidden"),m.addClass("sv-placeholder"),m.css({height:c[0].height+"px",width:c[0].width+"px"})),l.after(m),l.addClass("ng-hide"),g=l,f=n,h=c,y(s,{$helper:{element:h},$part:$.model($.scope),$index:x,$item:$.model($.scope)[x]}),s.$root&&s.$root.$$phase||s.$apply()),h[0].reposition({x:r.x+document.body.scrollLeft-r.offset.x*j.width,y:r.y+document.body.scrollTop-r.offset.y*j.height}),t(p).forEach(function(t,a){if(null==n.containment||o(t.element,n.containment)||o(t.element,n.containment+" *")){var i=t.element[0].getBoundingClientRect(),s={x:~~(i.left+i.width/2),y:~~(i.top+i.height/2)};t.container||!t.element[0].scrollHeight&&!t.element[0].scrollWidth||d.push({element:t.element,q:(s.x-r.x)*(s.x-r.x)+(s.y-r.y)*(s.y-r.y),view:t.getPart(),targetIndex:t.getIndex(),after:e(s,r,b)}),t.container&&!t.element[0].querySelector("[sv-element]:not(.sv-placeholder):not(.sv-source)")&&d.push({element:t.element,q:(s.x-r.x)*(s.x-r.x)+(s.y-r.y)*(s.y-r.y),view:t.getPart(),targetIndex:0,container:!0})}});var w=m[0].getBoundingClientRect(),I={x:~~(w.left+w.width/2),y:~~(w.top+w.height/2)};d.push({q:(I.x-r.x)*(I.x-r.x)+(I.y-r.y)*(I.y-r.y),element:m,placeholder:!0}),d.sort(function(e,t){return e.q-t.q}),d.forEach(function(e,t){0!==t||e.placeholder||e.container?0===t&&e.container?(v=e,e.element.append(m)):e.element.removeClass("sv-candidate"):(v=e,e.element.addClass("sv-candidate"),e.after?e.element.after(m):i(e.element,m))})},this.$drop=function(e,t,n){function i(){if(a=!1,m.remove(),h.remove(),g.removeClass("ng-hide"),d=void 0,m=void 0,n=void 0,h=void 0,g=void 0,x(s,{$part:e.model(e.scope),$index:t,$item:e.model(e.scope)[t]}),v){v.element.removeClass("sv-candidate");var i=e.model(e.scope).splice(t,1),o=v.targetIndex;v.view===e&&v.targetIndex>t&&o--,v.after&&o++,v.view.model(v.view.scope).splice(o,0,i[0]),v.view===e&&t===o||$(s,{$partTo:v.view.model(v.view.scope),$partFrom:e.model(e.scope),$item:i[0],$indexTo:o,$indexFrom:t}),c.fun&&j({$index:t,$targetIndex:o})}v=void 0,s.$root&&s.$root.$$phase||s.$apply()}if(m)if(n.revert){var o=m[0].getBoundingClientRect(),r=h[0].getBoundingClientRect(),l=Math.sqrt(Math.pow(r.top-o.top,2)+Math.pow(r.left-o.left,2)),u=+n.revert*l/200;u=Math.min(u,+n.revert),["-webkit-","-moz-","-ms-","-o-",""].forEach(function(e){"undefined"!=typeof h[0].style[e+"transition"]&&(h[0].style[e+"transition"]="all "+u+"ms ease")}),setTimeout(i,u)}else i()},this.addToSortableElements=function(e){t(p).push(e)},this.removeFromSortableElements=function(e){var a=t(p),i=a.indexOf(e);i>-1&&(a.splice(i,1),0===a.length&&n(p))}}]}}]).directive("svPart",["$parse",function(e){return{restrict:"A",require:"^svRoot",controller:["$scope",function(e){e.$svCtrl=this,this.getPart=function(){return e.part},this.$drop=function(t,n){e.$sortableRoot.$drop(e.part,t,n)}}],scope:!0,link:function(t,n,a,i){if(!a.svPart)throw new Error("no model provided");var o=e(a.svPart);if(!o.assign)throw new Error("model not assignable");t.part={id:t.$id,element:n,model:o,scope:t},t.$sortableRoot=i;var r={element:n,getPart:t.$svCtrl.getPart,container:!0};i.addToSortableElements(r),t.$on("$destroy",function(){i.removeFromSortableElements(r)})}}}]).directive("svElement",["$parse",function(e){return{restrict:"A",require:["^svPart","^svRoot"],controller:["$scope",function(e){e.$svCtrl=this}],link:function(a,i,o,r){function s(s){function l(e){n(e),m||(i.parent().prepend(g),m=!0),r[1].$moveUpdate(u,{x:e.clientX,y:e.clientY,offset:$},g,i,d,r[0].getPart(),a.$index)}if(n(s),!r[1].sortingInProgress()&&(0==s.button||"mousedown"!==s.type)){m=!1;var u=e(o.svElement)(a);if(u=t.extend({},{tolerance:"pointer",revert:200,containment:"html"},u),u.containment)var h=c.call(i,u.containment)[0].getBoundingClientRect();var g,v=i,b=i[0].getBoundingClientRect();p||(p=r[0].helper),d||(d=r[0].placeholder),p?(g=p.clone(),g.removeClass("ng-hide"),g.css({left:b.left+document.body.scrollLeft+"px",top:b.top+document.body.scrollTop+"px"}),v.addClass("sv-visibility-hidden")):(g=v.clone(),g.addClass("sv-helper").css({left:b.left+document.body.scrollLeft+"px",top:b.top+document.body.scrollTop+"px",width:b.width+"px"})),g[0].reposition=function(e){var t=e.x,n=e.y,a=g[0].getBoundingClientRect(),i=document.body;h&&(nh.top+i.scrollTop+h.height&&(n=h.top+i.scrollTop+h.height-a.height),th.left+i.scrollLeft+h.width&&(t=h.left+i.scrollLeft+h.width-a.width)),this.style.left=t-i.scrollLeft+"px",this.style.top=n-i.scrollTop+"px"};var $={x:(s.clientX-b.left)/b.width,y:(s.clientY-b.top)/b.height};f.addClass("sv-sorting-in-progress"),f.on("mousemove touchmove",l).on("mouseup touchend touchcancel",function y(e){f.off("mousemove touchmove",l),f.off("mouseup touchend touchcancel",y),f.removeClass("sv-sorting-in-progress"),m&&r[0].$drop(a.$index,u),i.removeClass("sv-visibility-hidden")})}}var l={element:i,getPart:r[0].getPart,getIndex:function(){return a.$index}};r[1].addToSortableElements(l),a.$on("$destroy",function(){r[1].removeFromSortableElements(l)});var u=i;u.on("mousedown touchstart",s),a.$watch("$svCtrl.handle",function(e){e&&(u.off("mousedown touchstart",s),u=e,u.on("mousedown touchstart",s))});var p;a.$watch("$svCtrl.helper",function(e){e&&(p=e)});var d;a.$watch("$svCtrl.placeholder",function(e){e&&(d=e)});var m,f=(t.element(document.body),t.element(document.documentElement))}}}]).directive("svHandle",function(){return{require:"?^svElement",link:function(e,t,n,a){a&&(a.handle=t.add(a.handle))}}}),t.element(document.head).append([""].join(""));var r=document.documentElement,s=r.matches?"matches":r.matchesSelector?"matchesSelector":r.webkitMatches?"webkitMatches":r.webkitMatchesSelector?"webkitMatchesSelector":r.msMatches?"msMatches":r.msMatchesSelector?"msMatchesSelector":r.mozMatches?"mozMatches":r.mozMatchesSelector?"mozMatchesSelector":null;if(null==s)throw"This browser doesn't support the HTMLElement.matches method";var c=t.element.prototype.closest||function(e){for(var n=this[0].parentNode;n!==document.documentElement&&!n[s](e);)n=n.parentNode;return n[s](e)?t.element(n):t.element()};"function"!=typeof t.element.prototype.add&&(t.element.prototype.add=function(e){var n,a=t.element();for(e=t.element(e),n=0;n{{interaction.request.text}}
',scope:{interaction:"<",dumpDirective:"&"},link:function(t,n,a,i){t.data={info:{elem:document.getElementById("dump-directive_js")},fun:{dump:null}};var o={info:{broadcast:null},fun:{init:null,$DumpDirective_Click:null,$Destory:null}};t.data.fun.dump=function(){t.$broadcast("$Init_LoadingCommonComponent",{arg:{"switch":t.interaction.request["switch"]}})},o.fun.$DumpDirective_Click=function(n,a){t.data.info.elem.href=e.HOST+"export/"+a.response.fileName,t.data.info.elem.click()},o.fun.$Destory=function(){o.info.broadcast()},o.fun.init=function(){t.interaction=t.interaction||{request:{}},o.info.broadcast=t.$on("$DumpDirective_Click_"+(t.interaction.request.broadcast||t.interaction.request["switch"]||""),o.fun.$DumpDirective_Click),t.$on("$destroy",o.fun.$Destory)}()}}}])}(),function(){"use strict";angular.module("eolinker.directive").directive("buttonSetDisableDirective",[function(){return{restrict:"AE",scope:{buttonSetDisableDirective:"&"},link:function(e,t,n,a){var i={fun:{init:null,btnFun:null}};i.fun.btnFun=function(n){n.stopPropagation();var a={promise:e.buttonSetDisableDirective()};t.prop("disabled",!0),a.promise?a.promise["finally"](function(){t.prop("disabled",!1)}):(t.prop("disabled",!1),e.$root&&e.$root.$$phase||e.$apply())},i.fun.init=function(){t.bind(n.buttonFunction||"click",i.fun.btnFun)}()}}}])}(),function(){return angular.module("eolinker").constant("serverUrl","../").constant("nodeServerUrl","../nodeHttpServer/").constant("isDebug",!1).constant("assetUrl","").constant("PRODUCT_TYPE","online").constant("COOKIE_CONFIG",{path:"/",domain:".eolinker.com"}).constant("WEBSOCKET_PORT",1204)}(),angular.module("eolinker").run(["$templateCache",function(e){e.put("app/modal/index.html"," "),e.put("app/component/autoComplete/index.html",'
'),e.put("app/component/listBlock/index.html",'
'),e.put("app/component/menuDefault/index.html",''),e.put("app/component/loadingPart/index.html",''),e.put("app/component/menuRadio/index.html",''),e.put("app/component/progressBar/index.html",'{{item[$ctrl.mainObject.setting.key]}}
'),e.put("app/component/selectDefault/index.html",'
'),e.put("app/directive/tip/index.html",' '),e.put("app/ui/content/index.html",''),e.put("app/component/common/sidebar/index.html",'
'),e.put("app/component/common/tip/index.html",""),
-e.put("app/component/product/overview/index.html",'
{{$ctrl.mainObject.setting.title}} {{item.title}}
{{$ctrl.otherObject[item.quotePoint][item.quoteVariable]}}
{{item.key}}
{{childItem.key}}
'),e.put("app/directive/common/datepicker/index.html",'开始:{{request.startTime?(request.startTime | currentTimeFilter:{min:\'day\'}):\'\' }} 结束:{{request.endTime?(request.endTime | currentTimeFilter:{min:\'day\'}):\'\' }}
'),e.put("app/modal/branch/gateway/index.html",'
'),e.put("app/modal/branch/common/index.html",'
'),e.put("app/ui/content/login/index.html",''),e.put("app/ui/navbar/nav0/index.html",''),e.put("app/ui/navbar/nav1/index.html",'{{item.name}} {{item.name}} {{$ctrl.service.navbar.info.navigation.current}} {{$ctrl.service.navbar.info.navigation.extra}} {{$ctrl.data.userInfo.remark||$ctrl.data.userInfo.loginCall||\' \'}} {{$ctrl.service.navbar.info.userInfo.unreadMsgNum+$ctrl.service.navbar.info.userInfo.unreadNoticeNum}}
'),
-e.put("app/component/common/group/default/index.html",'{{$ctrl.mainObject.baseInfo.title||\'分组\'}}
{{item[$ctrl.mainObject.baseInfo.name]}}
{{item[$ctrl.mainObject.baseInfo.name]}} ({{item[$ctrl.mainObject.baseInfo.tips]}}) '),e.put("app/component/common/group/old/index.html",'{{item.key}} {{item.key}} {{$ctrl.mainObject.baseInfo.title||\'分组\'}} {{item[$ctrl.mainObject.baseInfo.name]}} '),e.put("app/component/common/list/default/index.html",'
'),e.put("app/component/common/select/multistage/index.html",'{{$first?"":" / "}}{{item[$ctrl.input.key]}} 请选择...
'),e.put("app/modal/lib/template/modal/backdrop.html",'
'),e.put("app/modal/lib/template/modal/window.html",''),e.put("app/ui/content/alert/setting/index.html",''),e.put("app/ui/content/balance/list/index.html",'
'),e.put("app/ui/content/alert/list/index.html",'
'),e.put("app/ui/content/balance/service/index.html",'
'),e.put("app/ui/content/balance/operate/index.html",''),e.put("app/ui/content/gpedit/inside/index.html",''),e.put("app/ui/content/gpedit/common/index.html",'
'),e.put("app/ui/content/gpedit/overview/index.html",'开放策略 {{$ctrl.ajaxResponse.openGpeditInfo.enableStatus?"启用":"停用"}}
系统自带访问策略,使用开放策略时不需要传递策略 ID 参数
'),e.put("app/ui/content/cluster/node/index.html",'
'),e.put("app/ui/content/cluster/_default/index.html",'
'),e.put("app/ui/content/monitor/global/index.html",'V{{$ctrl.ajaxResponse.monitorInfo.baseInfo.version}}
版本
{{$ctrl.ajaxResponse.monitorInfo.baseInfo.clusterCount||0}}
集群
{{$ctrl.ajaxResponse.monitorInfo.baseInfo.nodeCount}}
节点
{{$ctrl.ajaxResponse.monitorInfo.baseInfo.redisCount}}
REDIS
{{$ctrl.ajaxResponse.monitorInfo.baseInfo.projectCount}}
项目
{{$ctrl.ajaxResponse.monitorInfo.baseInfo.apiCount}}
API
{{$ctrl.ajaxResponse.monitorInfo.baseInfo.strategyCount}}
访问策略
{{$ctrl.ajaxResponse.monitorInfo.gatewayRequestInfo.gatewayRequestCount}}
请求到达总数
{{$ctrl.ajaxResponse.monitorInfo.gatewayRequestInfo.gatewayErrorCount||0}}
请求异常数量
{{$ctrl.ajaxResponse.monitorInfo.gatewayRequestInfo.gatewaySuccessRate}}
请求成功率
{{$ctrl.ajaxResponse.monitorInfo.proxyRequestInfo.proxyRequestCount}}
请求转发总数
{{$ctrl.ajaxResponse.monitorInfo.proxyRequestInfo.proxyErrorCount||0}}
转发异常数量
{{$ctrl.ajaxResponse.monitorInfo.proxyRequestInfo.proxySuccessRate}}
转发成功率
'),e.put("app/ui/content/plugin/operate/index.html",'名称:
*插件名需与插件代码文件名一致,保存后不可更改
插件类型:
全局 策略 API *保存后不可更改
插件优先级(0-3000):
描述信息:
错误处理方式:
中断请求并返回错误信息 继续后续操作
插件配置文件信息:
'),
-e.put("app/ui/content/plugin/_default/index.html",'
'),e.put("app/ui/content/project/api/index.html",'
'),e.put("app/ui/content/setting/basic/index.html",''),e.put("app/ui/content/project/_default/index.html",'
'),e.put("app/ui/content/setting/log/index.html",' '),e.put("app/ui/content/gpedit/inside/navbar/index.html",' '),e.put("app/ui/content/gpedit/common/default/index.html",'
'),e.put("app/ui/content/cluster/node/_default/index.html",'
'),e.put("app/ui/content/project/api/_default/index.html",'
'),e.put("app/ui/content/project/api/operate/index.html",'分组:
名称:
请求方式:
请求路径:
转发地址/负载后端(Target/Upstream):
转发路径:
转发时去除匹配网关请求路径,实际转发路径:{{$ctrl.ajaxResponse.apiInfo.targetURL}}{{$ctrl.ajaxResponse.apiInfo.stripPrefix?\'\':($ctrl.ajaxResponse.apiInfo.requestURL|Filter_SlashSymbol)}}
转发时去除路径中多余的"/",例如“//login”会被解析成“/login”
转发方式:
跟随用户请求方式 POST GET PUT DELETE HEAD OPTIONS PATCH
超时限制(ms):
重试次数[非必填]:
告警阀值(次)[非必填]:*单位时间内,请求失败到达该阀值进行告警,0代表不进行告警;单位时间在告警管理处设定
'),e.put("app/ui/content/gpedit/inside/content/apiPlugin/index.html",'
'),e.put("app/ui/content/gpedit/inside/content/auth/index.html",' '),e.put("app/ui/content/gpedit/inside/content/setting/index.html",'基本设置
启用/停用策略
停用策略后,所有请求将无法通过该策略访问API
{{$ctrl.ajaxResponse.strategyInfo.enableStatus?"停用":"启用"}}
'),
-e.put("app/ui/content/gpedit/inside/content/api/_default/index.html",' '),e.put("app/ui/content/gpedit/inside/content/plugin/gpedit/index.html",'
'),e.put("app/ui/content/gpedit/inside/content/api/operate/index.html",' '),e.put("app/ui/content/gpedit/inside/content/plugin/operate/index.html",'')}]);
\ No newline at end of file
diff --git a/app/console/static/styles/app-6e5f7694bf.css b/app/console/static/styles/app-6e5f7694bf.css
deleted file mode 100644
index 7675719d73010602c03f381adaa45fbf09767614..0000000000000000000000000000000000000000
--- a/app/console/static/styles/app-6e5f7694bf.css
+++ /dev/null
@@ -1,16 +0,0 @@
-@charset "UTF-8";
-/*! Editor.md v1.5.0 | editormd.min.css | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 */
-/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */
-.fa-ul,.markdown-body .task-list-item,li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}.editormd-form br,.markdown-body hr:after{clear:both}.editormd{width:90%;height:640px;margin:0 auto 15px;text-align:left;overflow:hidden;position:relative;border:1px solid #ddd;font-family:"Meiryo UI","Microsoft YaHei","Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,Monaco,monospace,Tahoma,STXihei,"华文细黑",STHeiti,"Helvetica Neue","Droid Sans","wenquanyi micro hei",FreeSans,Arimo,Arial,SimSun,"宋体",Heiti,"黑体",sans-serif}.editormd *,.editormd:after,.editormd:before{-webkit-box-sizing:border-box;box-sizing:border-box}.editormd a{text-decoration:none}.editormd img{border:none;vertical-align:middle}.editormd .editormd-html-textarea,.editormd .editormd-markdown-textarea,.editormd>textarea{width:0;height:0;outline:0;resize:none}.editormd .editormd-html-textarea,.editormd .editormd-markdown-textarea{display:none}.editormd button,.editormd input[type=button],.editormd input[type=submit],.editormd input[type=text],.editormd select,.editormd textarea{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none}.editormd::-webkit-scrollbar{height:10px;width:7px;background:rgba(0,0,0,.1)}.editormd::-webkit-scrollbar:hover{background:rgba(0,0,0,.2)}.editormd::-webkit-scrollbar-thumb{background:rgba(0,0,0,.3);-webkit-border-radius:6px;border-radius:6px}.editormd::-webkit-scrollbar-thumb:hover{-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);-ms-box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);-o-box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);background-color:rgba(0,0,0,.4)}.editormd-user-unselect{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.editormd-toolbar{width:100%;min-height:37px;background:#fff;display:none;position:absolute;top:0;left:0;z-index:3;border-bottom:1px solid #ddd}.editormd-toolbar-container{padding:0 8px;min-height:35px;-o-user-select:none;user-select:none}.editormd-toolbar-container,.markdown-body .octicon{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.editormd-menu,.markdown-body ol,.markdown-body td,.markdown-body th,.markdown-body ul{padding:0}.editormd-menu{margin:0;list-style:none}.editormd-menu>li{margin:0;padding:5px 1px;display:inline-block;position:relative}.editormd-menu>li.divider{display:inline-block;text-indent:-9999px;margin:0 5px;height:65%;border-right:1px solid #ddd}.editormd-menu>li>a{outline:0;color:#666;display:inline-block;min-width:24px;font-size:16px;text-decoration:none;text-align:center;-webkit-border-radius:2px;border-radius:2px;border:1px solid #fff;transition:all 300ms ease-out;-webkit-transition:all 300ms ease-out}.editormd-dropdown-menu>li>a:hover,.editormd-menu>li>a{-moz-transition:all 300ms ease-out}.editormd-menu>li>a.active,.editormd-menu>li>a:hover{border:1px solid #ddd;background:#eee}.editormd-menu>li>a>.fa{text-align:center;display:block;padding:5px}.editormd-menu>li>a>.editormd-bold{padding:5px 2px;display:inline-block;font-weight:700}.editormd-menu>li:hover .editormd-dropdown-menu{display:block}.editormd-menu>li+li>a{margin-left:3px}.editormd-dropdown-menu{display:none;background:#fff;border:1px solid #ddd;width:148px;list-style:none;position:absolute;top:33px;left:0;z-index:100;-webkit-box-shadow:1px 2px 6px rgba(0,0,0,.15);-ms-box-shadow:1px 2px 6px rgba(0,0,0,.15);-o-box-shadow:1px 2px 6px rgba(0,0,0,.15);box-shadow:1px 2px 6px rgba(0,0,0,.15)}.editormd-dropdown-menu:after,.editormd-dropdown-menu:before{width:0;height:0;display:block;content:"";position:absolute;left:8px;border:5px solid transparent}.editormd-dropdown-menu:before{top:-11px;border-bottom-color:#ccc}.editormd-dropdown-menu:after{border-bottom-color:#fff;top:-10px}.editormd-dropdown-menu>li>a{color:#666;display:block;text-decoration:none;padding:8px 10px}.editormd-dropdown-menu>li>a:hover{background:#f6f6f6;-webkit-transition:all 300ms ease-out;transition:all 300ms ease-out}.editormd-dropdown-menu>li+li{border-top:1px solid #ddd}.editormd-container{margin:0;width:100%;height:100%;overflow:hidden;padding:35px 0 0;position:relative;background:#fff;-webkit-box-sizing:border-box;box-sizing:border-box}.editormd-dialog{color:#666;position:fixed;z-index:99999;display:none;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 0 10px rgba(0,0,0,.3);-ms-box-shadow:0 0 10px rgba(0,0,0,.3);-o-box-shadow:0 0 10px rgba(0,0,0,.3);box-shadow:0 0 10px rgba(0,0,0,.3);background:#fff;font-size:14px}.editormd-dialog-container{position:relative;padding:20px;line-height:1.4}.editormd-dialog-container h1{font-size:24px;margin-bottom:10px}.editormd-dialog-container h1 .fa{color:#2c7eea;padding-right:5px}.editormd-dialog-container h1 small{padding-left:5px;font-weight:400;font-size:12px;color:#999}.editormd-dialog-container select{color:#999;padding:3px 8px;border:1px solid #ddd}.editormd-dialog-close{position:absolute;top:12px;right:15px;font-size:18px;color:#ccc;-webkit-transition:color 300ms ease-out;transition:color 300ms ease-out}.editormd .CodeMirror pre.CodeMirror-placeholder,.editormd-dialog-close:hover{color:#999}.editormd-dialog-header{padding:11px 20px;border-bottom:1px solid #eee;-webkit-transition:background 300ms ease-out;transition:background 300ms ease-out}.editormd-dialog-header:hover{background:#f6f6f6}.editormd-dialog-title{font-size:14px}.editormd-dialog-footer{padding:10px 0 0;text-align:right}.editormd-dialog-info{width:420px}.editormd-dialog-info h1{font-weight:400}.editormd-dialog-info .editormd-dialog-container{padding:20px 25px 25px}.editormd-dialog-info .editormd-dialog-close{top:10px;right:10px}.editormd-dialog-info .hover-link:hover,.editormd-dialog-info a:hover,.editormd-dialog-info p>a{color:#2196f3}.editormd-dialog-info .hover-link{color:#666}.editormd-dialog-info a .fa-external-link,.editormd-form iframe{display:none}.editormd-dialog-info a:hover .fa-external-link,.editormd-form .fa-btns,.editormd-tab-head li{display:inline-block}.editormd-container-mask{width:100%;height:100%;position:absolute;top:0;left:0}.editormd-dialog-mask{position:absolute}.editormd-dialog-mask,.editormd-mask{display:none;width:100%;height:100%;top:0;left:0}.editormd-dialog-mask-bg,.editormd-mask{background:#fff;opacity:.5;filter:alpha(opacity=50)}.editormd-mask{position:fixed;background:#000;opacity:.2;filter:alpha(opacity=20);z-index:99998}.editormd-container-mask{z-index:20;display:block;background-color:#fff}.editormd-code-block-dialog textarea,.editormd-preformatted-text-dialog textarea{width:100%;height:400px;margin-bottom:6px;overflow:auto;border:1px solid #eee;background:#fff;padding:15px;resize:none}.editormd-code-toolbar{color:#999;font-size:14px;margin:-5px 0 10px}.editormd-grid-table{width:99%;display:table;border:1px solid #ddd;border-collapse:collapse}.editormd-grid-table-row{width:100%;display:table-row}.editormd-grid-table-row a,.editormd-tab-head li a{color:#999;text-align:center;text-decoration:none;border:1px solid #ddd}.editormd-grid-table-row a{font-size:1.4em;width:5%;height:36px;display:table-cell;vertical-align:middle;-webkit-transition:background-color 300ms ease-out,color 100ms ease-in;transition:background-color 300ms ease-out,color 100ms ease-in}.editormd-grid-table-row a.selected{color:#666;background-color:#eee}.editormd-grid-table-row a:hover{color:#777;background-color:#f6f6f6}.editormd-tab-head{list-style:none;border-bottom:1px solid #ddd}.editormd-tab-head li a{display:block;padding:6px 12px 5px;margin-bottom:-1px;-webkit-border-top-left-radius:3px;-moz-border-top-left-radius:3px;border-top-left-radius:3px;-webkit-border-top-right-radius:3px;-moz-border-top-right-radius:3px;border-top-right-radius:3px;background:#f6f6f6;-webkit-transition:all 300ms ease-out;transition:all 300ms ease-out}.editormd-tab-head li a:hover{color:#666;background:#eee}.editormd-tab-head li.active a{color:#666;background:#fff;border-bottom-color:#fff}.editormd-tab-head li+li{margin-left:3px}.editormd-tab-box{padding:20px 0}.editormd-form{color:#666}.editormd-form label{float:left;display:block;width:75px;text-align:left;padding:7px 0 15px 5px;margin:0 0 2px;font-weight:400}.editormd-form input:focus{outline:0}.editormd-form input[type=text]{color:#999;padding:8px;border:1px solid #ddd}.editormd-form input[type=number]{color:#999;border:1px solid #ddd;width:40px;display:inline-block;padding:6px 8px}.editormd-form input[type=text]{display:inline-block;width:264px}.editormd-form .fa-btns a{color:#999;padding:7px 10px 0 0;display:inline-block;text-decoration:none;text-align:center}.editormd-form .fa-btns .fa{font-size:1.3em}.editormd-form .fa-btns label{float:none;display:inline-block;width:auto;text-align:left;padding:0 0 0 5px;cursor:pointer}.fa-fw,.fa-li{text-align:center}.editormd-dialog-container .editormd-btn,.editormd-dialog-container button,.editormd-dialog-container input[type=submit],.editormd-dialog-footer .editormd-btn,.editormd-dialog-footer button,.editormd-dialog-footer input[type=submit],.editormd-form .editormd-btn,.editormd-form button,.editormd-form input[type=submit]{color:#666;min-width:75px;cursor:pointer;background:#fff;padding:7px 10px;border:1px solid #ddd;-webkit-border-radius:3px;border-radius:3px;-webkit-transition:background 300ms ease-out;transition:background 300ms ease-out}.editormd-dialog-container .editormd-btn:hover,.editormd-dialog-container button:hover,.editormd-dialog-container input[type=submit]:hover,.editormd-dialog-footer .editormd-btn:hover,.editormd-dialog-footer button:hover,.editormd-dialog-footer input[type=submit]:hover,.editormd-file-input:hover input[type=submit],.editormd-form .editormd-btn:hover,.editormd-form button:hover,.editormd-form input[type=submit]:hover{background:#eee}.editormd-dialog-container .editormd-btn+.editormd-btn,.editormd-dialog-footer .editormd-btn+.editormd-btn,.editormd-form .editormd-btn+.editormd-btn{margin-left:8px}.editormd-file-input{width:75px;height:32px;margin-left:8px;position:relative;display:inline-block}.editormd-file-input input[type=file]{width:75px;height:32px;opacity:0;cursor:pointer;background:#000;display:inline-block;position:absolute;top:0;right:0}.editormd-file-input input[type=file]::-webkit-file-upload-button{visibility:hidden}.editormd .CodeMirror,.editormd-preview{width:50%;height:100%;vertical-align:top;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;line-height:1.6}.editormd .CodeMirror{z-index:3;float:left;border-right:1px solid #ddd;font-size:14px;font-family:"YaHei Consolas Hybrid",Consolas,"微软雅黑","Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,Monaco,courier,monospace;margin-top:35px;display:inline-block}.editormd-preview{position:absolute;top:35px;right:0;overflow:auto;display:none;background:#fff}.fa,.fa-stack{display:inline-block}.editormd .CodeMirror pre{font-size:14px;padding:0 12px}.editormd .CodeMirror-linenumbers{padding:0 5px}.editormd .CodeMirror-focused .CodeMirror-selected,.editormd .CodeMirror-selected{background:#70b7ff}.editormd .CodeMirror,.editormd .CodeMirror-scroll,.editormd .editormd-preview{-webkit-overflow-scrolling:touch}.editormd .styled-background{background-color:#ff7}.editormd .CodeMirror-focused .cm-matchhighlight{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);background-position:bottom;background-repeat:repeat-x}.editormd .CodeMirror-empty.CodeMirror-focused{outline:0}.editormd .cm-trailingspace{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAACCAYAAAB/qH1jAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUXCToH00Y1UgAAACFJREFUCNdjPMDBUc/AwNDAAAFMTAwMDA0OP34wQgX/AQBYgwYEx4f9lQAAAABJRU5ErkJggg==);background-position:bottom left;background-repeat:repeat-x}.editormd .cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=) right no-repeat}
-/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */
-/*!
- * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
- * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
- */
-.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em}.fa-ul{padding-left:0;margin-left:2.14286em}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14286em}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;-webkit-border-radius:.1em;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{position:relative;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}
-/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */
-@font-face{font-family:editormd-logo;src:url(../fonts/editormd-logo.eot?-5y8q6h);src:url(.../fonts/editormd-logo.eot?#iefix-5y8q6h) format("embedded-opentype"),url(../fonts/editormd-logo.woff?-5y8q6h) format("woff"),url(../fonts/editormd-logo.ttf?-5y8q6h) format("truetype"),url(../fonts/editormd-logo.svg?-5y8q6h#icomoon) format("svg");font-weight:400;font-style:normal}.editormd-logo{font-size:inherit}.editormd-logo,.editormd-logo-1x,.editormd-logo-2x,.editormd-logo-3x,.editormd-logo-4x,.editormd-logo-5x,.editormd-logo-6x,.editormd-logo-7x,.editormd-logo-8x{font-family:editormd-logo;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;display:inline-block;text-rendering:auto;vertical-align:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.markdown-body hr:after,.markdown-body hr:before{content:"";display:table}.editormd-logo-1x:before,.editormd-logo-2x:before,.editormd-logo-3x:before,.editormd-logo-4x:before,.editormd-logo-5x:before,.editormd-logo-6x:before,.editormd-logo-7x:before,.editormd-logo-8x:before,.editormd-logo:before{content:""}.editormd-logo-1x{font-size:1em}.editormd-logo-lg{font-size:1.2em}.editormd-logo-2x{font-size:2em}.editormd-logo-3x{font-size:3em}.editormd-logo-4x{font-size:4em}.editormd-logo-5x{font-size:5em}.editormd-logo-6x{font-size:6em}.editormd-logo-7x{font-size:7em}.editormd-logo-8x{font-size:8em}.editormd-logo-color{color:#2196f3}
-/*! github-markdown-css | The MIT License (MIT) | Copyright (c) Sindre Sorhus (sindresorhus.com) | https://github.com/sindresorhus/github-markdown-css */
-@font-face{font-family:octicons-anchor;src:url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format("woff")}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;color:#333;overflow:hidden;font-family:"Microsoft YaHei",Helvetica,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Monaco,monospace,Tahoma,STXihei,"华文细黑",STHeiti,"Helvetica Neue","Droid Sans","wenquanyi micro hei",FreeSans,Arimo,Arial,SimSun,"宋体",Heiti,"黑体",sans-serif;font-size:16px;line-height:1.6;word-wrap:break-word}.markdown-body strong,.markdown-body table th{font-weight:700}.markdown-body h1{margin:.67em 0}.markdown-body img{border:0;max-width:100%}.markdown-body hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;margin:15px 0;overflow:hidden;background:0 0;border:0;border-bottom:1px solid #ddd}.markdown-body input{color:inherit;margin:0;line-height:normal;font:13px/1.4 Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.markdown-body html input[disabled]{cursor:default}.markdown-body input[type=checkbox]{padding:0}.markdown-body *,.markdown-body img,.markdown-body input[type=checkbox]{-webkit-box-sizing:border-box;box-sizing:border-box}.markdown-body a{background:0 0;color:#4183c4;text-decoration:none}.markdown-body a:active,.markdown-body a:hover{outline:0;text-decoration:underline}.markdown-body h1,.markdown-body h2{padding-bottom:.3em;border-bottom:1px solid #eee}.markdown-body blockquote{margin:0}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;padding:.2em 0;margin:0;font-size:85%;background-color:rgba(0,0,0,.04);-webkit-border-radius:3px;border-radius:3px}.markdown-body pre{font:12px Consolas,"Liberation Mono",Menlo,Courier,monospace;word-wrap:normal}.markdown-body .octicon{font:16px octicons-anchor;line-height:1;display:inline-block;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.markdown-body .octicon-link:before{content:""}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body .anchor{position:absolute;top:0;left:0;display:block;padding-right:6px;padding-left:30px;margin-left:-30px}.markdown-body .anchor:focus{outline:0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{position:relative;margin-top:1em;margin-bottom:16px;font-weight:700}.markdown-body h4,.markdown-body h5,.markdown-body h6{line-height:1.4}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{display:none;color:#000;vertical-align:middle}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{padding-left:8px;margin-left:-30px;text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{display:inline-block}.markdown-body h1{font-size:2.25em;line-height:1.2}.markdown-body h1 .anchor,.markdown-body h2 .anchor{line-height:1}.markdown-body h2{font-size:1.75em;line-height:1.225}.markdown-body h3{font-size:1.5em;line-height:1.43}.markdown-body h3 .anchor,.markdown-body h4 .anchor{line-height:1.2}.markdown-body h4{font-size:1.25em}.markdown-body h5 .anchor,.markdown-body h6 .anchor{line-height:1.1}.markdown-body h5{font-size:1em}.markdown-body h6{font-size:1em;color:#777}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:16px}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li>p{margin-top:16px}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:700}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body blockquote{padding:0 15px;color:#777;border-left:4px solid #ddd}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body table{border-collapse:collapse;border-spacing:0;display:block;width:100%;overflow:auto;word-break:keep-all}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid #ddd}.markdown-body table tr{background-color:#fff;border-top:1px solid #ccc}.markdown-body table tr:nth-child(2n){background-color:#f8f8f8}.markdown-body code:after,.markdown-body code:before{letter-spacing:-.2em;content:" "}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:0 0;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;background-color:#f7f7f7;-webkit-border-radius:3px;border-radius:3px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body pre code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body pre code:after,.markdown-body pre code:before{content:normal}.markdown-body .pl-c{color:#969896}.markdown-body .pl-c1,.markdown-body .pl-mdh,.markdown-body .pl-mm,.markdown-body .pl-mp,.markdown-body .pl-mr,.markdown-body .pl-s1 .pl-v,.markdown-body .pl-s3,.markdown-body .pl-sc,.markdown-body .pl-sv{color:#0086b3}.markdown-body .pl-e,.markdown-body .pl-en{color:#795da3}.markdown-body .pl-s1 .pl-s2,.markdown-body .pl-smi,.markdown-body .pl-smp,.markdown-body .pl-stj,.markdown-body .pl-vo,.markdown-body .pl-vpf{color:#333}.markdown-body .pl-ent{color:#63a35c}.markdown-body .pl-k,.markdown-body .pl-s,.markdown-body .pl-st{color:#a71d5d}.markdown-body .pl-pds,.markdown-body .pl-s1,.markdown-body .pl-s1 .pl-pse .pl-s2,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre,.markdown-body .pl-src{color:#df5000}.markdown-body .pl-mo,.markdown-body .pl-v{color:#1d3e81}.markdown-body .pl-id{color:#b52a1d}.markdown-body .pl-ii{background-color:#b52a1d;color:#f8f8f8}.markdown-body .pl-sr .pl-cce{color:#63a35c;font-weight:700}.markdown-body .pl-ml{color:#693a17}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{color:#1d3e81;font-weight:700}.markdown-body .pl-mq{color:teal}.markdown-body .pl-mi{color:#333;font-style:italic}.markdown-body .pl-mb{color:#333;font-weight:700}.markdown-body .pl-md,.markdown-body .pl-mdhf{background-color:#ffecec;color:#bd2c00}.markdown-body .pl-mdht,.markdown-body .pl-mi1{background-color:#eaffea;color:#55a532}.markdown-body .pl-mdr{color:#795da3;font-weight:700}.markdown-body kbd{display:inline-block;padding:3px 5px;font:11px Consolas,"Liberation Mono",Menlo,Courier,monospace;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:1px solid #ccc;border-bottom-color:#bbb;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 #bbb;box-shadow:inset 0 -1px 0 #bbb}.markdown-body .task-list-item+.task-list-item{margin-top:3px}.markdown-body .task-list-item input{float:left;margin:.3em 0 .25em -1.6em;vertical-align:middle}.markdown-body:checked+.radio-label{z-index:1;position:relative;border-color:#4183c4}.editormd-html-preview,.editormd-preview-container{text-align:left;font-size:14px;line-height:1.6;padding:20px;overflow:auto;width:100%;background-color:#fff}.editormd-html-preview blockquote,.editormd-preview-container blockquote{color:#666;border-left:4px solid #ddd;padding-left:20px;margin-left:0;font-size:14px;font-style:italic}.editormd-html-preview p code,.editormd-preview-container p code{margin-left:5px;margin-right:4px}.editormd-html-preview abbr,.editormd-preview-container abbr{background:#ffd}.editormd-html-preview hr,.editormd-preview-container hr{height:1px;border:none;border-top:1px solid #ddd;background:0 0}.editormd-html-preview code,.editormd-preview-container code{border:1px solid #ddd;background:#f6f6f6;padding:3px;-webkit-border-radius:3px;border-radius:3px;font-size:14px}.editormd-html-preview pre,.editormd-preview-container pre{border:1px solid #ddd;background:#f6f6f6;padding:10px;-webkit-border-radius:3px;border-radius:3px}.editormd-html-preview pre code,.editormd-preview-container pre code{padding:0}.editormd-html-preview code,.editormd-html-preview kbd,.editormd-html-preview pre,.editormd-preview-container code,.editormd-preview-container kbd,.editormd-preview-container pre{font-family:"YaHei Consolas Hybrid",Consolas,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,monospace,monospace}.editormd-html-preview table thead tr,.editormd-preview-container table thead tr{background-color:#f8f8f8}.editormd-html-preview p.editormd-tex,.editormd-preview-container p.editormd-tex{text-align:center}.editormd-html-preview span.editormd-tex,.editormd-preview-container span.editormd-tex{margin:0 5px}.editormd-html-preview .emoji,.editormd-preview-container .emoji{width:24px;height:24px}.editormd-html-preview .katex,.editormd-preview-container .katex{font-size:1.4em}.editormd-html-preview .flowchart,.editormd-html-preview .sequence-diagram,.editormd-preview-container .flowchart,.editormd-preview-container .sequence-diagram{margin:0 auto;text-align:center}.editormd-html-preview .flowchart svg,.editormd-html-preview .sequence-diagram svg,.editormd-preview-container .flowchart svg,.editormd-preview-container .sequence-diagram svg{margin:0 auto}.editormd-html-preview .flowchart text,.editormd-html-preview .sequence-diagram text,.editormd-preview-container .flowchart text,.editormd-preview-container .sequence-diagram text{font-size:15px!important;font-family:"YaHei Consolas Hybrid",Consolas,"Microsoft YaHei","Malgun Gothic","Segoe UI",Helvetica,Arial!important}
-/*! Pretty printing styles. Used with prettify.js. */
-.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.clo,.opn,.pun{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.kwd,.tag,.typ{font-weight:700}.str{color:#060}.kwd{color:#006}.com{color:#600;font-style:italic}.typ{color:#404}.lit{color:#044}.clo,.opn,.pun{color:#440}.tag{color:#006}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}.editormd-html-preview pre.prettyprint,.editormd-preview-container pre.prettyprint{padding:10px;border:1px solid #ddd;white-space:pre-wrap;word-wrap:break-word}.editormd-html-preview ol.linenums,.editormd-preview-container ol.linenums{color:#999;padding-left:2.5em}.editormd-html-preview ol.linenums li,.editormd-preview-container ol.linenums li,.wangEditor-container .wangEditor-txt ol li{list-style-type:decimal}.editormd-html-preview ol.linenums li code,.editormd-preview-container ol.linenums li code{border:none;background:0 0;padding:0}.editormd-html-preview .editormd-toc-menu,.editormd-preview-container .editormd-toc-menu{margin:8px 0 12px;display:inline-block}.editormd-html-preview .editormd-toc-menu>.markdown-toc,.editormd-preview-container .editormd-toc-menu>.markdown-toc{position:relative;-webkit-border-radius:4px;border-radius:4px;border:1px solid #ddd;display:inline-block;font-size:1em}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul{width:160%;min-width:180px;position:absolute;left:-1px;top:-2px;z-index:100;padding:0 10px 10px;display:none;background:#fff;border:1px solid #ddd;-webkit-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.2);-ms-box-shadow:0 3px 5px rgba(0,0,0,.2);-o-box-shadow:0 3px 5px rgba(0,0,0,.2);box-shadow:0 3px 5px rgba(0,0,0,.2)}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li ul{width:100%;min-width:180px;border:1px solid #ddd;display:none;background:#fff;-webkit-border-radius:4px;border-radius:4px}.editormd-html-preview .editormd-toc-menu .toc-menu-btn:hover,.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li a:hover,.editormd-preview-container .editormd-toc-menu .toc-menu-btn:hover,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li a:hover{background-color:#f6f6f6}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li a,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li a{color:#666;padding:6px 10px;display:block;-webkit-transition:background-color 500ms ease-out;transition:background-color 500ms ease-out}.editormd-html-preview .editormd-toc-menu>.markdown-toc li,.editormd-preview-container .editormd-toc-menu>.markdown-toc li{position:relative}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul{position:absolute;top:32px;left:10%;display:none;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.2);-ms-box-shadow:0 3px 5px rgba(0,0,0,.2);-o-box-shadow:0 3px 5px rgba(0,0,0,.2);box-shadow:0 3px 5px rgba(0,0,0,.2)}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:after{pointer-events:pointer-events;position:absolute;left:15px;display:block;content:"";width:0;height:0;border:6px solid transparent;border-width:0 6px 6px;z-index:3}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:before{top:-6px}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:before,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:before{pointer-events:pointer-events;position:absolute;left:15px;display:block;content:"";width:0;height:0;border:6px solid transparent;border-width:0 6px 6px;z-index:3}.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:before{top:-6px}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:before,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:before{border-bottom-color:#ccc}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:after{border-bottom-color:#fff;top:-5px}.editormd-html-preview .editormd-toc-menu ul,.editormd-preview-container .editormd-toc-menu ul{list-style:none}.editormd-html-preview .editormd-toc-menu a,.editormd-preview-container .editormd-toc-menu a{text-decoration:none}.editormd-html-preview .editormd-toc-menu h1,.editormd-preview-container .editormd-toc-menu h1{font-size:16px;padding:5px 0 10px 10px;line-height:1;border-bottom:1px solid #eee}.editormd-html-preview .editormd-toc-menu h1 .fa,.editormd-preview-container .editormd-toc-menu h1 .fa{padding-left:10px}.editormd-html-preview .editormd-toc-menu .toc-menu-btn,.editormd-preview-container .editormd-toc-menu .toc-menu-btn{color:#666;min-width:180px;padding:5px 10px;-webkit-border-radius:4px;border-radius:4px;display:inline-block;-webkit-transition:background-color 500ms ease-out;transition:background-color 500ms ease-out}.editormd-html-preview textarea,.editormd-onlyread .editormd-toolbar{display:none}.editormd-html-preview .editormd-toc-menu .toc-menu-btn .fa,.editormd-preview-container .editormd-toc-menu .toc-menu-btn .fa{float:right;padding:3px 0 0 10px;font-size:1.3em}.markdown-body .editormd-toc-menu ul{padding-left:0}.markdown-body .highlight pre,.markdown-body pre{line-height:1.6}hr.editormd-page-break{border:1px dotted #ccc;font-size:0;height:2px}@media only print{hr.editormd-page-break{background:0 0;border:none;height:0}}.editormd-html-preview hr.editormd-page-break{background:0 0;border:none;height:0}.editormd-preview-close-btn{color:#fff;padding:4px 6px;font-size:18px;-webkit-border-radius:500px;border-radius:500px;display:none;background-color:#ccc;position:absolute;top:25px;right:35px;z-index:19;-webkit-transition:background-color 300ms ease-out;transition:background-color 300ms ease-out}.editormd-preview-close-btn:hover{background-color:#999}.editormd-preview-active{width:100%;padding:40px}.editormd-preview-theme-dark{color:#777;background:#2c2827}.editormd-preview-theme-dark .editormd-preview-container{color:#888;background-color:#2c2827}.editormd-preview-theme-dark .editormd-preview-container pre.prettyprint,.editormd-preview-theme-dark .editormd-preview-container table,fieldset{border:none}.editormd-preview-theme-dark .editormd-preview-container blockquote{color:#555;padding:.5em;background:#222;border-color:#333}.editormd-preview-theme-dark .editormd-preview-container abbr{color:#fff;padding:1px 3px;-webkit-border-radius:3px;border-radius:3px;background:#f90}.editormd-preview-theme-dark .editormd-preview-container code{color:#fff;border:none;padding:1px 3px;-webkit-border-radius:3px;border-radius:3px;background:#5a9600}.editormd-preview-theme-dark .editormd-preview-container .fa-emoji{color:#b4bf42}.editormd-preview-theme-dark .editormd-preview-container .katex{color:#fec93f}.editormd-preview-theme-dark .editormd-toc-menu>.markdown-toc{background:#fff;border:none}.editormd-preview-theme-dark .editormd-toc-menu>.markdown-toc h1{border-color:#ddd}.editormd-preview-theme-dark .markdown-body h1,.editormd-preview-theme-dark .markdown-body h2,.editormd-preview-theme-dark .markdown-body hr{border-color:#222}.editormd-preview-theme-dark pre{color:#999;background-color:#111;background-color:rgba(0,0,0,.4)}.editormd-preview-theme-dark pre .pln{color:#999}.editormd-preview-theme-dark li.L1,.editormd-preview-theme-dark li.L3,.editormd-preview-theme-dark li.L5,.editormd-preview-theme-dark li.L7,.editormd-preview-theme-dark li.L9{background:0 0}.editormd-preview-theme-dark [class*=editormd-logo]{color:#2196f3}.editormd-preview-theme-dark .sequence-diagram text{fill:#fff}.editormd-preview-theme-dark .sequence-diagram path,.editormd-preview-theme-dark .sequence-diagram rect{color:#fff;fill:#64d1cb;stroke:#64d1cb}.editormd-preview-theme-dark .flowchart path,.editormd-preview-theme-dark .flowchart rect{stroke:#a6c6ff}.editormd-preview-theme-dark .flowchart rect{fill:#a6c6ff}.editormd-preview-theme-dark .flowchart text{fill:#5879b4}@media screen{.editormd-preview-theme-dark .str{color:#080}.editormd-preview-theme-dark .kwd{color:#f90}.editormd-preview-theme-dark .com{color:#444}.editormd-preview-theme-dark .typ{color:#606}.editormd-preview-theme-dark .lit{color:#066}.editormd-preview-theme-dark .clo,.editormd-preview-theme-dark .opn,.editormd-preview-theme-dark .pun{color:#660}.editormd-preview-theme-dark .tag{color:#f90}.editormd-preview-theme-dark .atn{color:#6c95f5}.editormd-preview-theme-dark .atv{color:#080}.editormd-preview-theme-dark .dec,.editormd-preview-theme-dark .var{color:#008ba7}.editormd-preview-theme-dark .fun{color:red}}.editormd-onlyread .CodeMirror{margin-top:0}.editormd-onlyread .editormd-preview{top:0}.editormd-fullscreen{position:fixed;top:0;left:0;border:none;margin:0 auto}.editormd-theme-dark{border-color:#1a1a17}.editormd-theme-dark .editormd-toolbar{background:#1a1a17;border-color:#1a1a17}.editormd-theme-dark .editormd-menu>li>a{color:#777;border-color:#1a1a17}.editormd-theme-dark .editormd-menu>li>a.active,.editormd-theme-dark .editormd-menu>li>a:hover{border-color:#333;background:#333}.editormd-theme-dark .editormd-menu>li.divider{border-right:1px solid #111}.editormd-theme-dark .CodeMirror{border-right:1px solid rgba(0,0,0,.1)}@font-face{font-family:"iconfont";src:url(../assets/font/iconfont.eot?t=50);src:url(../assets/font/iconfont.eot?t=50#iefix) format("embedded-opentype"),url(../assets/font/iconfont.woff?t=500) format("woff"),url(../assets/font/iconfont.ttf?t=500) format("truetype"),url(../assets/font/iconfont.svg?t=500#iconfont) format("svg")}@font-face{font-family:'icomoon';src:url(../assets/font/icomoon.eot?-qdfu1s);src:url(../assets/font/icomoon.eot?#iefix-qdfu1s) format("embedded-opentype"),url(../assets/font/icomoon.ttf?-qdfu1s) format("truetype"),url(../assets/font/icomoon.woff?-qdfu1s) format("woff"),url(../assets/font/icomoon.svg?-qdfu1s#icomoon) format("svg");font-weight:400;font-style:normal}.iconfont{font-family:"iconfont"!important;font-style:normal;-webkit-font-smoothing:antialiased;-webkit-text-stroke-width:.2px;-moz-osx-font-smoothing:grayscale}.icon-circle:before{content:"\e635"}.icon-htmal5icon24:before{content:"\e63c"}.icon-chrome:before{content:"\e665"}.icon-coding:before{content:"\e62e"}.icon-edge:before{content:"\e7de"}.icon-shoucang:before{content:"\e667"}.icon-github:before{content:"\e6a5"}.icon-zhifubao:before{content:"\e666"}.icon-weixinzhifu-copy:before{content:"\e615"}.icon-shiyanshiguanli:before{content:"\e65e"}.icon-gitoschina:before{content:"\e607"}.icon-qq:before{content:"\e69e"}.icon-source-branch:before{content:"\e8b6"}.icon-firefox:before{content:"\e6ab"}.icon-eoLinkerAMS:before{content:"\e624"}.icon-bijibendiannao:before{content:"\eabb"}.icon-bianjibiaoge:before{content:"\eabc"}.icon-chizi:before{content:"\eabd"}.icon-biaoqian:before{content:"\eabe"}.icon-dayinji:before{content:"\eabf"}.icon-baocun:before{content:"\eac0"}.icon-bianji:before{content:"\eac1"}.icon-daochu:before{content:"\eac2"}.icon-daoru:before{content:"\eac3"}.icon-diannao:before{content:"\eac4"}.icon-fuzhi:before{content:"\eac5"}.icon-ding:before{content:"\eac6"}.icon-jianqie:before{content:"\eac7"}.icon-jianpan:before{content:"\eac8"}.icon-jiesuo:before{content:"\eac9"}.icon-shaixuan:before{content:"\eaca"}.icon-shouji:before{content:"\eacb"}.icon-suoding:before{content:"\eacc"}.icon-tupian:before{content:"\eacd"}.icon-tianjiafujian:before{content:"\eace"}.icon-wenben:before{content:"\eacf"}.icon-bangongbao:before{content:"\ead0"}.icon-shu:before{content:"\ead1"}.icon-wenjianjia:before{content:"\ead2"}.icon-touyingyi:before{content:"\ead3"}.icon-cangku_cangchuguanli:before{content:"\ead4"}.icon-cangku_kucun:before{content:"\ead5"}.icon-cangku_kucunxiangqing:before{content:"\ead6"}.icon-cangku:before{content:"\ead7"}.icon-cangku_zhongzhuanchuzhan:before{content:"\ec8c"}.icon-cangku_cangneishicao:before{content:"\ec8e"}.icon-fuwuguanli:before{content:"\ec8a"}.icon-fuwuliu:before{content:"\ead8"}.icon-cangku_daozhan:before{content:"\ec8f"}.icon-cangku_kucunshuaxin:before{content:"\ec90"}.icon-guanliyuanrenzheng:before{content:"\ead9"}.icon-jinzhidengji:before{content:"\eada"}.icon-dianbiao:before{content:"\eadb"}.icon-guanliyuansousuo:before{content:"\eadc"}.icon-kuaisugongzuoliu:before{content:"\eadd"}.icon-saomafuquan:before{content:"\eade"}.icon-fuwuxunhuanguanli:before{content:"\eadf"}.icon-shebeidadian:before{content:"\ec92"}.icon-shuibiao:before{content:"\eae0"}.icon-shebeisousuo:before{content:"\eae1"}.icon-shebeijiance:before{content:"\eae2"}.icon-shuiweichuanganqi:before{content:"\eae3"}.icon-xunjianweixiu:before{content:"\ec93"}.icon-yemianliu:before{content:"\eae4"}.icon-yichangshangbao:before{content:"\ec8d"}.icon-zhongkong:before{content:"\ec94"}.icon-weixiufuwu:before{content:"\eae5"}.icon-wenshiduchuanganqi:before{content:"\eae6"}.icon-duoxuanxuanzhong:before{content:"\eae7"}.icon-bofang:before{content:"\eae8"}.icon-duibi:before{content:"\eae9"}.icon-huojianjiasu:before{content:"\eaea"}.icon-gouwudai:before{content:"\eaeb"}.icon-gouwu:before{content:"\eaec"}.icon-danxuanweixuanzhong:before{content:"\eaed"}.icon-danxuanxuanzhong:before{content:"\eaee"}.icon-jiqiren:before{content:"\eaef"}.icon-jinxianshibutong:before{content:"\eaf0"}.icon-kefu:before{content:"\eaf1"}.icon-leida-faxianx:before{content:"\eaf2"}.icon-lianjie:before{content:"\eaf3"}.icon-duoxuanweixuanzhong:before{content:"\eaf4"}.icon-liangliangduibi:before{content:"\eaf5"}.icon-quxiaolianjie:before{content:"\eaf6"}.icon-liwu:before{content:"\eaf7"}.icon-shanguangdeng:before{content:"\eaf8"}.icon-shengyin:before{content:"\eaf9"}.icon-renlianshibie:before{content:"\eafa"}.icon-tingzhi:before{content:"\eafb"}.icon-tanhao:before{content:"\eafc"}.icon-wenhao:before{content:"\eafd"}.icon-xinxi:before{content:"\eafe"}.icon-shounadaohang:before{content:"\eaff"}.icon-yinliang:before{content:"\eb00"}.icon-yingwen:before{content:"\eb01"}.icon-yuyin:before{content:"\ec99"}.icon-yuechi:before{content:"\eb02"}.icon-yunsuancaozuo:before{content:"\eb03"}.icon-zhediedaohang:before{content:"\eb04"}.icon-zhinanzhen:before{content:"\eb05"}.icon-zhongwen:before{content:"\eb06"}.icon-zanting:before{content:"\eb07"}.icon-zhuti_yifu:before{content:"\eb08"}.icon-zhendong:before{content:"\eb09"}.icon-zhuti_tiaosepan:before{content:"\eb0a"}.icon-mofabang:before{content:"\eb0b"}.icon-zuanshi:before{content:"\eb0c"}.icon-anniu_guanbi:before{content:"\eb0d"}.icon-anquan:before{content:"\eb0e"}.icon-bangzhu:before{content:"\eb0f"}.icon-biaoge:before{content:"\eb10"}.icon-anniu_xuanzhong:before{content:"\eb11"}.icon-chexiao:before{content:"\eb12"}.icon-shouye:before{content:"\eb13"}.icon-duihao:before{content:"\eb14"}.icon-erweima:before{content:"\eb15"}.icon-caidan:before{content:"\eb16"}.icon-guanbi:before{content:"\eb17"}.icon-guanyu:before{content:"\eb18"}.icon-cengji:before{content:"\eb19"}.icon-dengyu:before{content:"\eb1a"}.icon-daohang:before{content:"\eb1b"}.icon-jiahao:before{content:"\eb1c"}.icon-jiazai_dan:before{content:"\eb1d"}.icon-jiazai_shuaxin:before{content:"\eb1e"}.icon-jieshaoxinxi:before{content:"\eb1f"}.icon-jianhao:before{content:"\eb20"}.icon-jinyong:before{content:"\eb21"}.icon-kaiguan:before{content:"\eb22"}.icon-jinggao:before{content:"\eb23"}.icon-lishijilu:before{content:"\eb24"}.icon-linggan:before{content:"\eb25"}.icon-liebiao:before{content:"\eb26"}.icon-pinleijianshao:before{content:"\eb27"}.icon-pinleishanchu:before{content:"\eb28"}.icon-pinleizengjia:before{content:"\eb29"}.icon-kongzhizhongxin:before{content:"\eb2a"}.icon-shanchu:before{content:"\eb2b"}.icon-saoyisao:before{content:"\eb2c"}.icon-shipin:before{content:"\eb2d"}.icon-quanjushezhi:before{content:"\eb2e"}.icon-shitujuzhen:before{content:"\eb2f"}.icon-shuliang-zengjia:before{content:"\eb30"}.icon-shuaxin:before{content:"\eb31"}.icon-shuliangjianshao:before{content:"\eb32"}.icon-sousuo:before{content:"\eb33"}.icon-tuwen:before{content:"\eb34"}.icon-xinzengdaohangliebiao:before{content:"\ec98"}.icon-Androidgengduo:before{content:"\eb35"}.icon-iosgengduo:before{content:"\eb36"}.icon-xiangji:before{content:"\eb37"}.icon-yemiankuangjia:before{content:"\eb38"}.icon-yingyongAPP:before{content:"\eb39"}.icon-anniu_jiantoushouqi:before{content:"\eb3a"}.icon-anniu-jiantouxiangyou:before{content:"\eb3b"}.icon-jiantou_liebiaoxiangyou:before{content:"\eb3c"}.icon-anniu_jiantouzhankai:before{content:"\eb3d"}.icon-jiantou_liebiaoshouqi:before{content:"\eb3e"}.icon-jiantou_liebiaoxiangzuo:before{content:"\eb3f"}.icon-jiantou_liebiaozhankai:before{content:"\eb40"}.icon-jiantou_shangyiye:before{content:"\eb41"}.icon-anniu_jiantouxiangzuo:before{content:"\eb42"}.icon-jiantou_xiayiye:before{content:"\eb43"}.icon-jiantou_xiangyou:before{content:"\eb44"}.icon-jiantou_xiangzuo:before{content:"\eb45"}.icon-jiantou_xiangyouliangci:before{content:"\eb46"}.icon-jiantou_shangxiaqiehuan:before{content:"\eb47"}.icon-jiantou_yemian_xiangshang:before{content:"\eb48"}.icon-jiantou_xiangxia:before{content:"\eb49"}.icon-jiantou_xiangshang:before{content:"\eb4a"}.icon-jiantou_xiangzuoliangci:before{content:"\eb4b"}.icon-jiantou_yemian_xiangxia:before{content:"\eb4c"}.icon-jiantou_yemian_xiangyou:before{content:"\eb4d"}.icon-jiantou_youshang:before{content:"\eb4e"}.icon-jiantou_zuoshang:before{content:"\eb4f"}.icon-jiantou_youxia:before{content:"\eb50"}.icon-jiantou_zuoyouqiehuan:before{content:"\eb51"}.icon-jiaobiaoweixuanzhong:before{content:"\eb52"}.icon-jiaobiaoxuanzhong:before{content:"\eb53"}.icon-quxiaoquanping:before{content:"\eb54"}.icon-sanjiaoxing_shang:before{content:"\eb55"}.icon-quanping:before{content:"\eb56"}.icon-sanjiaoxing:before{content:"\eb57"}.icon-xiazai:before{content:"\eb58"}.icon-xuanzeqishouqi:before{content:"\eb59"}.icon-xiangzuo:before{content:"\eb5a"}.icon-xuanzeqixiayige:before{content:"\eb5b"}.icon-xuanzeqizhankai:before{content:"\eb5c"}.icon-zhiding:before{content:"\eb5d"}.icon-dunpaibaowei:before{content:"\eb5e"}.icon-dunpaibaoxianrenzheng:before{content:"\eb5f"}.icon-huobiliu:before{content:"\ec9b"}.icon-jisuanqi:before{content:"\eb60"}.icon-jiekuan:before{content:"\ec9c"}.icon-jinbi:before{content:"\eb61"}.icon-cunkuan:before{content:"\ec9e"}.icon-meiyuan:before{content:"\eb62"}.icon-qianbao:before{content:"\eb63"}.icon-yinhangqia:before{content:"\eb64"}.icon-zhangdan_xiangqing:before{content:"\eb65"}.icon-zhangdan_quxiao:before{content:"\eb66"}.icon-zhangdan_xinzeng:before{content:"\eb67"}.icon-jinrongguanli:before{content:"\eca1"}.icon-zhangdan-wancheng:before{content:"\eb68"}.icon-zijin_dongjie:before{content:"\eca2"}.icon-zijin:before{content:"\eca3"}.icon-biaoqing:before{content:"\eb69"}.icon-anniu-zan:before{content:"\eb6a"}.icon-biaoqing_xiao:before{content:"\eb6b"}.icon-chengchang:before{content:"\eb6c"}.icon-dianhua:before{content:"\eb6d"}.icon-duanxin:before{content:"\eb6e"}.icon-gerentouxiang:before{content:"\eb6f"}.icon-fenxiang:before{content:"\eb70"}.icon-qiandao:before{content:"\eca9"}.icon-qunzu:before{content:"\eb71"}.icon-biaoqing_beishang:before{content:"\eb72"}.icon-eo_shoucang:before{content:"\eb73"}.icon-tianjiahaoyou:before{content:"\eb74"}.icon-xiai:before{content:"\eb75"}.icon-zan:before{content:"\eb76"}.icon-daibanrenwu_quxiao:before{content:"\eb77"}.icon-daibanrenwu:before{content:"\eb78"}.icon-naozhong:before{content:"\eb79"}.icon-shijian:before{content:"\eb7a"}.icon-riqi:before{content:"\eb7b"}.icon-rili:before{content:"\ec9f"}.icon-shuzhuangtu:before{content:"\eb7c"}.icon-yun:before{content:"\eb7d"}.icon-bingtu:before{content:"\eb7e"}.icon-yunshangchuan:before{content:"\eb7f"}.icon-yunxiazai:before{content:"\eb80"}.icon-zhexiantu:before{content:"\eb81"}.icon-zhuzhuangtu:before{content:"\eb82"}.icon-baoguo_lanshou:before{content:"\eb83"}.icon-baoguo_dabao:before{content:"\eb84"}.icon-baoguo_hezi:before{content:"\eb85"}.icon-baoguo_quxiaoshouhuo:before{content:"\eb86"}.icon-baoguo_shouhuo:before{content:"\eb87"}.icon-didiandingwei:before{content:"\eb88"}.icon-ditu_diqiu:before{content:"\eb89"}.icon-baoguo_fahuo:before{content:"\eb8a"}.icon-ditu_dingwei:before{content:"\eb8b"}.icon-baoguo:before{content:"\eb8c"}.icon-gaojijibao:before{content:"\eb8d"}.icon-fenjianguocheng:before{content:"\eb8e"}.icon-guizi:before{content:"\eca5"}.icon-huoche:before{content:"\eb8f"}.icon-fuwu:before{content:"\eb90"}.icon-jiankong:before{content:"\eb91"}.icon-jibao:before{content:"\ecb8"}.icon-jianzhu:before{content:"\eca6"}.icon-jingliren:before{content:"\eb92"}.icon-huopinfenliu:before{content:"\eb93"}.icon-quxiaojibao:before{content:"\ecb9"}.icon-kuaidiyuan:before{content:"\eb94"}.icon-sandengfen:before{content:"\eca8"}.icon-shijuedingwei:before{content:"\eb95"}.icon-wuliudanao:before{content:"\ecaa"}.icon-yizhan:before{content:"\ecab"}.icon-sidengfen:before{content:"\ecac"}.icon-CPhezuo:before{content:"\ecad"}.icon-yibiaopan:before{content:"\eb96"}.icon-xiaoxi:before{content:"\eb97"}.icon-xinwen:before{content:"\eb98"}.icon-tongzhizhongxin:before{content:"\eb99"}.icon-youjian:before{content:"\ec88"}.icon-dengchu:before{content:"\ecaf"}.icon-yanjing_yincang:before{content:"\eb9a"}.icon-yanjing_xianshi:before{content:"\eb9b"}.icon-baocun_o:before{content:"\eb9c"}.icon-biaoqian_o:before{content:"\eb9d"}.icon-bianjibiaoge_o:before{content:"\eb9e"}.icon-dayinji_o:before{content:"\eb9f"}.icon-chizi_o:before{content:"\eba0"}.icon-bangongbao_o:before{content:"\eba1"}.icon-daoru_o:before{content:"\eba2"}.icon-diannao_o:before{content:"\eba3"}.icon-bianji_o:before{content:"\eba4"}.icon-bijibendiannao_o:before{content:"\eba5"}.icon-ding_o:before{content:"\eba6"}.icon-jianpan_o:before{content:"\eba7"}.icon-jianqie_o:before{content:"\eba8"}.icon-shaixuan_o:before{content:"\eba9"}.icon-jiesuo_o:before{content:"\ebaa"}.icon-daochu_o:before{content:"\ebab"}.icon-shouji_o:before{content:"\ebac"}.icon-tianjiafujian_o:before{content:"\ebad"}.icon-shu_o:before{content:"\ebae"}.icon-fuzhi_o:before{content:"\ebaf"}.icon-wenben_o:before{content:"\ebb0"}.icon-touyingyi_o:before{content:"\ebb1"}.icon-wenjianjia_o:before{content:"\ebb2"}.icon-tupian_o:before{content:"\ebb3"}.icon-suoding_o:before{content:"\ebb4"}.icon-cangku_kucunxiangqing_o:before{content:"\ebb5"}.icon-cangku_daozhan_o:before{content:"\ebb6"}.icon-cangku_kucun_o:before{content:"\ebb7"}.icon-dianbiao_o:before{content:"\ebb8"}.icon-fuwuliu_o:before{content:"\ebb9"}.icon-fuwuguanli_o:before{content:"\ebba"}.icon-gongzuoliu_o:before{content:"\ebbb"}.icon-fuwuxunhuanguanli_o:before{content:"\ebbc"}.icon-guanliyuanrenzheng_o:before{content:"\ebbd"}.icon-jinzhidengji_o:before{content:"\ebbe"}.icon-kuaisugongzuoliu_o:before{content:"\ebbf"}.icon-saomafuquan_o:before{content:"\ebc0"}.icon-guanliyuansousuo_o:before{content:"\ebc1"}.icon-shebeijiance_o:before{content:"\ebc2"}.icon-shebeisousuo_o:before{content:"\ebc3"}.icon-shuibiao_o:before{content:"\ebc4"}.icon-saomajiahuiche_o:before{content:"\ebc5"}.icon-shebeidadian_o:before{content:"\ebc6"}.icon-shuiweichuanganqi_o:before{content:"\ebc7"}.icon-yichangshangbao_o:before{content:"\ebc8"}.icon-xunjianweixiu_o:before{content:"\ebc9"}.icon-yemianliu_o:before{content:"\ebca"}.icon-weixiufuwu_o:before{content:"\ebcb"}.icon-zhongkong_o:before{content:"\ebcc"}.icon-danxuanweixuanzhong_o:before{content:"\ebcd"}.icon-bofang_o:before{content:"\ebce"}.icon-duoxuanweixuanzhong_o:before{content:"\ebcf"}.icon-duoxuanxuanzhong_o:before{content:"\ebd0"}.icon-gouwudai_o:before{content:"\ebd1"}.icon-gouwu_o:before{content:"\ebd2"}.icon-huojianjiasu_o:before{content:"\ebd3"}.icon-jiqiren_o:before{content:"\ebd4"}.icon-kefu_o:before{content:"\ebd5"}.icon-lanya_o:before{content:"\ebd6"}.icon-shengyin_o:before{content:"\ebd7"}.icon-leida-faxian_o:before{content:"\ebd8"}.icon-danxuanxuanzhong_o:before{content:"\ebd9"}.icon-lianjie_o:before{content:"\ebda"}.icon-liwu_o:before{content:"\ebdb"}.icon-liangdu_o:before{content:"\ebdc"}.icon-liangliangduibi_o:before{content:"\ebdd"}.icon-renlianshibie_o:before{content:"\ebde"}.icon-quxiaolianjie_o:before{content:"\ebdf"}.icon-jinxianshibutong_o:before{content:"\ebe0"}.icon-shanguangdeng_o:before{content:"\ebe1"}.icon-tanhao_o:before{content:"\ebe2"}.icon-wenhao_o:before{content:"\ebe3"}.icon-xinxi_o:before{content:"\ebe4"}.icon-tingzhi_o:before{content:"\ebe5"}.icon-yuechi_o:before{content:"\ebe6"}.icon-yingwen_o:before{content:"\ebe7"}.icon-yuyin_o:before{content:"\ebe8"}.icon-yunsuancaozuo_o:before{content:"\ebe9"}.icon-zanting_o:before{content:"\ebea"}.icon-shounadaohang_o:before{content:"\ebeb"}.icon-zhediedaohang_o:before{content:"\ebec"}.icon-zhuti_tiaosepan_o:before{content:"\ebed"}.icon-zhuti_yifu_o:before{content:"\ebee"}.icon-zhuti_o:before{content:"\ebef"}.icon-zuanshi_o:before{content:"\ebf0"}.icon-zhongwen_o:before{content:"\ebf1"}.icon-zhinanzhen_o:before{content:"\ebf2"}.icon-anquan_o:before{content:"\ebf3"}.icon-caidan_o:before{content:"\ebf4"}.icon-anniu_xuanzhong_o:before{content:"\ebf5"}.icon-bangzhu_o:before{content:"\ebf6"}.icon-cengji_o:before{content:"\ebf7"}.icon-chexiao_o:before{content:"\ebf8"}.icon-daohang_o:before{content:"\ebf9"}.icon-duihao_o:before{content:"\ebfa"}.icon-anniu_guanbi_o:before{content:"\ebfb"}.icon-erweima_o:before{content:"\ebfc"}.icon-guanbi_o:before{content:"\ebfd"}.icon-biaoge_o:before{content:"\ebfe"}.icon-guanyu_o:before{content:"\ebff"}.icon-jiahao_o:before{content:"\ec00"}.icon-dengyu_o:before{content:"\ec01"}.icon-jiazai_shuang_o:before{content:"\ec02"}.icon-jianhao_o:before{content:"\ec03"}.icon-jieshaoxinxi_o:before{content:"\ec04"}.icon-kaiguan_o:before{content:"\ec05"}.icon-jiazai_shuaxin_o:before{content:"\ec06"}.icon-lishijilu_o:before{content:"\ec07"}.icon-liebiao_o:before{content:"\ec08"}.icon-linggan_o:before{content:"\ec09"}.icon-jinyong_o:before{content:"\ec0a"}.icon-pinleishanchu_o:before{content:"\ec0b"}.icon-pinleijianshao_o:before{content:"\ec0c"}.icon-kongzhizhongxin_o:before{content:"\ec0d"}.icon-pinleizengjia_o:before{content:"\ec0e"}.icon-renwuzhongxin_o:before{content:"\ec0f"}.icon-quanjushezhi_o:before{content:"\ec10"}.icon-jinggao_o:before{content:"\ec11"}.icon-saoyisao_o:before{content:"\ec12"}.icon-shipin_o:before{content:"\ec13"}.icon-shouye_o:before{content:"\ec14"}.icon-shuliang-zengjia_o:before{content:"\ec15"}.icon-shuaxin_o:before{content:"\ec16"}.icon-shanchu_o:before{content:"\ec17"}.icon-tishi_o:before{content:"\ec18"}.icon-tuwen_o:before{content:"\ec19"}.icon-shitujuzhen_o:before{content:"\ec1a"}.icon-xinzengdaohangliebiao_o:before{content:"\ec1b"}.icon-sousuo_o:before{content:"\ec1c"}.icon-shuliangjianshao_o:before{content:"\ec1d"}.icon-yemiankuangjia_o:before{content:"\ec1e"}.icon-xiangji_o:before{content:"\ec1f"}.icon-yingyongAPP_o:before{content:"\ec20"}.icon-anniu_jiantoushouqi_o:before{content:"\ec21"}.icon-anniu_jiantouxiangzuo_o:before{content:"\ec22"}.icon-anniu_jiantouzhankai_o:before{content:"\ec23"}.icon-jiantou_liebiaoshouqi_o:before{content:"\ec24"}.icon-jiantou_liebiaoxiangyou_o:before{content:"\ec25"}.icon-jiantou_liebiaozhankai_o:before{content:"\ec26"}.icon-anniu-jiantouxiangyou_o:before{content:"\ec27"}.icon-xuanzeqizhankai_o:before{content:"\ec28"}.icon-jiantou_zuoshang_o:before{content:"\ec29"}.icon-jiantou_liebiaoxiangzuo_o:before{content:"\ec2a"}.icon-jiantou_shangyiye_o:before{content:"\ec2b"}.icon-jiantou_xiayiye_o:before{content:"\ec2c"}.icon-jiantou_xiangshang_o:before{content:"\ec2d"}.icon-jiantou_xiangxia_o:before{content:"\ec2e"}.icon-jiantou_xiangyouliangci_o:before{content:"\ec2f"}.icon-jiantou_shangxiaqiehuan_o:before{content:"\ec30"}.icon-jiantou_xiangzuo_o:before{content:"\ec31"}.icon-jiantou_yemian_xiangshang_o:before{content:"\ec32"}.icon-jiantou_xiangzuoliangci_o:before{content:"\ec33"}.icon-jiantou_yemian_xiangyou_o:before{content:"\ec34"}.icon-jiantou_youshang_o:before{content:"\ec35"}.icon-jiantou_xiangyou_o:before{content:"\ec36"}.icon-jiantou_yemian_xiangzuo_o:before{content:"\ec37"}.icon-jiantou_youxia_o:before{content:"\ec38"}.icon-jiantou_zuoyouqiehuan_o:before{content:"\ec39"}.icon-jiantou_yemian_xiangxia_o:before{content:"\ec3a"}.icon-jiaobiaoweixuanzhong_o:before{content:"\ec3b"}.icon-quxiaoquanping_o:before{content:"\ec3c"}.icon-jiaobiaoxuanzhong_o:before{content:"\ec3d"}.icon-sanjiaoxing_shang_o:before{content:"\ec3e"}.icon-quanping_o:before{content:"\ec3f"}.icon-xiangzuo_o:before{content:"\ec40"}.icon-shangxiazhankai_o:before{content:"\ec41"}.icon-xuanzeqishouqi_o:before{content:"\ec42"}.icon-xuanzeqixiayige_o:before{content:"\ec43"}.icon-sanjiaoxing_o:before{content:"\ec44"}.icon-shangchuan_o:before{content:"\ec45"}.icon-xiazai_o:before{content:"\ec46"}.icon-zhiding_o:before{content:"\ec47"}.icon-dunpaibaowei_o:before{content:"\ec48"}.icon-huobiliu_o:before{content:"\ecba"}.icon-dunpaibaoxianzhiliang_o:before{content:"\ec49"}.icon-jiekuan_o:before{content:"\ecbb"}.icon-jinrongguanli_o:before{content:"\ecbc"}.icon-cunkuan_o:before{content:"\ecbd"}.icon-dunpaibaoxianrenzheng_o:before{content:"\ec4a"}.icon-jinbi_o:before{content:"\ec4b"}.icon-zhangdan_quxiao_o:before{content:"\ecbf"}.icon-zhangdan_kong_o:before{content:"\ecc0"}.icon-zhangdan_xinzeng_o:before{content:"\ec4c"}.icon-zhangdan-wancheng_o:before{content:"\ec4d"}.icon-zijin_dongjie_o:before{content:"\ecc3"}.icon-yinhangqia_o:before{content:"\ec4e"}.icon-zijin_o:before{content:"\ecc4"}.icon-zhangdan_xiangqing_o:before{content:"\ec4f"}.icon-anniu-zan_o:before{content:"\ec50"}.icon-biaoqing_xiao_o:before{content:"\ec51"}.icon-chengchang_o:before{content:"\ec52"}.icon-duanxin_o:before{content:"\ec53"}.icon-biaoqing_beishang_o:before{content:"\ec54"}.icon-fenxiang_o:before{content:"\ec55"}.icon-biaoqing_o:before{content:"\ec56"}.icon-gerentouxiang_o:before{content:"\ec57"}.icon-qiandao_o:before{content:"\ecc7"}.icon-qunzu_o:before{content:"\ec58"}.icon-dianhua_o:before{content:"\ec59"}.icon-tianjiahaoyou_o:before{content:"\ec5a"}.icon-shoucang_o:before{content:"\ec5b"}.icon-xiai_o:before{content:"\ec5c"}.icon-zan_o:before{content:"\ec5d"}.icon-naozhong_o:before{content:"\ec5e"}.icon-shijian_o:before{content:"\ec5f"}.icon-riqi_o:before{content:"\ec60"}.icon-daibanrenwu_o:before{content:"\ec61"}.icon-daibanrenwu_quxiao_o:before{content:"\ec62"}.icon-shuzhuangtu_o:before{content:"\ec63"}.icon-zhexiantu_o:before{content:"\ec64"}.icon-yun_o:before{content:"\ec65"}.icon-yunshangchuan_o:before{content:"\ec66"}.icon-yunxiazai_o:before{content:"\ec67"}.icon-bingtu_o:before{content:"\ec68"}.icon-zhuzhuangtu_o:before{content:"\ec69"}.icon-baoguo_hezi_o:before{content:"\ec6a"}.icon-baoguo_dabao_o:before{content:"\ec6b"}.icon-baoguo_quxiaoshouhuo_o:before{content:"\ec6c"}.icon-baoguo_shouhuo_o:before{content:"\ec6d"}.icon-baoguo_shouna_o:before{content:"\ec6e"}.icon-baoguo_o:before{content:"\ec6f"}.icon-baoguo_lanshou_o:before{content:"\ec70"}.icon-didiandingwei_o:before{content:"\ec71"}.icon-ditu_dingwei_o:before{content:"\ec72"}.icon-ditu_diqiu_o:before{content:"\ec73"}.icon-fenjianguocheng_o:before{content:"\ec74"}.icon-fuwu_o:before{content:"\ec75"}.icon-gaojijibao_o:before{content:"\ec76"}.icon-huopinfenliu_o:before{content:"\ec77"}.icon-jiankong_o:before{content:"\ec78"}.icon-kuaidiyuan_o:before{content:"\ec79"}.icon-jianzhu_o:before{content:"\ecd6"}.icon-kuaidiyuanguanli_o:before{content:"\ec7a"}.icon-jibao_o:before{content:"\ecd7"}.icon-sandengfen_o:before{content:"\ecd8"}.icon-shijuedingwei_o:before{content:"\ec7b"}.icon-jingliren_o:before{content:"\ec7c"}.icon-sidengfen_o:before{content:"\ecdb"}.icon-quxiaojibao_o:before{content:"\ecdc"}.icon-wuliudanao_o:before{content:"\ecdd"}.icon-CPhezuo_o:before{content:"\ec7d"}.icon-yibiaopan_o:before{content:"\ec7e"}.icon-xinwen_o:before{content:"\ec7f"}.icon-xiaoxi_o:before{content:"\ec80"}.icon-youjian_o:before{content:"\ece0"}.icon-tongzhizhongxin_o:before{content:"\ec81"}.icon-dengchu_o:before{content:"\ec82"}.icon-yanjing_xianshi_o:before{content:"\ec83"}.icon-gerenxinxi_o:before{content:"\ec84"}.icon-yanjing_yincang_o:before{content:"\ec85"}.icon-anniu_gerenzhongxin_o:before{content:"\ec86"}.icon-huadongkaiguan-guanbi:before{content:"\e606"}.icon-huadongkaiguan-dakai:before{content:"\ec87"}.icon-api:before{content:"\e61e"}.icon-source-branch-copy:before{content:"\ece1"}.icon-api-copy:before{content:"\ece2"}.eo-modal-header .icon-guanbi:hover,menu-Default-Common-Component .common_menu_ul .common-btn:hover,menu-Default-Common-Component .common_menu_ul .fun-list-li:hover,overview-Product-Component .btn-edit-project:hover,overview-Product-Component .common-btn:hover{-webkit-transition:all .2s cubic-bezier(.645,.045,.355,1);transition:all .2s cubic-bezier(.645,.045,.355,1)}list-default-common-component .footer{background-color:#f8f8f8;padding:0 15px;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;height:40px;line-height:40px}list-default-common-component .footer .divide-span{border-right:1px solid #d9d9d9;height:30px;line-height:30px}list-default-common-component .footer,list-default-common-component .pagination{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}list-default-common-component .pagination .first-page,list-default-common-component .pagination .last-page{-webkit-border-radius:3px;border-radius:3px}list-default-common-component .pageFooter .pagination>.active,list-default-common-component .pageFooter .pagination>.active:focus,list-default-common-component .pageFooter .pagination>.active:hover{background-color:#333}list-default-common-component .pageFooter .pagination>.active a,list-default-common-component .pageFooter .pagination>.active:focus a,list-default-common-component .pageFooter .pagination>.active:hover a{color:#fff}list-default-common-component .pagination-next .iconfont,list-default-common-component .pagination-prev .iconfont{font-weight:700}list-default-common-component .pagination-prev{margin-right:15px}list-default-common-component .pagination-next{margin-left:15px}list-default-common-component .pagination-page{width:25px;height:25px;line-height:25px;-webkit-border-radius:3px;border-radius:3px;margin-right:5px}.eo_theme_btn_danger,.eo_theme_btn_default,.eo_theme_btn_delete,.eo_theme_btn_info,.eo_theme_btn_orange,.eo_theme_btn_success,.eo_theme_btn_warning{height:32px;line-height:32px;cursor:pointer;-webkit-border-radius:4px;border-radius:4px;font-size:13px;padding:0 10px}.btn_static_test_utac,.eo_theme_btn_disabled{height:32px;line-height:32px;-webkit-border-radius:4px;border-radius:4px;font-size:13px;padding:0 10px}.btn_static_test_utac{cursor:pointer}.btn_static_test_utac .iconfont,.eo_theme_btn_danger .iconfont,.eo_theme_btn_default .iconfont,.eo_theme_btn_delete .iconfont,.eo_theme_btn_disabled .iconfont,.eo_theme_btn_info .iconfont,.eo_theme_btn_orange .iconfont,.eo_theme_btn_success .iconfont,.eo_theme_btn_warning .iconfont{font-size:14px}.btn_static_test_utac .iconfont+span,.eo_theme_btn_danger .iconfont+span,.eo_theme_btn_default .iconfont+span,.eo_theme_btn_delete .iconfont+span,.eo_theme_btn_disabled .iconfont+span,.eo_theme_btn_info .iconfont+span,.eo_theme_btn_orange .iconfont+span,.eo_theme_btn_success .iconfont+span,.eo_theme_btn_warning .iconfont+span{margin-left:10px}.btn_static_test_utac span:nth-last-child(n+2),.eo_theme_btn_danger span:nth-last-child(n+2),.eo_theme_btn_default span:nth-last-child(n+2),.eo_theme_btn_delete span:nth-last-child(n+2),.eo_theme_btn_disabled span:nth-last-child(n+2),.eo_theme_btn_info span:nth-last-child(n+2),.eo_theme_btn_orange span:nth-last-child(n+2),.eo_theme_btn_success span:nth-last-child(n+2),.eo_theme_btn_warning span:nth-last-child(n+2){float:left}.btn_static_test_utac:hover,.eo_theme_btn_danger:hover,.eo_theme_btn_default:hover,.eo_theme_btn_delete:hover,.eo_theme_btn_disabled:hover,.eo_theme_btn_info:hover,.eo_theme_btn_orange:hover,.eo_theme_btn_success:hover,.eo_theme_btn_warning:hover{-webkit-transition:all .2s cubic-bezier(.645,.045,.355,1);transition:all .2s cubic-bezier(.645,.045,.355,1)}.btn_static_test_utac:disabled,.eo_theme_btn_danger:disabled,.eo_theme_btn_default:disabled,.eo_theme_btn_delete:disabled,.eo_theme_btn_disabled:disabled,.eo_theme_btn_info:disabled,.eo_theme_btn_orange:disabled,.eo_theme_btn_success:disabled,.eo_theme_btn_warning:disabled{cursor:not-allowed}*{margin:0;padding:0;outline:none;color:inherit;font-family:inherit;font-size:inherit}.base-container-div{position:absolute;width:100%;top:0;left:0;height:100%;z-index:0;font-size:13px}.common-table-div{padding:15px}a *,button *,div,li,p,span,thead th{cursor:inherit}td,th{text-align:left;word-break:break-all}ol,ul{list-style-type:none}body{position:absolute;font-family:"Helvetica Neue","Helvetica","PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans CJK SC","WenQuanYi Micro Hei","Arial",sans-serif;background:#fff;width:100%;height:100%;color:#333;font-size:13px}a,button{cursor:pointer;text-decoration:none}a input[type=text],button input[type=text]{cursor:text}button{background:initial;border:none}textarea{resize:none}textarea:disabled{background-color:#fafafa;color:#ccc;cursor:not-allowed}input::-ms-clear{display:none}input::-ms-reveal{display:none}.absolute{position:absolute}.eo-blod{font-weight:700}.inline-block{display:inline-block}.eo-tip-container{position:absolute;z-index:100;visibility:hidden}.eo-tip-container .message-li{padding:10px;line-height:initial;-webkit-border-radius:3px;border-radius:3px;background-color:#000;color:#fff;font-size:12px;text-align:left;max-width:500px}.eo-tip-container .message-li *{color:#fff}.eo-tip-container .arrow-li{border-color:#000 transparent transparent transparent;border-width:5px 5px 0;border-style:solid;width:0;margin-left:8px}.eo-modal-header{height:50px;line-height:50px;border-bottom:1px solid #e5e5e5;font-size:18px;padding:0 20px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.eo-modal-header a,.eo-modal-header input[type=button]{padding:0 16px}.eo-modal-header .icon-guanbi:hover{color:#1890ff}.eo-modal-article{padding:20px}.eo-modal-article .eo_form_first_item_title{margin-bottom:8px}.eo-modal-article .eo_form_item_title{margin:20px 0 8px}.eo-modal-footer{padding:15px 20px;border-top:1px solid #e5e5e5;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;background-color:#f9f9f9;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.eo-modal-footer button,.eo-modal-footer input[type=button]{margin-right:8px}.eo-modal-tip{color:#999}.eo-operate-btn{color:#1890ff;margin-right:10px;border:none;background:0 0;text-indent:0;cursor:pointer;font-size:12px}.eo-operate-btn .iconfont{padding-right:2px}.eo-operate-btn:hover{color:#1e88e5;text-decoration:underline}.eo-operate-btn:disabled{color:#ccc!important;cursor:not-allowed!important}.eo-static-hidden{height:0;overflow:hidden;visibility:hidden;position:relative;padding:0!important}.eo-none-tr{background-color:inherit!important;color:#999!important;line-height:100px!important;height:100px!important}.eo-none-tr td{text-align:center;cursor:default;vertical-align:middle!important}.no-menu-list-container .common_scss_list .first_level_article{margin:15px 15px 0}.no-menu-list-container .footer{margin:0 15px 15px}.pull-left{float:left}.pull-right{float:right}.wrap{width:1250px;height:auto;margin:0 auto}.eo_theme_mask_bg{position:fixed;z-index:-1;width:100%;height:100%;top:0;left:0}.eo_disable{color:#999!important;background-color:#fafafa!important}.eo_more_btn_container{position:relative;display:inline-block}.eo_more_btn_container .more-btn:focus+.wrap-container{display:block}.eo_more_btn_container .common-btn{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;float:left}.eo_more_btn_container .more-btn{border-left:1px solid #089462;-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;width:25px;padding:0}.eo_more_btn_container .wrap-container:hover{display:block}.eo_more_btn_container .wrap-container{background-color:#fff;-webkit-box-shadow:0 10px 15px rgba(0,0,0,.12);box-shadow:0 10px 15px rgba(0,0,0,.12);position:absolute;border-style:solid;border-width:1px;-webkit-border-radius:3px;border-radius:3px;right:0;z-index:2;border-color:#d9d9d9;display:none;margin-top:5px}.eo_more_btn_container .wrap-container a,.eo_more_btn_container .wrap-container button{height:35px;line-height:35px;padding:0 15px;text-align:left;color:#555;word-break:keep-all;white-space:pre;display:block}.eo-more-btn-container .wrap-div p:hover,.eo_more_btn_container .wrap-container a:hover,.eo_more_btn_container .wrap-container button:hover{background-color:#eee;color:#607d8b;text-decoration:underline}.null_tip_span{font-size:16px;width:100%;display:block;text-align:center;line-height:140px;color:#999}.btn_hover:hover{color:#1890ff}.eo-sv-handle{cursor:move}.eo-textarea{border-style:solid;border-width:1px;-webkit-border-radius:3px;border-radius:3px;font-size:14px;padding:4px 11px;-webkit-box-sizing:border-box;box-sizing:border-box;width:250px}.eo-input:disabled,.eo-select:disabled,.eo-textarea:disabled{cursor:not-allowed}.eo-input,.eo-select{border-style:solid;border-width:1px;-webkit-border-radius:3px;border-radius:3px;font-size:12px;padding:4px 6px;-webkit-box-sizing:border-box;box-sizing:border-box;height:30px;line-height:100%;width:250px}.btn-addChild:disabled:hover .ams-scss-disable-tip,.get-more-btn:disabled:hover .ams-scss-disable-tip,.number-label:disabled:hover .ams-scss-disable-tip{display:block}.ams-scss-disable-tip{position:absolute;margin-top:-54px;z-index:4;display:none;margin-left:-10px}.ams-scss-disable-tip .tip-div{padding:10px;word-break:keep-all;line-height:initial;-webkit-border-radius:3px;border-radius:3px;background-color:#000;color:#fff;font-size:12px;text-align:left;max-width:500px;min-width:200px}.ams-scss-disable-tip .arrow-div{border-color:#000 transparent transparent transparent;border-width:5px 5px 0;border-style:solid;width:0;margin-top:8px;margin-left:8px}.eo-checkbox{height:15px;line-height:15px;width:15px;font-size:12px!important;margin-right:4px;cursor:pointer;display:inline-block;text-align:center;-webkit-border-radius:3px;border-radius:3px;text-indent:0;color:#333;background-color:#fff;border:1px solid #d9d9d9;font-weight:100}.eo_link{color:#1890ff}.eo_link:hover{text-decoration:underline}.eo_mask{position:fixed;z-index:-1;width:100%;height:100%;top:0;left:0}.eo_theme_btn_default{border-style:solid;border-width:1px}.eo_theme_btn_danger:disabled,.eo_theme_btn_delete:disabled,.eo_theme_btn_info:disabled,.eo_theme_btn_orange:disabled,.eo_theme_btn_success:disabled,.eo_theme_btn_warning:disabled{border-style:solid;border-width:1px}.eo_theme_btn_disabled{color:#999!important;background-color:#eee!important;border:1px solid #d9d9d9!important;cursor:not-allowed}.eo-more-btn-container{position:relative;display:inline-block}.eo-more-btn-container:hover{color:#1890ff}.eo-more-btn-container .eo_more_btn{line-height:28px}.eo-more-btn-container .iconfont{font-size:24px}.eo-more-btn-container .icon-jiantou_liebiaozhankai{font-size:18px}.eo-more-btn-container .wrap-div{background-color:#fff;-webkit-box-shadow:0 10px 15px rgba(0,0,0,.12);box-shadow:0 10px 15px rgba(0,0,0,.12);position:absolute;border-style:solid;border-width:1px;-webkit-border-radius:3px;border-radius:3px;z-index:2;border-color:#d9d9d9;display:none;margin-top:5px}.eo-more-btn-container .wrap-div p{height:35px;line-height:35px;padding:0 15px;text-align:left;color:#555;word-break:keep-all;white-space:nowrap;min-width:60px;cursor:pointer}.eo-more-btn-container .eo_more_btn:focus+.wrap-div,.eo-more-btn-container:focus .wrap-div{display:block}.eo-wrap-div{background-color:#fff;-webkit-box-shadow:0 10px 15px rgba(0,0,0,.12);box-shadow:0 10px 15px rgba(0,0,0,.12);position:absolute;border-style:solid;border-width:1px;-webkit-border-radius:3px;border-radius:3px;right:0;z-index:2;border-color:#d9d9d9;display:none;margin-top:5px}.eo-wrap-div p{height:35px;line-height:35px;padding:0 15px;text-align:left;color:#555;word-break:keep-all;white-space:pre;min-width:60px;cursor:pointer}.eo-wrap-div p:hover{background-color:#eee;color:#607d8b;text-decoration:underline}.eo-label-default,.eo-label-purple,.eo-label-success{color:#9c27b0;background-color:#f8fff9;border:1px solid #9c27b0;-webkit-border-radius:3px;border-radius:3px}.eo-label-default,.eo-label-success{color:#58a942;border:1px solid #58a942}.eo-label-default{color:#07a1ea;background-color:#fcfeff;border:1px solid #07a1ea}.eo-label-danger,.eo-label-tips,.eo-label-warning{color:#ea0707;background-color:#fffdfd;border:1px solid #ea0707;-webkit-border-radius:3px;border-radius:3px}.eo-label-tips,.eo-label-warning{color:#f18f00;background-color:#fffdf8;border:1px solid #f18f00}.eo-label-tips{color:#999;background-color:#f5f5f5;border:1px solid #999}.eo-label-options,.eo-label-others,.eo-label-yellow{color:#6d4c41;background-color:#fffcfb;border:1px solid #6d4c41;-webkit-border-radius:3px;border-radius:3px}.eo-label-options,.eo-label-yellow{color:#ff8f00;background-color:#fffef6;border:1px solid #ff8f00}.eo-label-options{color:#546e7a;background-color:#fafdff;border:1px solid #546e7a}.eo-color-back,.eo-color-default,.eo-color-success{color:#fff;background-color:#1890ff;border:1px solid #1890ff;-webkit-border-radius:3px;border-radius:3px}.eo-color-back,.eo-color-success{background-color:#00ab6d;border:1px solid #00ab6d}.eo-color-back{background-color:#333;border:1px solid #333;line-height:14px;text-indent:0;-webkit-box-sizing:border-box;box-sizing:border-box}.eo-color-error,.eo-color-warning,.eo-color-yellow{color:#fff;background-color:#f18f00;border:1px solid #f18f00;-webkit-border-radius:3px;border-radius:3px}.eo-color-error,.eo-color-yellow{background-color:#e83333;border:1px solid #e83333}.eo-color-yellow{background-color:#fc0;border:1px solid #fc0}.eo-color-danger,.eo-color-tips,.eo-color-tips-shallow{color:#fff;background-color:#ea0707;border:1px solid #ea0707;-webkit-border-radius:3px;border-radius:3px}.eo-color-tips,.eo-color-tips-shallow{background-color:#999;border:1px solid #999}.eo-color-tips-shallow{background-color:#b3b4b3;border:1px solid #b3b4b3}.eo-color-options,.eo-color-others,.eo-color-purple,.eo-color-unuse{color:#fff;background-color:#795548;border:1px solid #6d4c41;-webkit-border-radius:3px;border-radius:3px}.eo-color-options,.eo-color-purple,.eo-color-unuse{background-color:#607d8b;border:1px solid #546e7a}.eo-color-purple,.eo-color-unuse{background-color:#999;border:1px solid #c63e21}.eo-color-purple{background-color:#9c27b0;border:1px solid #9c27b0}.eo-error-tips{color:#e83333;font-size:12px;display:none;line-height:32px}.eo-had-input-error .eo-error-tips,.eo-had-input-error+.eo-error-tips,.eo-input-error+.eo-error-tips{display:block}.eo-status-options{color:#546e7a}.eo-status-others{color:#6d4c41}.eo-status-default{color:#07a1ea}.eo-status-success{color:#00ab6d}.eo-status-warning{color:#f18f00}.eo-status-error{color:#e83333}.eo-status-yellow{color:#fc0}.eo-status-purple{color:#9c27b0}.eo-status-danger{color:#ea0707}.eo-status-tips{color:#999}.eo-status-disabled{color:#ccc}.eo-tab-icon{color:#fff;height:16px;line-height:18px;-webkit-border-radius:8px;border-radius:8px;display:inline-block;padding:0 10px;font-size:12px}@-webkit-keyframes flicker{0%,to{border:1px solid #d9d9d9}50%{border:1px solid #089462}}@keyframes flicker{0%,to{border:1px solid #d9d9d9}50%{border:1px solid #089462}}.eo-copy{-webkit-animation:flicker 1s;animation:flicker 1s}.eo-tab-menu{display:table;border-bottom:0;width:100%}.eo-tab-menu .item-tab{padding:0 15px;display:inline-block;cursor:pointer;height:38px;line-height:38px;border-bottom-style:solid;border-bottom-width:3px;margin-right:2px}.eo-tab-menu .item-tab .icon-circle{font-size:12px;margin-right:5px}.eo-tab-menu .active-item{cursor:default}.eo-tab-menu .disable-item{cursor:not-allowed}.eo-tab-menu .disable-item .iconfont{display:none}.eo-tab-container{background-color:#fff;-webkit-box-shadow:0 4px 6px 0 rgba(31,31,31,.05),0 0 2px 0 rgba(31,31,31,.2);box-shadow:0 4px 6px 0 rgba(31,31,31,.05),0 0 2px 0 rgba(31,31,31,.2);display:block}.eo-block-container,.eo-method-label,.eo-tab-container{-webkit-border-radius:3px;border-radius:3px}.eo-block-container{background-color:#fff;border:1px solid #d9d9d9;display:block}.eo-method-label{margin-right:8px;font-size:12px;display:inline-block;width:45px;height:18px;line-height:18px;text-align:center;text-indent:0}.eo-absolute{position:absolute}.eo-relative{position:relative}.opacity-none{opacity:0}.eo-had-content-error *,.modal-open .error i,.modal-open .error span{color:#d85030}.eo-had-input-error input,.eo-input-error{border-color:#e83333!important;color:#e83333!important}.eo-had-input-error input:focus,.eo-input-error:focus{border-color:#e83333!important;color:#333!important}.eo-input-success{border-color:#089462!important}.eo-common-table,.eo_popover_tip{-webkit-border-radius:3px;border-radius:3px}.eo_popover_tip{position:absolute;z-index:6;background-color:#000;height:30px;line-height:30px;padding:0 10px;white-space:nowrap;text-indent:0;color:#fff;font-size:12px;display:none}.eo-common-table{border-spacing:0;table-layout:fixed;border:1px solid #e5e5e5}.eo-common-table tbody .hover-tr:hover,.eo-common-table thead,.eo-common-table thead td{background-color:#fafafa}.eo-common-table td{height:40px;line-height:40px;vertical-align:top;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-left:10px}.eo-common-table td:nth-last-child(n+2){border-right:1px dashed #e5e5e5}.eo-common-table .btn-delete{height:25px;line-height:25px;-webkit-border-radius:3px;border-radius:3px;background-color:#f2f2f2;color:#999;display:inline-block;text-align:center;border:1px solid #d9d9d9;padding:0 5px;font-size:12px}.eo-common-table .btn-delete:hover{background-color:#e83333;color:#fff;border:1px solid #d03333}.eo-common-table tbody tr:nth-last-child(n+2) td,gpedit-inside-auth .common-table tbody tr:nth-last-child(n+2) td{border-bottom:1px dashed #e5e5e5}.eo-common-table tbody tr:first-child td{border-top:1px solid #d9d9d9}.popover{position:absolute;z-index:2}.popover table{border-spacing:0}.arrow{border-style:solid;border-width:5px 10px 5px 0;border-color:transparent #333 transparent transparent}.popover-inner{background-color:#333;padding:5px 10px;min-width:150px;max-width:215px}.popover-inner .popover-content{color:#fff;font-size:12px;line-height:20px}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#ccc}input:-moz-placeholder,input::-moz-placeholder,textarea:-moz-placeholder,textarea::-moz-placeholder{color:#ccc}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#ccc}.pageFooter{text-align:center}.pageFooter li>a,.pageFooter li>span{color:#555;width:35px}.pageFooter .disabled>a{color:#e5e5e5;cursor:default}.pageFooter .pagination-next,.pageFooter .pagination-prev{-webkit-border-radius:3px;border-radius:3px}.pageFooter .pagination .active,.pageFooter .pagination .active:focus,.pageFooter .pagination .active:hover{background-color:#089462}.pageFooter .pagination .active a,.pageFooter .pagination .active:focus a,.pageFooter .pagination .active:hover a,list-block-common-component .tfooter-div .pagination>.active a,list-block-common-component .tfooter-div .pagination>.active:focus a,list-block-common-component .tfooter-div .pagination>.active:hover a{color:#fff}.pageFooter .pagination-jump{color:#555;margin:37px 0 20px 10px;display:inline-block}.pageFooter .pagination-jump li{height:37px;line-height:37px;display:inline-block}.pageFooter .pagination-jump li input{height:33px;line-height:33px;margin:0 8px;width:55px;border:1px solid #dfdfdf;background-color:#fff;text-indent:1em}.pageFooter .pagination-jump li button{width:50px}.pageFooter .pagination-sm{margin:25px;display:inline-block}.pageFooter .pagination-sm li{width:35px;height:35px;line-height:36px;background-color:#fff;border:1px solid rgba(0,0,0,.06);border-left:none;text-align:center;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex}.pageFooter .pagination-sm .pagination-prev{margin-right:10px;border-left:1px solid rgba(0,0,0,.06)}.pageFooter .pagination-sm .pagination-next{margin-left:10px;border-left:1px solid rgba(0,0,0,.06)}.pageFooter .pagination-sm li:nth-child(2){border-left:1px solid rgba(0,0,0,.06)}.pageFooter .first-page{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.pageFooter .last-page{-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.pageFooter .only-page{-webkit-border-radius:3px;border-radius:3px}.wangEditor-container .wangEditor-txt ul li{list-style-type:initial}.wangEditor-container .wangEditor-txt *{white-space:pre-wrap}.hidden{display:none}::-webkit-scrollbar-track{background:#f5f5f5}::-webkit-scrollbar-thumb{background:#bdbdbd}::-webkit-scrollbar{width:12px;height:12px}.z_index8{z-index:8}.va_top{vertical-align:top}.ws_nowrap{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wb_all{word-break:break-all}.ws_initial{white-space:initial}.of_hidden{overflow:hidden}.of_inherit{overflow:inherit!important}.br_3{-webkit-border-radius:3px;border-radius:3px}.eo_to_right_0{right:0}.eo_to_right_750{right:-750px}.br_0330{-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.h_180{height:180px}.h_70{height:80px}.lh_50{line-height:50px}.lh_30{line-height:30px}.lh_35{line-height:35px}.lh_20{line-height:20px}.lh_1em{line-height:1em}.lh_14{line-height:14px}.lh_12{line-height:12px}.lh_1point75{line-height:1.75em}.clear_b{clear:both}.dp_f,menu-Default-Common-Component,tip-common-component{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.dp_none{display:none}.dp_b{display:block!important}.dp_ib{display:inline-block}.dp_it{display:inline-table}.mw_1100{min-width:1100px}.mw_100{min-width:100px}.mw_110{min-width:110px}.maw_200{max-width:200px}.mw_300{min-width:300px}.mw_80{min-width:80px}.mw_800{min-width:800px}.mw_55{min-width:55px}.mw_50{min-width:50px}.w_240{width:240px}.w_25{width:25px}.w_15{width:15px}.w_60{width:60px}.w_330{width:330px}.w_640{width:640px}.w_80{width:80px!important}.w_150{width:150px}.w_90{width:90px}.w_180{width:180px}.w_170{width:170px}.w_200{width:200px}.w_300{width:300px}.w_320{width:320px}.w_18percent{width:18%}.w_30percent{width:30%}.w_25percent{width:25%}.w_20percent{width:20%}.w_40percent{width:40%}.w_10percent{width:10%}.w_30{width:30px}.w_400{width:400px}.w_500{width:500px}.w_55{width:55px}.w_50{width:50px!important}.w_250{width:250px}.w_220{width:220px}.w_100{width:100px}.w_50percent{width:50%}.modal-open .eo-modal select-multistage-common-component .container-div,.w_100percent{width:100%}.w_8percent{width:8%}.w_fc{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.h_100percent{height:100%}.mh_40{min-height:40px}.h_50,eo-navbar header{height:50px}.h_40{height:40px;line-height:40px}.h_54{height:54px!important}.h_20{height:20px!important}.h_30{height:30px}.h_110{height:110px}.po_re{position:relative}.po_ab{position:absolute}.po_fix{position:fixed}.ti0,tip-directive *{text-indent:0}.ti20{text-indent:20px}.tac{text-align:center}.ta_l{text-align:left}.ta_j{text-align:justify}.ab_r20{position:absolute;right:20px}.h20,.h6{font-size:16px;font-weight:700}.h20{font-size:20px}.h24{font-size:24px}.fwb,.h24{font-weight:700}.fwn{font-weight:400}.cp{cursor:pointer}.cd{cursor:default}.cn-a{cursor:not-allowed}.ccr{cursor:col-resize}.c555{color:#555}.c999{color:#999}.c666,.eo_theme_lrt tbody tr{color:#666}.cddd{color:#ddd}.c_b_g{color:#00ab6d;border:1px solid}.bgc_white{background-color:#fff}.bgc_g{background-color:#00ab6d}.bgc_r{background-color:#e83333}.c_b_r,.c_b_y{color:#f18f00;border:1px solid}.c_b_r{color:#ea0707}.f_row,.f_row_ac{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.f_row{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.f_row_ac{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.f_column,.f_row_ac,.f_wrap{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.f_column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.f_wrap{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.f_jc_ac,.f_js_ac{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.f_js_ac{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.f_jc{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.f_js{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.f_je{-webkit-box-pack:end;-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end}.f_ac{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.f_as{-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start}.f_ae{-webkit-box-align:end;-webkit-align-items:flex-end;-ms-flex-align:end;align-items:flex-end}.bl_none{border-left:none!important}.btd,list-block-common-component .tbody-div>inner-html-common-directive .tr-tbd{border-top:1px solid #d9d9d9}.bbd{border-bottom:1px solid #d9d9d9}.bb_ddd{border-bottom:1px solid #ddd}.bd_all,.bdd_br3{border:1px solid #d9d9d9}.bdd_br3{-webkit-border-radius:3px;border-radius:3px}.fg1,.fg_auto{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}.fg_auto{-webkit-flex:auto;-ms-flex:auto;flex:auto}.cr{color:#e83333}.b_cr{border:1px solid #e83333}.b_none{border:none}.cb{color:#2196f3}.cy{color:#f48932}.co{color:#ffb74d}.ce6{color:#e6e6e6}.cf{color:#fff}.cg{color:#00ab6d}.c9{color:#999}.common_scss_list .first_level_article .more-function li:hover,.tdu{text-decoration:underline}.fs12{font-size:12px!important}.fs27{font-size:27px}.fs14{font-size:14px}.fs16{font-size:16px}.fs18{font-size:18px}.fs20{font-size:20px}.fs23{font-size:23px}.fs24{font-size:24px}.fs30{font-size:30px}.fs22{font-size:22px!important}.fs13{font-size:13px}.m_auto{margin:auto}.m20{margin:20px}.m10{margin:10px}.m15{margin:15px}.mr0{margin-right:0}.btn-back .iconfont,.mr5{margin-right:5px}.mr10{margin-right:10px}.mr15{margin-right:15px}.mr20{margin-right:20px}.mr25{margin-right:25px}.mr30{margin-right:30px}.mr40{margin-right:40px}.mr80{margin-right:80px}.ml12{margin-left:12px}.ml0{margin-left:0}.ml5{margin-left:5px}.ml15{margin-left:15px}.ml10{margin-left:10px}.ml20{margin-left:20px}.ml240{margin-left:240px}.ml40{margin-left:40px}.ml50{margin-left:50px}.ml47{margin-left:47px}.mlr5{margin-left:5px;margin-right:5px}.mlr10{margin-left:10px;margin-right:10px}.mlr15{margin-left:15px;margin-right:15px}.mlr20{margin-left:20px;margin-right:20px}.mlr40{margin-left:40px;margin-right:40px}.ml30{margin-left:30px}.mt0{margin-top:0}.mt60{margin-top:60px}.mt65{margin-top:65px}.mt50,cluster-node{margin-top:50px}.mt35{margin-top:35px}.mt12{margin-top:12px}.mt5{margin-top:5px}.mt10{margin-top:10px}.mtb50{margin-top:50px;margin-bottom:50px}.mtb5{margin-top:5px;margin-bottom:5px}.mt20{margin-top:20px}.mt30{margin-top:30px}.mt40{margin-top:40px}.mt15{margin-top:15px}.mt100{margin-top:100px}.mb20{margin-bottom:20px}.mb25{margin-bottom:25px}.mb10{margin-bottom:10px}.mb15{margin-bottom:15px}.mb30{margin-bottom:30px}.mb50{margin-bottom:50px}.mb65{margin-bottom:65px}.mb5{margin-bottom:5px}.mtb10{margin-top:10px;margin-bottom:10px}.mtb15{margin-top:15px;margin-bottom:15px}.mtb20{margin-top:20px;margin-bottom:20px}.mtb40{margin-top:40px;margin-bottom:40px}.pr20{padding-right:20px}.pr5{padding-right:5px}.home-common-has-group-div menu-default-common-component,.pr15{padding-right:15px}.pr10{padding-right:10px}.p5{padding:5px}.p10{padding:10px}.p15{padding:15px}.pl15,list-default-common-component .common_scss_list .first_level_article td,list-default-common-component .common_scss_list .first_level_article th{padding-left:15px}.p20{padding:20px}.ptd1{padding-top:1px;padding-bottom:1px}.plr30{padding-left:30px;padding-right:30px}.plr3{padding-left:3px;padding-right:3px}.plr40{padding-left:40px;padding-right:40px}.plr5{padding-left:5px;padding-right:5px}.pl20{padding-left:20px}.plr10{padding-left:10px;padding-right:10px}.plr15{padding:0 15px}.pl10{padding-left:10px}.plr20{padding-left:20px;padding-right:20px}.ptb2{padding-top:2px;padding-bottom:2px}.ptb5{padding-top:5px;padding-bottom:5px}.pt15{padding-top:15px}.ptb25{padding-top:25px;padding-bottom:25px}.pt10{padding-top:10px}.pt30{padding-top:30px}.pt20{padding-top:20px}.pt25{padding-top:25px}.pb20{padding-bottom:20px}.pb10,.ptb10{padding-bottom:10px}.ptb10{padding-top:10px}.ptb15{padding-top:15px;padding-bottom:15px}.ptb20{padding-top:20px;padding-bottom:20px}.btn-back{border:1px solid #d9d9d9;-webkit-border-radius:3px;border-radius:3px;background-color:#fff;padding:0 10px;font-size:12px;display:inline-block;text-align:center;height:32px;line-height:30px}.btn-back:hover{background-color:#fafafa}.bdn-bgn{border:none;background-color:unset}.vis_hid{visibility:hidden}.tips-box{-webkit-box-shadow:0 4px 6px 0 rgba(31,31,31,.05),0 0 2px 0 rgba(31,31,31,.2);box-shadow:0 4px 6px 0 rgba(31,31,31,.05),0 0 2px 0 rgba(31,31,31,.2);-webkit-border-radius:3px;border-radius:3px;padding:0 15px 15px}.tips-box .tips-title{font-weight:700;border-bottom:1px solid #d9d9d9;height:40px;line-height:40px}.tips-box .tips-ul{padding:10px 0}.tips-box .tips-ul .tips-ul-title{display:inline-block;width:8rem}.tips-box .tips-ul>li{height:30px;line-height:30px}.eo_theme_modal_mask{background-color:rgba(0,0,0,.5)}.eo_theme_mask_bg{background:#f0f2f5}.eo_theme_ts_btn{background-color:#2196f3;color:#fff}.eo_theme_ts_btn:hover{background-color:#1e88e5;color:#fff}.eo_theme_tp_btn{background-color:#00ab6d;color:#fff}.eo_theme_tp_btn:hover{background-color:#089462}.eo_theme_tp_p_btn{background-color:#388e3c;color:#fff}.eo_theme_tp_p_btn:hover{background-color:#2e7d32}.eo_theme_t_p_btn{background-color:#3c7ce5;color:#fff}.eo_theme_t_p_btn:hover{background-color:#3a85c1}.eo-input,.eo-select,.eo-textarea{border-color:#d9d9d9;background-color:#fff;color:#333}.eo-input:hover,.eo-select:hover,.eo-textarea:hover{border-color:#999;-webkit-transition:all .2s cubic-bezier(.645,.045,.355,1);transition:all .2s cubic-bezier(.645,.045,.355,1)}.eo-input:focus,.eo-select:focus,.eo-textarea:focus{border-color:#089462}.eo-input:disabled,.eo-select:disabled,.eo-textarea:disabled{color:#999;background-color:#fafafa}input:disabled{color:#999!important;background-color:#fafafa!important}.eo-tab-menu,.eo_theme_ldt tbody tr:hover,.eo_theme_lgt tbody tr:hover{background-color:#efefef}.eo-tab-menu .item-tab{border-bottom-color:#efefef}.eo-tab-menu .item-tab:hover{border-color:#089462}.eo-tab-menu .item-tab .tab-icon{background-color:#00ab6d}.eo-tab-menu .item-tab .icon-circle{color:#00ab6d}.eo-tab-menu .active-item,.eo-tab-menu .active-item:hover{border-bottom-color:#00ab6d}.eo-tab-menu .disable-item{color:#999}.eo-tab-menu .disable-item:hover{border-bottom-color:transparent}.eo_theme_iblock,.eo_theme_iblock_i{border-color:#d9d9d9;background-color:#fff}.eo_theme_iblock_i:hover{background-color:#fafafa}.eo_theme_iblock_i_dp{color:#b6b6b6}.eo_theme_iblock_tb{color:#607d8b}.eo_theme_iblock_tp{color:#555}.eo_theme_rblock{background-color:#f3f3f3}.eo_theme_rblock_tp{color:#b6b6b6}.eo_theme_rblock_i_dp{border-color:#b6b6b6}.eo_theme_gd_container{background-color:#fff}.eo_theme_gd_container .sv-helper,.eo_theme_gd_li:hover{background-color:#eee}.eo_theme_gd_d{border-color:#e5e5e5}.eo_theme_gd_lt,.eo_theme_ldt thead th{border-color:#d9d9d9}.eo_theme_gd_li{color:#555}.eo_theme_gd_li:hover .eo_theme_gd_lt_icon{color:#455a64}.eo_theme_gd_li .iconfont{color:#999}.eo_theme_gd_li_fl{background-color:#fff;-webkit-box-shadow:-5px 5px 15px #ededed;box-shadow:-5px 5px 15px #ededed;border-color:#dcdcdc}.eo_theme_gd_li_fli{color:#555}.eo_theme_gd_li_fli_s{color:#089462}.eo_theme_gd_li_fli:hover,.eo_theme_gd_li_fli_a{background-color:#eee;color:#607d8b}.eo_theme_gd_btn_c{background-color:#fff;color:#e83333;border-color:#e83333}.eo_theme_gd_btn_c:active,.eo_theme_gd_btn_c:hover{background-color:#d03333;color:#fff;border-color:#d03333}.eo_theme_lct_tra{background-color:#ffecb3!important}.eo_theme_ldt,.eo_theme_lgt{background-color:#fff}.bottom-count-div,.eo_theme_lgt thead th{background-color:#f8f8f8;color:#48555c}.eo_theme_ldt_tdt{color:#999}.eo_theme_lrd{background-color:#fff}.eo_theme_lrt tbody tr:nth-child(odd){background:#fafafa}.eo_theme_lrt tbody tr:nth-child(even){background:#fff}.eo_theme_lrt tbody tr:hover{background:#f0f0f0}.s_style{-webkit-box-shadow:0 0 5px rgba(0,0,0,.1);box-shadow:0 0 5px rgba(0,0,0,.1);border-color:#d9d9d9}.s0_logo_style,.s0_style{background-color:#fff;border-bottom:1px solid #d9d9d9}.s0_style{color:#999}.s0_style:hover{background-color:#f2f2f2}.s0_logo_style{border-color:#d9d9d9}.s0_icon_style{border-right:1px solid #d9d9d9;background-color:#fafafa}.s1_style{background-color:#fff}.s1_tip_style{color:#fff;background-color:#dc441e}.s1_c_style{background-color:#fff}.s1_ic_style{background-color:#efefef}.s1_i_style{border-color:#e5e5e5}.s1_i_style:hover{background-color:#f0f2f5}.s1_if_style{color:#333}.s1_if_style .iconfont{color:#00ab6d}.s1_if_style,.s1_if_style:hover{background-color:#efefef}.s1_i_shrink_style{border-color:#e5e5e5}.s1_i_shrink_style:hover,.s1_if_shrink_style{color:#000;background-color:#e5e7e8}.s1_if_shrink_style .iconfont{color:#00ab6d}.s1_if_shrink_style:hover{color:#000;background-color:#e5e7e8}.s2_style{border-right:1px solid #d9d9d9;-webkit-box-shadow:2px 0 5px rgba(0,0,0,.02);box-shadow:2px 0 5px rgba(0,0,0,.02)}.s2_c_style,.s2_style{background-color:#efefef}.s2_c_shrink_style{background-color:#fff}.s2_i_style:hover{background-color:#f0f2f5}.s2_i_shrink_style:hover{background-color:#f3f3f3}.s2_iaf_style{color:#000;border-right-color:#e5e7e8}.s2_iaf_style,.s2_iaf_style:hover{background-color:#e5e7e8}.s_id_style,.s_id_style:hover{background-color:#efefef;color:#999}.n0_style{background-color:#fff;border-color:#d9d9d9}.n_sbtn_style,.n_space_d_style{background-color:#fff;color:#333}.n_sbtn_style{color:#555}.n_space_d_style:hover .n_sbtn_style{border-color:#1e88e5;color:#1e88e5}.n_dv_c,.n_sbtn_style{border-color:#d9d9d9}.n_r_style,login .login-wrap .login-content article li .iconfont{color:#999}.n_ra_style:hover{color:#333}.n_list0_style,.n_list1_style{background-color:#fff}.n_list0_style:hover{background-color:#f8f8f8;border-color:#f8f8f8}.n_list1_style{-webkit-box-shadow:0 10px 15px rgba(0,0,0,.12);box-shadow:0 10px 15px rgba(0,0,0,.12)}.n_list1_i_style:hover{background-color:#f0f0f0}.m_i_tab_style{border-color:#089462;background-color:#fff}.m_nav_item_style{border-bottom-color:transparent}.m_nav_item_style:hover{border-bottom-color:#089462}.m_nav_active_item_style,.m_nav_active_item_style:hover{border-bottom-color:#00ab6d}.m_btn_d,.m_tab_d{background-color:#fff;border-color:#d9d9d9}.m_btn_d:hover{background-color:#fafafa}.m_i_tab_style .m_tab_d:hover,.m_tab_a{background-color:#089462;color:#fff}.m_tab_a{background-color:#00ab6d}.eo_theme_btn_danger .iconfont,.eo_theme_btn_delete .iconfont,.eo_theme_btn_info .iconfont,.eo_theme_btn_orange .iconfont,.eo_theme_btn_success .iconfont,.eo_theme_btn_warning .iconfont{color:rgba(255,255,255,.7)}.eo_theme_btn_default{background-color:#fff;color:#666;border-color:#d9d9d9}.eo_theme_btn_default:hover{background-color:#fff;color:#1e88e5}.eo_theme_btn_default:disabled{color:#999!important;background-color:#eee!important;border-color:#d9d9d9!important}.eo_theme_btn_default:disabled .iconfont,.eo_theme_btn_delete:disabled .iconfont{color:#999!important}.eo_theme_btn_default:hover{border-color:#1e88e5}.eo_theme_btn_delete{background-color:#f2f2f2;color:#a3a3a3}.eo_theme_btn_delete:hover{background-color:#e83333;color:#fff}.eo_theme_btn_delete:disabled{color:#999!important;background-color:#eee!important;border-color:#d9d9d9!important}.btn_static_test_utac:hover+.eo_theme_btn_success{background-color:#00b775}.btn_static_test_utac:hover+.eo_theme_btn_info{background-color:#3aa3ff}.eo_theme_btn_success{background-color:#00ab6d;color:#fff}.eo_theme_btn_success:hover{background-color:#00b775;color:#fff}.eo_theme_btn_success:disabled{color:#999!important;background-color:#eee!important;border-color:#d9d9d9!important}.eo_theme_btn_danger:disabled .iconfont,.eo_theme_btn_info:disabled .iconfont,.eo_theme_btn_orange:disabled .iconfont,.eo_theme_btn_success:disabled .iconfont,.eo_theme_btn_warning:disabled .iconfont{color:#999!important}.eo_theme_btn_success:active{background-color:#008d5a}.eo_theme_btn_info{background-color:#1890ff;color:#fff}.eo_theme_btn_info:hover{background-color:#3aa3ff;color:#fff}.eo_theme_btn_info:disabled{color:#999!important;background-color:#eee!important;border-color:#d9d9d9!important}.eo_theme_btn_info:active{background-color:#137cdd}.eo_theme_btn_orange{background-color:#ff9800;color:#fff}.eo_theme_btn_orange:hover{background-color:#f47c36;color:#fff}.eo_theme_btn_orange:disabled{color:#999!important;background-color:#eee!important;border-color:#d9d9d9!important}.eo_theme_btn_warning{background-color:#ff5722;color:#fff}.eo_theme_btn_warning:hover{background-color:#f44336;color:#fff}.eo_theme_btn_warning:disabled{color:#999!important;background-color:#eee!important;border-color:#d9d9d9!important}.eo_theme_btn_danger{background-color:#e83333;color:#fff}.eo_theme_btn_danger:hover{background-color:#fd5858;color:#fff}.eo_theme_btn_danger:disabled{color:#999!important;background-color:#eee!important;border-color:#d9d9d9!important}.eo_theme_btn_danger:active{background-color:#d52828}.modal-open{top:0;left:0;overflow:hidden}.modal-open .modal{opacity:1}.modal-open .modal-dialog{position:fixed;width:100%;height:100%;z-index:4;overflow:auto;top:0;min-width:1000px}.modal-open .modal:nth-child(2) .modal-dialog{z-index:3}.modal-open .modal:nth-child(3) .modal-dialog{z-index:2}.modal-open .modal:nth-child(n+3) .modal-dialog{z-index:1}.modal-open .error{background-color:#fff1f0;border:1px solid #d85030;-webkit-box-shadow:0 10px 29px #ffcdd2;box-shadow:0 10px 29px #ffcdd2}.modal-open .success{background-color:#f2fae3;border:1px solid #659f13;-webkit-box-shadow:0 10px 29px #c8e6c9;box-shadow:0 10px 29px #c8e6c9}.modal-open .success i,.modal-open .success span{color:#659f13}@-webkit-keyframes sticky-up{0%{-webkit-transform:translateY(-200%);-ms-transform:translateY(-200%);transform:translateY(-200%)}to{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}}@keyframes sticky-up{0%{-webkit-transform:translateY(-200%);-ms-transform:translateY(-200%);transform:translateY(-200%)}to{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}}@-webkit-keyframes fade{0%{-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7);opacity:0}to{-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes fade{0%{opacity:0}to{opacity:1}}@-webkit-keyframes gradient{0%{opacity:0}to{opacity:.5}}@keyframes gradient{0%{opacity:0}to{opacity:.5}}.modal-open .modal-content{height:-webkit-calc(100% - 100px);height:-ms-calc(100% - 100px);height:calc(100% - 100px)}.modal-open .eo_theme_modal_mask{position:fixed;z-index:-1;width:-webkit-calc(100% - 12px);width:-ms-calc(100% - 12px);width:calc(100% - 12px);height:100%;top:0;left:0;-webkit-animation:fade .7s;animation:fade .7s}.modal-open .eo-modal{position:relative;margin:100px auto 20px;-webkit-border-radius:4px;border-radius:4px}.modal-info-display .modal-dialog,.modal-open .common-modal{-webkit-box-shadow:0 10px 30px rgba(0,0,0,.1);box-shadow:0 10px 30px rgba(0,0,0,.1)}.modal-open .common-modal{background:#fff;text-align:left;-webkit-border-radius:5px;border-radius:5px;-webkit-animation:fade .2s;animation:fade .2s}.modal-open .modal-sure article .textarea-li pre{display:block;visibility:hidden}.modal-info-display .modal-dialog{position:fixed;min-width:350px;max-width:500px;text-align:center;-webkit-animation:sticky-up .3s;animation:sticky-up .3s;-webkit-border-radius:3px;border-radius:3px;height:auto;top:0;margin-top:75px;left:-webkit-calc(50% - 250px);left:-ms-calc(50% - 250px);left:calc(50% - 250px)}.modal-info-display .modal-info p{text-align:justify;line-height:1.75em;padding:10px}.modal-info-display .modal-info p .iconfont{font-size:18px;margin-right:10px}auto-complete-component{position:relative;width:100%}auto-complete-component .iconfont{position:absolute;right:5px;top:3px}auto-complete-component .eo-input{width:100%}auto-complete-component .active_item_acac{background-color:#fafafa}auto-complete-component .container_acac{display:inline-table;width:100%}auto-complete-component .list_container_acac{position:absolute;z-index:1;height:100px;background-color:#fff;border:1px solid #d9d9d9;overflow-y:scroll;line-height:20px;text-indent:10px;font-size:12px;margin-top:1px;width:100%}auto-complete-component .item_acac:hover{background-color:#f5f5f5}auto-complete-component input[type=text]:disabled+.icon-xuanzeqizhankai{display:none}list-block-common-component .disable-tbody-div{cursor:not-allowed;opacity:.5}list-block-common-component>.container-div{border-top:1px solid #d9d9d9;border-bottom:1px solid #d9d9d9}list-block-common-component .hover-tr-lbcc{cursor:pointer}list-block-common-component .hover-tr-lbcc:hover{background-color:#fafafa}list-block-common-component .tr-tbd:hover{background-color:#f2f2f2}list-block-common-component select-default-common-component .container-div{width:-webkit-calc(100% - 2px);width:-ms-calc(100% - 2px);width:calc(100% - 2px)}list-block-common-component select-default-common-component .text-p{border-color:transparent}list-block-common-component .desc-cth{line-height:27px;display:inline-block;margin-left:5px}list-block-common-component .eo-checkbox{margin:auto}list-block-common-component .eo-input,list-block-common-component input[type=text]{width:100%;border-color:transparent}list-block-common-component .eo-input:read-only,list-block-common-component input[type=text]:read-only{-webkit-box-shadow:none;box-shadow:none;text-indent:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}list-block-common-component .sort-handle-td,list-block-common-component .sort-handle-th{width:55px;text-align:center}list-block-common-component .sort-handle-td{padding-top:7px}list-block-common-component .sort-handle-td span{width:23px;height:23px;line-height:25px;-webkit-border-radius:3px;border-radius:3px;background-color:#f2f2f2;color:#999;display:inline-block;text-align:center;border:1px solid #d9d9d9;cursor:move}list-block-common-component .thead-div,list-block-common-component .tr-tbd{display:table;width:100%;height:38px;table-layout:fixed}list-block-common-component .thead-div>div,list-block-common-component .tr-tbd>div{display:table-cell}list-block-common-component .thead-div>div:nth-last-child(n+2),list-block-common-component .tr-tbd>div:nth-last-child(n+2){border-right:1px solid #d9d9d9}list-block-common-component .text-td-tbd,list-block-common-component .thead-div>div{vertical-align:middle}list-block-common-component .va-top-td-tbd{vertical-align:top;padding-top:4px}list-block-common-component .depth-td-tbd,list-block-common-component .text-td-tbd,list-block-common-component .thead-div>div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}list-block-common-component .text-td-tbd .depth-td-tbd{line-height:38px}list-block-common-component .depth-td-tbd{position:relative;height:100%}list-block-common-component .depth-td-tdb{white-space:nowrap;padding-top:0!important}list-block-common-component .depth-td-tdb input[type=text]{margin-top:4px}list-block-common-component .checkbox-td,list-block-common-component .checkbox-th{width:30px;padding-left:5px;padding-right:5px}list-block-common-component .checkbox-td{padding-top:9px!important}list-block-common-component .block_cth{display:block}list-block-common-component .inline_cth{display:inline-block}list-block-common-component .thead-div{background-color:#f4f4f4;font-weight:700}list-block-common-component .sv-group-helper{background-color:rgba(221,221,221,.3)}list-block-common-component .sv-group-helper .tr-tbd{border-top:none;background-color:transparent}list-block-common-component .sv-group-helper .divide-td-tbd{visibility:hidden}list-block-common-component .btn-shrink{text-align:center;font-size:24px;border:none;background-color:transparent;line-height:38px;margin-left:-5px;position:absolute;left:0}list-block-common-component .btn-shrink:hover{color:#1890ff}list-block-common-component .placeholder-td-tbd{display:inline-block;width:15px}list-block-common-component .divide-td-tbd{border-left:1px solid #d9d9d9;position:absolute;height:100%;margin-left:-3px}list-block-common-component .first-divide-td-tbd{top:10px;display:none}list-block-common-component .operate-td-tbd{padding-top:10px!important}list-block-common-component .operate-td-tbd>div>button:nth-last-child(n+2){padding-right:10px;border-right:1px solid #d9d9d9}list-block-common-component .readonly-tbody-div select-default-common-component .disabled-text-p{border:none;background-color:#fff;color:#333;padding-left:0}list-block-common-component .readonly-tbody-div select-default-common-component .text-p{cursor:default}list-block-common-component .readonly-tbody-div input{border:none}list-block-common-component .file-div{position:relative}list-block-common-component .file-div .file-input{position:absolute;right:5px;-webkit-border-radius:3px;border-radius:3px;line-height:25px;height:23px;border:none;top:4.5px;width:65px;z-index:1;opacity:0;cursor:pointer}list-block-common-component .file-div .file-input:hover+.file-btn-lbt,list-block-common-component .float-btngroup-tbd .float-btn-lbt:hover{background-color:#3faeff}list-block-common-component .file-div .file-btn-lbt{position:absolute;right:5px;width:65px;top:3.5px}list-block-common-component .disabled-tr-lbcc{background-color:#fafafa;color:#999;cursor:not-allowed}list-block-common-component .file-btn-lbt,list-block-common-component .float-btn-lbt{-webkit-border-radius:3px;border-radius:3px;line-height:25px;height:23px;border:none;font-size:12px;background-color:#2196f3;color:#fff}list-block-common-component .float-btngroup-tbd{position:absolute;top:8px;display:none}list-block-common-component .float-btngroup-tbd .float-btn-lbt{padding:0 10px}list-block-common-component .float-btngroup-tbd .float-btn-lbt:nth-child(n+2){margin-left:5px}list-block-common-component .acp-and-file-tbd,list-block-common-component .acp-tbd,list-block-common-component .depth-td-tdb,list-block-common-component .input-tbd{position:relative}list-block-common-component .acp-and-file-tbd:focus-within .float-btngroup-tbd,list-block-common-component .acp-and-file-tbd:hover .float-btngroup-tbd,list-block-common-component .acp-tbd:focus-within .float-btngroup-tbd,list-block-common-component .acp-tbd:hover .float-btngroup-tbd,list-block-common-component .depth-td-tdb:focus-within .float-btngroup-tbd,list-block-common-component .depth-td-tdb:hover .float-btngroup-tbd,list-block-common-component .input-tbd:focus-within .float-btngroup-tbd,list-block-common-component .input-tbd:hover .float-btngroup-tbd,list-block-common-component .more-btn-container:focus-within .more-div-btngroup-tbd{display:block}list-block-common-component .float-btngroup-acp-tbd{right:25px}list-block-common-component .float-btngroup-input-tbd{right:10px}list-block-common-component .more-btn-container{position:relative}list-block-common-component .disable-checkbox{cursor:not-allowed;color:#999;background-color:#fafafa}list-block-common-component .more-div-btngroup-tbd{background-color:#fff;-webkit-box-shadow:0 10px 15px rgba(0,0,0,.12);box-shadow:0 10px 15px rgba(0,0,0,.12);position:absolute;border-style:solid;border-width:1px;-webkit-border-radius:3px;border-radius:3px;right:0;z-index:2;border-color:#d9d9d9;display:none;margin-top:5px;cursor:pointer}list-block-common-component .more-div-btngroup-tbd button{height:35px;line-height:35px;padding:0 15px;text-align:left;color:#555;word-break:keep-all;display:block}list-block-common-component .more-div-btngroup-tbd button:hover{background-color:#eee;color:#607d8b;text-decoration:underline}list-block-common-component .more-btn:focus+.more-div-btngroup-tbd{display:block}list-block-common-component .tfooter-div{background-color:#f4f4f4;padding:0 15px;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:end;-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end;-webkit-box-shadow:0 4px 6px 0 rgba(31,31,31,.05);box-shadow:0 4px 6px 0 rgba(31,31,31,.05);height:60px;line-height:60px;border-top:1px solid #d9d9d9;text-align:center;position:relative}list-block-common-component .tfooter-div>div{position:absolute;left:20px}list-block-common-component .tfooter-div,list-block-common-component .tfooter-div .pagination{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}list-block-common-component .tfooter-div .pagination .first-page,list-block-common-component .tfooter-div .pagination .last-page{-webkit-border-radius:3px;border-radius:3px}list-block-common-component .tfooter-div .pagination>.active,list-block-common-component .tfooter-div .pagination>.active:focus,list-block-common-component .tfooter-div .pagination>.active:hover{background-color:#333}list-block-common-component .tfooter-div .pagination-next .iconfont,list-block-common-component .tfooter-div .pagination-prev .iconfont{font-weight:700}list-block-common-component .tfooter-div .pagination-prev{margin-right:15px}list-block-common-component .tfooter-div .pagination-next{margin-left:15px}list-block-common-component .tfooter-div .pagination-page{width:25px;height:25px;line-height:25px;-webkit-border-radius:3px;border-radius:3px;margin-right:5px}@-webkit-keyframes load{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes load{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}loading-Part-Common-Component .loading-content{z-index:10}loading-Part-Common-Component .loading-content .loading{padding:10px;-webkit-border-radius:3px;border-radius:3px}loading-Part-Common-Component .loading-content .loading li{height:50px;line-height:50px;text-align:center;color:#999}loading-Part-Common-Component .loading-content .loading li .iconfont{font-size:18px;color:#999}loading-Part-Common-Component .loading-content .loading li div,loading-common-component .loading-content .loading li div{-webkit-animation:load 1.7s infinite ease;animation:load 1.7s infinite ease;display:inline-block;margin-right:10px}menu-Default-Common-Component .common_menu_ul{padding:0 10px;background-color:#fff;width:100%;height:50px;line-height:50px;margin-top:15px;-webkit-border-radius:0 3px 0 0;border-radius:0 3px 0 0;border-right:1px solid #d9d9d9;border-top:1px solid #d9d9d9;border-left:1px solid #d9d9d9}menu-Default-Common-Component .common_menu_ul .menu-title{float:left}menu-Default-Common-Component .common_menu_ul .eo_more_btn:focus+.wrap_div_mcc,menu-Default-Common-Component .common_menu_ul .more-btn-box .more-btn-right:focus+.more-btn-div{display:block}menu-Default-Common-Component .common_menu_ul .wrap_div_mcc{z-index:4;color:#333;-webkit-box-shadow:0 10px 15px rgba(0,0,0,.12);box-shadow:0 10px 15px rgba(0,0,0,.12);min-width:200px;line-height:30px;border:1px solid #d9d9d9;background-color:#fff;font-size:12px;display:none;right:-11px}menu-Default-Common-Component .common_menu_ul .wrap_div_mcc .checkbox-td,menu-Default-Common-Component .common_menu_ul .wrap_div_mcc .checkbox-th{border-right:none}menu-Default-Common-Component .common_menu_ul .wrap_div_mcc .tbody-div{max-height:200px;overflow:auto}menu-Default-Common-Component .common_menu_ul .wrap_div_mcc .thead-div,menu-Default-Common-Component .common_menu_ul .wrap_div_mcc .tr-tbd{height:30px}menu-Default-Common-Component .common_menu_ul .wrap_div_mcc .checkbox-td{padding-top:7px!important}menu-Default-Common-Component .common_menu_ul .wrap_div_mcc:hover{display:block}menu-Default-Common-Component .common_menu_ul .common-btn-list .common-btn{margin-left:15px}menu-Default-Common-Component .common_menu_ul .common-btn-list-first .common-btn:first-child{margin-left:0}menu-Default-Common-Component .common_menu_ul .common-btn{height:32px;line-height:32px;display:inline-block;text-align:center;vertical-align:middle}menu-Default-Common-Component .common_menu_ul .common-btn .iconfont{font-size:24px;margin-right:5px}menu-Default-Common-Component .common_menu_ul .common-btn:hover{color:#2196f3}menu-Default-Common-Component .common_menu_ul .common-btn:hover .disabled-tip{display:block}menu-Default-Common-Component .common_menu_ul .common-btn:disabled,menu-Default-Common-Component .common_menu_ul .common-btn:disabled .iconfont{color:#999;cursor:not-allowed}menu-Default-Common-Component .common_menu_ul .block-btn .iconfont{margin-right:0}menu-Default-Common-Component .common_menu_ul .block-btn:hover{color:#fff}menu-Default-Common-Component .common_menu_ul .block-btn:disabled{background-color:#fafafa;color:#999;border:1px solid #ddd}menu-Default-Common-Component .common_menu_ul .more-btn-box{position:relative}menu-Default-Common-Component .common_menu_ul .more-btn-box .more-btn-left{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}menu-Default-Common-Component .common_menu_ul .more-btn-box .more-btn-right{border-left:1px solid rgba(0,0,0,.1);-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;padding:0 5px}menu-Default-Common-Component .common_menu_ul .more-btn-box .more-btn-div{position:absolute;right:0;z-index:2;display:none;margin-top:-1px}menu-Default-Common-Component .common_menu_ul .more-btn-box .more-btn-div .more-btn-list{background-color:#fff;border:1px solid #d9d9d9;-webkit-border-radius:3px;border-radius:3px}menu-Default-Common-Component .common_menu_ul .fun-list-li .list_function_wrap .nav-function li,menu-Default-Common-Component .common_menu_ul .more-btn-box .more-btn-div .more-btn-list li{height:35px;line-height:35px;cursor:pointer;text-align:left;min-width:60px;padding:0 10px;white-space:nowrap}menu-Default-Common-Component .common_menu_ul .more-btn-box .more-btn-div .more-btn-list li:active,menu-Default-Common-Component .common_menu_ul .more-btn-box .more-btn-div .more-btn-list li:focus,menu-Default-Common-Component .common_menu_ul .more-btn-box .more-btn-div .more-btn-list li:hover{background-color:#fafafa;text-decoration:underline}menu-Default-Common-Component .common_menu_ul .block-btn .iconfont,menu-Default-Common-Component .common_menu_ul .more-btn-left .iconfont,menu-Default-Common-Component .common_menu_ul .more-btn-right .iconfont{font-size:14px}menu-Default-Common-Component .common_menu_ul .default-btn{border-style:solid;border-width:1px;-webkit-border-radius:3px;border-radius:3px}menu-Default-Common-Component .common_menu_ul .fun-list-li{cursor:pointer;text-align:center;margin-left:15px}menu-Default-Common-Component .common_menu_ul .fun-list-li .iconfont{cursor:pointer;font-size:24px}menu-Default-Common-Component .common_menu_ul .fun-list-li:hover{color:#2196f3}menu-Default-Common-Component .common_menu_ul .fun-list-li:hover .list_function_wrap,select-default-common-component{display:block}menu-Default-Common-Component .common_menu_ul .fun-list-li .disabled-btn,menu-Default-Common-Component .common_menu_ul .fun-list-li .disabled-btn .iconfont{color:#999;cursor:not-allowed}menu-Default-Common-Component .common_menu_ul .fun-list-li .disabled-btn .list_function_wrap{display:none}menu-Default-Common-Component .common_menu_ul .fun-list-li .list_function_wrap{position:absolute;cursor:default;margin-top:-1px;display:none;z-index:4;color:#333;-webkit-box-shadow:0 10px 15px rgba(0,0,0,.12);box-shadow:0 10px 15px rgba(0,0,0,.12)}menu-Default-Common-Component .common_menu_ul .fun-list-li .list_function_wrap .nav-function{background-color:#fff;border:1px solid #d9d9d9;-webkit-border-radius:3px;border-radius:3px}menu-Default-Common-Component .common_menu_ul .fun-list-li .list_function_wrap .nav-function li:active,menu-Default-Common-Component .common_menu_ul .fun-list-li .list_function_wrap .nav-function li:focus,menu-Default-Common-Component .common_menu_ul .fun-list-li .list_function_wrap .nav-function li:hover{background-color:#fafafa}menu-Default-Common-Component .common_menu_ul .fun-list-li .list_function_wrap .nav-function .strong-li{font-weight:700;color:#2196f3}menu-Default-Common-Component .common_menu_ul .batch_cancel_ldcc+.fun-list-li{margin-left:0}menu-Default-Common-Component .common_menu_ul .combo_box_mdcc{line-height:51px}menu-Default-Common-Component .common_menu_ul .vertical_divide_line_mdcc{color:#d9d9d9}menu-Default-Common-Component .common_menu_ul .divide-span{border-right:1px solid #d9d9d9;margin-left:15px}menu-Default-Common-Component .common_menu_ul .elem-active{cursor:default}menu-Default-Common-Component .common_menu_ul .menu-li{border-style:solid;border-width:1px;-webkit-border-radius:3px;border-radius:3px;overflow:hidden;margin-right:5px}menu-Default-Common-Component .common_menu_ul .menu-li a{padding:0 20px;height:30px;line-height:30px;display:inline-block}menu-Default-Common-Component .common_menu_ul .first-menu-li{margin-left:5px}menu-Default-Common-Component .common_menu_ul .menu-navigation{position:absolute;bottom:0}menu-Default-Common-Component .common_menu_ul .menu-navigation li{cursor:pointer;height:40px;line-height:40px;padding:0 15px;text-align:center;margin-right:2px;border-bottom-style:solid;border-bottom-width:3px}menu-Default-Common-Component .common_menu_ul .search-form{height:50px;line-height:50px;z-index:2;right:0}menu-Default-Common-Component .common_menu_ul .search-tips{color:#9e9e9e;background-color:#ededed;height:30px;line-height:30px;border:1px solid #d9d9d9;padding:0 10px;-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;cursor:default}menu-Default-Common-Component .common_menu_ul .search-div{height:28px;line-height:28px;width:100px;border:1px solid #d9d9d9;background-color:#fff;-webkit-border-radius:3px;border-radius:3px;-webkit-transition:width .3s linear 0s;transition:width .3s linear 0s;overflow:hidden;white-space:nowrap}menu-Default-Common-Component .common_menu_ul .search-div .search-input{width:-webkit-calc(100% - 30px);width:calc(100% - 30px);height:100%;border:none}menu-Default-Common-Component .common_menu_ul .search-div .search-tap-box{-webkit-border-radius:3px;border-radius:3px;left:25px;background-color:#eee;height:20px;line-height:20px}menu-Default-Common-Component .common_menu_ul .search-div .search-text{border-right:1px solid #d9d9d9;padding:0 5px;max-width:130px;text-overflow:ellipsis;-webkit-transition:max-width .1s linear 0s;transition:max-width .1s linear 0s;overflow:hidden}menu-Default-Common-Component .common_menu_ul .search-div .search-tap .iconfont:hover{color:#e83333}menu-Default-Common-Component .common_menu_ul .search-input-width-200{width:200px}menu-Default-Common-Component .common_menu_ul .search-div-advanced .advanced-btn{display:none;height:20px;line-height:20px;min-width:24px}menu-Default-Common-Component .common_menu_ul .search-div-advanced:focus .search-input,menu-Default-Common-Component .common_menu_ul .search-div-advanced:hover .search-input{width:-webkit-calc(100% - 75px);width:calc(100% - 75px)}menu-Default-Common-Component .common_menu_ul .search-div-advanced:focus .search-text,menu-Default-Common-Component .common_menu_ul .search-div-advanced:hover .search-text{max-width:75px}menu-Default-Common-Component .common_menu_ul .search-div-advanced:focus .advanced-btn,menu-Default-Common-Component .common_menu_ul .search-div-advanced:hover .advanced-btn{display:initial}menu-Default-Common-Component .common_menu_ul .menu-ml15{margin-left:15px}menu-Default-Common-Component .common_menu_ul .menu-ml10{margin-left:10px}menu-Default-Common-Component .common_menu_ul .menu-mr15{margin-right:15px}menu-Default-Common-Component .common_menu_ul .menu-mr10{margin-right:10px}menu-Default-Common-Component .common_menu_ul .menu-mr5{margin-right:5px}gpedit-inside-auth .common-table .required-td label,menu-Default-Common-Component .common_menu_ul .menu-mr0{margin-right:0}menu-Default-Common-Component .common_menu_ul .menu-ml0{margin-left:0}menu-Default-Common-Component .common-menu-lg{padding:20px;height:auto;line-height:initial;width:-webkit-calc(100% - 276px);width:calc(100% - 276px)}menu-Default-Common-Component .common-menu-lg .menu-title{float:none;margin-bottom:15px}menu-Default-Common-Component .common-menu-lg .vertical_divide_line_mdcc{line-height:32px}menu-Default-Common-Component .can-operate-placeholder{height:112px}menu-Default-Common-Component .can-operate-has-second-title-placeholder{height:160px}menu-Default-Common-Component .disabled-operate-placeholder{height:83px}menu-Default-Common-Component .disabled-operate-has-second-title-placeholder{height:123px}menu-Default-Common-Component .common-menu-md{height:105px}menu-Default-Common-Component .common-menu-fixed-seperate{margin:0;background-color:#fff;border-top:none;border-left:none;border-bottom:1px solid #d9d9d9;position:fixed;z-index:5;-webkit-box-shadow:0 0 10px rgba(0,0,0,.1);box-shadow:0 0 10px rgba(0,0,0,.1)}menu-Default-Common-Component .common-menu-only-navigation{height:50px;line-height:50px}menu-Default-Common-Component .divide-li{line-height:60px}menu-Default-Common-Component .tsc_ul{margin-top:10px}menu-Default-Common-Component .view-btn-li{margin-left:5px}menu-Default-Common-Component .view-btn-li>ul{-webkit-border-radius:3px;border-radius:3px;overflow:hidden}menu-Default-Common-Component .view-btn-li>ul .view-common-btn{cursor:pointer;height:30px;line-height:30px;text-align:center;padding:0 10px;border-style:solid;border-width:1px}menu-Default-Common-Component .view-btn-li>ul .view-common-btn+.view-common-btn{margin-left:0;border-left-style:none}.gateway-modal-copy-api tip-directive,menu-Default-Common-Component .un-margin-left{margin-left:0}menu-Default-Common-Component .disabled-tip{position:absolute;margin-top:-69px;z-index:10;display:none}menu-Default-Common-Component .disabled-tip .tip-div{padding:10px;line-height:initial;-webkit-border-radius:3px;border-radius:3px;background-color:#000;color:#fff;font-size:12px;text-align:left;max-width:500px;min-width:200px}menu-Default-Common-Component .disabled-tip .arrow-div{border-color:#000 transparent transparent transparent;border-width:5px 5px 0;border-style:solid;width:0;margin-left:8px}.shrink-div .common-menu-fixed-seperate{width:-webkit-calc(100% - 66px);width:calc(100% - 66px)}.shrink-div .common-menu-lg{width:-webkit-calc(100% - 86px);width:calc(100% - 86px)}menu-radio-common-component span{display:inline-block;line-height:30px}menu-radio-common-component button:disabled{cursor:not-allowed}progress-bar-common-component .container_pbcc{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;-webkit-border-radius:3px;border-radius:3px;overflow:hidden;background-color:#00ab6d;color:#fff}progress-bar-common-component .item_btn_pbcc{height:30px}progress-bar-common-component .active_item_btn_pbcc~button{background-color:#ccc;color:#333}progress-bar-common-component .active_item_btn_pbcc~button:hover{background-color:#ddd}select-default-common-component .container-div{width:-webkit-calc(100% - 2px);width:-ms-calc(100% - 2px);width:calc(100% - 2px);display:block;position:relative;color:#333}select-default-common-component .container-div:hover .preview-text-p{border-color:#999;-webkit-transition:all .2s cubic-bezier(.645,.045,.355,1);transition:all .2s cubic-bezier(.645,.045,.355,1)}select-default-common-component .search-p{background-color:#f8f8f8;height:40px;padding:0 10px;line-height:42px}select-default-common-component .search-p input[type=text]{border:none;background:0 0;height:40px;width:100%}select-default-common-component .search-p .iconfont{font-size:16px;padding-right:5px}select-default-common-component .search-p button{height:28px;line-height:28px;padding:0 10px;margin-top:6px;font-size:12px;width:60px}select-default-common-component .container-focus .list-container-div{display:block}select-default-common-component .container-div:focus-within .list-container-div{display:block}select-default-common-component .input-text:focus+.list-container-div{display:block}select-default-common-component .preview-text-p span:first-child{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}select-default-common-component .sd_check_box{border:1px solid #d9d9d9;height:15px;line-height:15px;-webkit-border-radius:3px;border-radius:3px;margin-right:10px;width:15px;text-align:center}select-default-common-component .arrow-span{position:absolute;right:5px;top:0}select-default-common-component .container-div:focus-within .preview-text-p{border-color:#089462}select-default-common-component .opacity-text-input{position:absolute;opacity:0;z-index:1;top:0}select-default-common-component .opacity-text-input:focus{z-index:-1}select-default-common-component .opacity-text-input:disabled{cursor:not-allowed}select-default-common-component .icon-guanbi{border:none;background-color:transparent;position:relative;z-index:1;top:-32px;height:0;line-height:35px;margin-right:5px}select-default-common-component .hide-node{z-index:-1}select-default-common-component .text-p{border:1px solid #d9d9d9;background-color:#fff;-webkit-border-radius:3px;border-radius:3px;color:#333;height:28px;line-height:30px;padding:0 5px;width:-webkit-calc(100% - 10px);width:-ms-calc(100% - 10px);width:calc(100% - 10px);cursor:pointer;font-size:12px;overflow:hidden}select-default-common-component .disabled_preview_text_p{color:#999;background-color:#fafafa}select-default-common-component .list-container-div{-webkit-border-radius:3px;border-radius:3px;background-color:#fff;border:1px solid #d9d9d9;width:100%;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;margin-top:2px;font-size:12px;position:absolute;-webkit-box-shadow:0 10px 15px rgba(0,0,0,.12);box-shadow:0 10px 15px rgba(0,0,0,.12);z-index:2;display:none}select-default-common-component .query-container-child-div{max-height:210px;overflow:auto}select-default-common-component .common-class-item{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer}.modal-open .common-modal-import article .modal-import-info .modal-btn-group-ul li:hover,select-default-common-component .common-class-item:hover,select-default-common-component .select-active-item{background-color:#fafafa}select-default-common-component .common-class-item,select-default-common-component .un-search-response-p{height:35px;line-height:35px;padding:0 10px}tip-directive{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;height:20px;line-height:20px;margin-left:5px}tip-directive .iconfont{color:rgba(0,0,0,.5);cursor:help;display:inline-block;font-weight:initial}tip-directive:hover .tips-message{visibility:visible}.move-tip-directive{position:fixed;z-index:100;visibility:hidden}.move-tip-directive .message-li{padding:10px;line-height:initial;-webkit-border-radius:3px;border-radius:3px;background-color:#000;color:#fff;font-size:12px;text-align:left;max-width:500px;min-width:150px}.move-tip-directive .message-li *{color:#fff}.move-tip-directive .arrow-li{border-color:#000 transparent transparent transparent;border-width:5px 5px 0;border-style:solid;width:0;margin-left:8px}.account-setting-common-scss{display:block;padding:15px}.account-setting-common-scss article{background:#fff;border:1px solid #e5e5e5;-webkit-border-radius:3px;border-radius:3px;font-size:14px}.account-setting-common-scss article .disabled-btn{cursor:not-allowed}.account-setting-common-scss article .title-p{border-bottom:1px solid #e5e5e5;padding-bottom:10px}.account-setting-common-scss article .warning-span{color:red;margin-left:5px;font-size:13px}.account-setting-common-scss article .open-alert-btn{display:inline-block;text-align:center;margin-left:10px;font-size:20px;padding:0;min-width:auto}.account-setting-common-scss article .icon-huadongkaiguan-dakai{color:#00ab6d}.account-setting-common-scss article .btn-group-li{margin-top:30px}.account-setting-common-scss article .btn-group-li button,.account-setting-common-scss article .btn-group-li input[type=button]{min-width:60px;padding:0 10px}.account-setting-common-scss article .btn-group-li button:disabled,.account-setting-common-scss article .btn-group-li button:disabled:hover,.account-setting-common-scss article .btn-group-li input[type=button]:disabled,.account-setting-common-scss article .btn-group-li input[type=button]:disabled:hover{background-color:#b7b7b7;color:#fff;border-color:#b7b7b7;cursor:not-allowed}.account-setting-common-scss article .btn-group-li button,home .home-content .home-div .home-header li button span{margin-right:5px}.account-setting-common-scss article .btn-group-li .list-div{display:inline-grid}.account-setting-common-scss article .btn-group-li .list-div p{line-height:40px}.account-setting-common-scss article .btn-group-li .list-div button{width:80px}.account-setting-common-scss article:nth-child(n+2){margin-top:10px}.account-setting-common-scss article .tips-span{color:#999;font-size:13px;margin-left:10px;display:inline-block}.account-setting-common-scss article input[type=text]:disabled,.account-setting-common-scss article select:disabled{background-color:#fafafa;cursor:not-allowed}.account-setting-common-scss article .icon-shanchu{width:25px;height:25px;line-height:25px;-webkit-border-radius:3px;border-radius:3px;background-color:#f2f2f2;color:#9e9e9e;display:inline-block;text-align:center;border:1px solid #ddd;margin-left:10px}.account-setting-common-scss article .icon-shanchu:hover{background-color:#e83333;color:#fff;border:1px solid #d03333}.account-setting-common-scss article tr:nth-child(n+2) td{padding-top:10px}.common-scss-group{width:240px;position:fixed;left:initial;z-index:3;height:-webkit-calc(100% - 79px);height:-ms-calc(100% - 79px);height:calc(100% - 79px)}.common-scss-group .title-ul{height:50px;line-height:50px;padding:0 10px;background-color:#fff;-webkit-border-radius:3px 0 0 0;border-radius:3px 0 0 0;border-bottom:1px solid #d9d9d9}.common-scss-group .title-ul .common-btn{height:32px;line-height:32px;font-size:13px;display:inline-block;vertical-align:middle}.common-scss-group .title-ul .default-btn{border-style:solid;border-width:1px;margin-left:5px;-webkit-border-radius:3px;border-radius:3px}.common-scss-group .group-ul{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;height:-webkit-calc(100% - 51px);height:-ms-calc(100% - 51px);height:calc(100% - 51px);position:absolute;width:100%;overflow-y:auto;overflow-x:hidden}.common-scss-group .group-li{overflow:hidden;font-size:12px;height:40px;line-height:40px;padding-left:10px;cursor:pointer}.common-scss-group .group-li .group-name{max-width:-webkit-calc(100% - 62px);max-width:calc(100% - 62px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer}.common-scss-group .group-li .active{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;float:right}.common-scss-group .group-li .icon-iosgengduo{display:inline-block;padding-right:10px}.common-scss-group .group-li .iconfont{float:left;margin-right:5px;cursor:pointer;line-height:41px;font-size:18px}.common-scss-group .group-li .group-function{position:absolute;right:10px;border-style:solid;border-width:1px;-webkit-border-radius:3px;border-radius:3px;z-index:2}.common-scss-group .group-li .group-function li{font-weight:initial;cursor:pointer;padding:0 20px}home>div{min-width:1000px}home .home-content .home-div{margin:51px 0 0 241px}home .home-content .home-div .home-header li button{width:100px;height:30px;line-height:30px;margin-top:15px}home .shrink-div .home-content .home-div{margin-left:51px}home .home-common-only-list-div{padding:0 15px 15px}home .home-common-project-list .common_scss_list{margin:15px}home .home-common-project-list .common-menu-fixed-seperate{-webkit-box-shadow:0 0 10px rgba(0,0,0,.1);box-shadow:0 0 10px rgba(0,0,0,.1);border-bottom:none}balance-list menu-Default-Common-Component .common_menu_ul .search-form,balance-service menu-Default-Common-Component .common_menu_ul .search-form,plugin-Default menu-Default-Common-Component .common_menu_ul .search-form{position:absolute;right:20px;bottom:20px;height:auto}.checkbox-btn{text-align:center;-webkit-border-radius:3px;border-radius:3px;border:1px solid #bcdffb;background-color:#e3f7ff;color:#1e88e5;padding:0 5px;height:30px;line-height:30px;font-size:12px}.checkbox-btn .eo-checkbox{margin:6px 5px 0 0;height:15px;line-height:15px;width:15px;border-color:#1e88e5}.home-common-has-group-div{margin:0 0 0 256px}.input-icon-span{position:absolute;display:inline-block;line-height:38px;margin:1px;text-indent:15px}.display-container-div{display:table;background-color:#f7f8fc;position:absolute;width:100%;top:0;left:0;height:100%;z-index:-1}.menu-divide-span{line-height:34px;margin-top:-4px;float:left;color:#999;font-weight:lighter}@keyframes load{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}loading-common-component .loading-content{top:109px;left:-webkit-calc(50% - 176px);left:-ms-calc(50% - 176px);left:calc(50% - 176px);position:fixed;z-index:10}loading-common-component .loading-content .loading{min-width:350px;max-width:500px;-webkit-border-radius:3px;border-radius:3px;background-color:#fff;border:1px solid #e5e5e5;-webkit-box-shadow:0 10px 29px #ccc;box-shadow:0 10px 29px #ccc}loading-common-component .loading-content .loading i,loading-common-component .loading-content .loading span{color:#e5e5e5}loading-common-component .loading-content .loading li{height:50px;line-height:50px;text-align:center;color:#555;font-size:14px}loading-common-component .loading-content .loading li .iconfont{color:#555;font-size:14px}tip-common-component .tips-ul{padding:0 10px;min-height:32px;line-height:34px;border:1px solid;-webkit-border-radius:3px;border-radius:3px;width:-webkit-calc(100% - 20px);width:-ms-calc(100% - 20px);width:calc(100% - 20px)}tip-common-component .tips-ul li{font-size:12px}tip-common-component .tips-ul .title-li{font-weight:700}tip-common-component .tips-ul>.content-li{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}tip-common-component .warning-ul{background-color:#fdefdd;border-color:#f57705}sidebar-common-component .footer_sidebar_cc{position:absolute;bottom:0;left:0;height:40px;line-height:41px;background-color:#f2f2f2;border-top:1px solid #d9d9d9;text-indent:12px;width:100%;overflow:hidden}sidebar-common-component .footer_sidebar_cc:hover{background-color:#f0f2f5}sidebar-common-component .footer_sidebar_cc:hover .iconfont,sidebar-common-component .shrink_footer_sidebar_cc .iconfont{color:#00b775}sidebar-common-component .text_footer_sidebar_cc{white-space:nowrap}sidebar-common-component .shrink_footer_sidebar_cc .text_footer_sidebar_cc{display:none}sidebar-common-component>div{height:100%;width:50px;color:#444}sidebar-common-component .tip_scc{float:left;line-height:50px}sidebar-common-component .tip_scc .iconfont{font-size:20px}sidebar-common-component .tip_scc .eo-tip-container{margin-top:-26px!important}sidebar-common-component .eo-sidebar{width:240px;position:fixed;top:0;left:0;z-index:10;border-right-style:solid;border-right-width:1px;-webkit-transition:all .3s cubic-bezier(0,0,.2,1);transition:all .3s cubic-bezier(0,0,.2,1)}sidebar-common-component .common-sidebar{height:-webkit-calc(100% - 91px);height:calc(100% - 91px);overflow:hidden}sidebar-common-component .common-sidebar .item-container-ul{height:100%}sidebar-common-component .divide-li{border-top-style:solid;border-top-width:1px}sidebar-common-component .divide-solid-bottom-li{border-bottom-style:solid;border-bottom-width:1px}sidebar-common-component .divide-solid-top-li{border-top-style:solid;border-top-width:1px}sidebar-common-component .default-div .item-container-ul{overflow-y:auto}sidebar-common-component .default-div .group-name1{margin-left:35px}sidebar-common-component .inside-sidebar{z-index:7}sidebar-common-component .item-li{height:45px;line-height:45px;overflow:hidden;text-indent:12px;cursor:pointer}sidebar-common-component .item-li .title-icon{font-size:24px;width:35px}sidebar-common-component .logo-li{text-align:left;background-color:#00ab6d;color:#fff}sidebar-common-component .logo-li .img-span{min-width:50px;display:inline-block}sidebar-common-component .logo-li .item-span{width:170px;font-weight:700;font-size:14px;overflow:hidden;white-space:nowrap}sidebar-common-component .disable-menu-li{cursor:default}.common_scss_list .first_level_article th,sidebar-common-component .static-sidebar{overflow:hidden}sidebar-common-component .static-li{height:50px;line-height:50px}sidebar-common-component .static-li .title-icon{margin-right:0;padding-right:15px}sidebar-common-component .parent-router-p{display:none;text-indent:15px;color:#999;line-height:28px}sidebar-common-component .float-s2 .parent-router-p,sidebar-common-component .shrink-sidebar-div .item-container-li:hover .list-item-div1{display:block}sidebar-common-component .had-child-div{margin-top:-50px}sidebar-common-component .had-child-div .parent-router-p{font-size:12px;background-color:#f3f3f3;font-weight:700}sidebar-common-component .un-child-div{margin-top:-45px}sidebar-common-component .un-child-div .float-s2{padding-bottom:0!important;width:-webkit-max-content!important;width:-moz-max-content!important;width:max-content!important;word-break:keep-all;padding-right:15px}sidebar-common-component .un-child-div .parent-router-p{background-color:#fff;line-height:40px;color:#333;font-weight:initial}sidebar-common-component .s1_tip_style{-webkit-border-radius:3px;border-radius:3px;padding:2px 5px;font-size:12px}sidebar-common-component .shrink-sidebar-div .list-item-div1{position:absolute;margin-left:50px;display:none}sidebar-common-component .shrink-sidebar-div .list-item-div1 div{margin-left:5px;width:180px;-webkit-border-radius:3px;border-radius:3px;overflow:hidden;-webkit-box-shadow:0 4px 6px 0 rgba(31,31,31,.05),0 0 2px 0 rgba(31,31,31,.2);box-shadow:0 4px 6px 0 rgba(31,31,31,.05),0 0 2px 0 rgba(31,31,31,.2);padding-bottom:5px}sidebar-common-component .shrink-sidebar-div .list-item-div1 div .item-li{height:40px;line-height:40px}sidebar-common-component .shrink-sidebar-div .list-item-div1 div .item-li:nth-child(n+2){margin-top:5px}.shrink-div sidebar-common-component .eo-sidebar{width:50px}overview-Product-Component .first-box{background-color:#fff;padding:40px;-webkit-box-shadow:0 0 10px rgba(0,0,0,.1);box-shadow:0 0 10px rgba(0,0,0,.1)}overview-Product-Component .productInfo-box{padding-top:30px}.gateway-modal-cluster .auth-type-p label,overview-Product-Component .btn-edit-project{cursor:pointer}overview-Product-Component .btn-edit-project:hover{color:#2196f3}overview-Product-Component .productInfo-ul{margin-right:140px}overview-Product-Component .productInfo-il{height:30px;line-height:30px}overview-Product-Component .productInfo-name{margin-right:5px}overview-Product-Component .project-operate{margin-top:30px;margin-bottom:-30px;padding-top:30px;border-top:1px solid #d9d9d9;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}overview-Product-Component .operate-box{width:300px;height:108px;border:1px solid #d9d9d9;margin-bottom:30px;margin-right:30px}overview-Product-Component .operate-box:hover{-webkit-box-shadow:0 4px 6px 0 rgba(0,0,0,.05);box-shadow:0 4px 6px 0 rgba(0,0,0,.05)}overview-Product-Component .operate-box-top{height:55px;padding-left:20px;padding-right:20px}overview-Product-Component .operate-box-bottom{-webkit-border-radius:3px;border-radius:3px;border-top:1px solid #d9d9d9;background-color:#f9f9f9}overview-Product-Component .common-btn{height:50px;line-height:50px;color:#666;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}overview-Product-Component .common-btn:hover{border-color:#d9d9d9;color:#2196f3}overview-Product-Component .common-btn .common_btn_divide{display:inline-block;vertical-align:middle;height:30px;line-height:30px;position:relative;right:25%;border-left:1px solid #d9d9d9}overview-Product-Component .list-box{margin:0 20px 20px}.btn-sm{height:35px;line-height:35px;width:40px;min-width:100%}.btn-sm *{color:inherit}.btn-sm:disabled{opacity:.5}.btn-sm:disabled,.btn-sm:disabled *{cursor:not-allowed}.btn-sm:disabled:hover{background-color:#f5f5f5}.uib-datepicker{border:1px solid #d9d9d9;-webkit-border-radius:3px;border-radius:3px;background-color:#fff;display:inline-block;vertical-align:text-top;margin:20px}.uib-datepicker table tr:nth-child(2){color:#333}.uib-datepicker .text-center{text-align:center}.uib-datepicker .td-selected{background-color:#4fc3f7;color:#fff}.uib-datepicker .td-selected:hover{background-color:#29b6f6;color:#fff}.uib-datepicker .td-selected:active{background-color:#29b6f6}.uib-datepicker .td-duration-selected{background-color:#1890ff}.uib-datepicker .td-duration-selected:active{background-color:#137cdd}.datapicker_time_directive{position:absolute;background-color:#fff;margin:10px 0 0 10px;-webkit-box-shadow:0 10px 15px rgba(0,0,0,.12);box-shadow:0 10px 15px rgba(0,0,0,.12);border:1px solid #d9d9d9;z-index:2}.datapicker_time_directive .time_desc{color:#333}.datapicker_time_directive .datapicker_footer{padding:15px 20px;border-top:1px solid #e5e5e5;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;background-color:#f9f9f9;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.uib-datepicker-popup.dropdown-menu{display:block;float:none;margin:0 auto;background-color:#fff}.modal-open .modal-group article input,.modal-open .modal-group article select,.modal-open .modal-project .eo-input[type=password],.modal-open .modal-project .eo-input[type=text],.modal-open .modal-project select-default-common-component .container-div,.modal-open .modal-project select-person-common-component .container-div,.modal-open .modal-project textarea,.uib-datepicker .uib-title{width:100%}.uib-button-bar{margin-top:20px;display:inline-block;width:100%}.btn-group-vertical,.datepicker-btn-group{position:relative;z-index:9999;display:inline-block;vertical-align:middle}.uib-day button,.uib-month button,.uib-year button{min-width:100%}.uib-day-disabled{opacity:.5}.uib-day-disabled:hover{background-color:#f5f5f5}.uib-position-measure{display:block!important;visibility:hidden!important;position:absolute!important;top:-9999px!important;left:-9999px!important}.uib-position-scrollbar-measure{position:absolute!important;top:-9999px!important;width:50px!important;height:50px!important;overflow:scroll!important}.uib-position-body-scrollbar-measure{overflow:scroll!important}.uib-clear,.uib-close,.uib-datepicker-current{min-width:100px}.sv-group-helper{position:fixed!important;z-index:99999;margin:0!important}.sv-group-helper .group-li{color:#999}.sv-group-helper .group-li,.sv-group-helper .group-li:hover{background-color:rgba(221,221,221,.3)}.sv-group-candidate-top{border-top:2px solid #26a69a}.sv-group-candidate-bottom{border-bottom:2px solid #26a69a}.sv-group-candidate{border:2px solid #26a69a}.sv-group-placeholder{opacity:.5}.sv-sorting-in-progress{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.sv-visibility-hidden{visibility:hidden!important;opacity:0!important}.modal-open .common-modal-singel-select,.modal-open .modal-project{width:600px}.modal-open .modal-project textarea{padding:10px;height:60px;text-indent:0}.modal-open .common-modal-import{width:190px}.modal-open .common-modal-import article .modal-import-info .modal-btn-group-ul{background-color:#f5f5f5;border:1px solid #e5e5e5;-webkit-border-radius:3px;border-radius:3px;margin:0 auto;overflow:hidden}.modal-open .common-modal-import article .modal-import-info .modal-btn-group-ul li{width:100%;height:130px;line-height:130px;cursor:pointer}.modal-open .common-modal-import article .modal-import-info .modal-btn-group-ul li input{width:150px;height:130px;position:absolute;cursor:pointer;opacity:0}.modal-open .common-modal-import article .modal-import-info .modal-btn-group-ul li a{display:inline-block;height:100%;width:100%;background:url(../assets/images/upload_icons.png) no-repeat;text-align:center}.modal-open .common-modal-import article .modal-import-info .modal-btn-group-ul li p{margin-top:46px}.modal-open .common-modal-import article .modal-import-info .modal-btn-group-ul .first-li a{background-position:-288px 9px}.modal-open .common-modal-import article .btn-group{height:10px;line-height:10px}.modal-open .modal-group,.modal-open .modal-sure{width:600px}.modal-open .modal-sure article input[type=text]{width:100%;margin-top:10px}.modal-open .modal-sure article .api-desc-textarea,.modal-open .modal-sure article .desc-textarea{height:80px;width:100%}.modal-open .modal-sure article .textarea-li{position:relative;min-height:96px;max-height:266px}.modal-open .modal-sure article .textarea-li .api-desc-textarea{position:absolute;top:0;left:0;padding:8px;height:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.modal-open .modal-sure .btn-confirm{min-width:56px}.modal-open .modal-sure .btn-confirm:disabled{color:#333;background-color:#d9d9d9;border:none}.modal-open .modal-export{width:500px}.modal-open .modal-export .view-btn-li{font-size:12px}.modal-open .modal-export .view-btn-li .view-common-btn{background-color:#fff;height:30px;line-height:30px;display:inline-block;text-align:center;padding:0 10px;border:1px solid #ddd;min-width:30px}.modal-open .modal-export .view-btn-li .view-common-btn:nth-child(n+2){border-left:none}.modal-open .modal-export .view-btn-li .view-common-btn:first-child{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.modal-open .modal-export .view-btn-li .last-view-common-btn{margin-left:0;border-left:none;-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.modal-open .modal-export .view-btn-li .elem-active{background-color:#00ab6d;color:#fff}.modal-open .common-modal-change-password{width:550px}.modal-open .common-modal-login{width:550px;text-align:left;-webkit-animation:fade .2s;animation:fade .2s;-webkit-box-shadow:0 10px 30px rgba(0,0,0,.1);box-shadow:0 10px 30px rgba(0,0,0,.1);background-color:#fff}.modal-open .common-modal-login .eo-input{width:100%}.modal-open .common-modal-singel-input{width:550px}.modal-open .modal-visual-group{width:600px}.modal-open .modal-visual-group .common-scss-group{position:initial;height:240px;width:560px;border:1px solid #ddd;-webkit-box-shadow:none;box-shadow:none}.modal-open .modal-visual-group .group-article-0{height:100%}.modal-open .modal-visual-group .group-ul{position:initial;height:100%;-webkit-box-shadow:none;box-shadow:none}.modal-open .modal-visual-group .group-ul .title-li{display:none}.modal-open .modal-visual-group .group-ul .item-li{margin-top:-10px;height:100%}.gateway-modal-service .icon-huadongkaiguan-dakai{color:#00ab6d}.gateway-modal-gpedit-api-plugin .first-level-article{margin:0;border:none;padding:0}.gateway-modal-gpedit-api-plugin .title-p:first-child{line-height:inherit;margin-bottom:10px}.gateway-modal-cluster .common-p select,.gateway-modal-gpedit-api-plugin .eo-input,.gateway-modal-gpedit-default .common-p select{width:100%}.gateway-modal-copy-api{width:640px}.gateway-modal-node-check-error-report{width:600px}.gateway-modal-node-check-error-report article{width:-webkit-calc(100% - 40px);width:-ms-calc(100% - 40px);width:calc(100% - 40px);padding:20px;line-height:1.75em;max-height:600px;overflow:auto}.gateway-modal-node-check-error-report article>div:nth-child(n+2){border-top:1px dashed #e5e5e5;margin-top:10px;padding-top:10px}.gateway-modal-node-check-error-report table{border-bottom:1px solid #e5e5e5;width:100%;padding:0 20px;height:61px}.gateway-modal-node-check-error-report table button{width:60px}.gateway-modal-node-check-error-report table .title-p{font-size:18px;margin-bottom:5px}.gateway-modal-change-password{width:400px}.gateway-modal-change-password .eo-input,.gateway-modal-cluster .common-p input,.gateway-modal-gpedit-default .common-p input{width:-webkit-calc(100% - 2px);width:-ms-calc(100% - 2px);width:calc(100% - 2px)}.gateway-modal-change-password .ng-invalid-password-confirm-directive,.gateway-modal-change-password .ng-invalid-pattern{border:1px solid #d85030}.gateway-modal-cluster,.gateway-modal-gpedit-default{width:570px}.gateway-modal-cluster .common-p textarea,.gateway-modal-gpedit-default .common-p textarea{width:-webkit-calc(100% - 22px);width:-ms-calc(100% - 22px);width:calc(100% - 22px);min-height:80px}@keyframes load{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.gateway-modal-cluster .icon-jiazai_shuaxin{-webkit-animation:load 1.7s infinite ease;animation:load 1.7s infinite ease;display:inline-block}.gateway-modal-cluster .testing-div{display:inline-block}.gateway-modal-cluster .auth-type-p .iconfont{margin-right:5px;font-size:18px}.gateway-modal-cluster .auth-type-p .name-label{margin-right:10px}.gateway-modal-cluster .auth-type-p .icon-danxuanxuanzhong{color:#089462}eo-navbar{margin:0 auto;border:none;z-index:9;min-width:1000px;position:fixed}eo-navbar,eo-navbar1,login{width:100%;top:0;left:0}eo-navbar1{z-index:7;background-color:#fff;position:fixed}eo-navbar1 .nav-router-container{height:50px;line-height:50px;text-align:left}eo-navbar1 .nav-container{height:50px;border-bottom-width:1px;border-bottom-style:solid}eo-navbar1 .space-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:230px;display:inline-block}eo-navbar1 .select-nav-item:hover .list-ni,eo-navbar1 .special-select-nav-item:hover .list-ni,plugin-operate{display:block}eo-navbar1 .special-select-nav-item:hover .list-ni{right:5px}eo-navbar1 .list-ni{background-color:#fff;-webkit-box-shadow:0 10px 15px rgba(0,0,0,.12);box-shadow:0 10px 15px rgba(0,0,0,.12);min-width:160px;-webkit-border-radius:3px;border-radius:3px;border:1px solid #d9d9d9;position:absolute;display:none}eo-navbar1 .item-lni{text-align:left;line-height:43px;cursor:pointer}eo-navbar1 .item-lni a{padding:0 10px;display:block}eo-navbar1 .btn-item-lni{padding:0 10px}eo-navbar1 .user-logo-tni{height:20px;line-height:20px;-webkit-border-radius:10px;border-radius:10px;width:20px;background-color:#d9d9d9;background-size:contain}eo-navbar1 .divide-top-item-lni{border-top-style:solid;border-top-width:1px}eo-navbar1 .unread-new-tip{color:#fff;background-color:#e83333;-webkit-border-radius:9px;border-radius:9px;padding:0 10px;font-size:12px;display:inline-block;height:18px;line-height:20px}eo-navbar1 .space-container{position:fixed;width:100%;text-align:center;top:0;left:0}eo-navbar1 .shrink-btn{height:50px;padding:0 20px}eo-navbar1 .zindex-top-container{z-index:1}eo-navbar1 .nav-item,eo-navbar1 .text-ni{width:auto;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;padding:0 15px;line-height:50px;cursor:pointer}login{position:absolute;height:100%;display:table}login .login-wrap{vertical-align:middle;display:table-cell;background-color:#f7f8fc}login .login-wrap .login-content{width:325px;margin:-100px auto 30px;text-align:left;padding:30px;font-size:14px;-webkit-box-shadow:0 0 14px #d4d4d4;box-shadow:0 0 14px #d4d4d4;background-color:#fff}login .login-wrap .login-content header .logo-p{margin-bottom:30px;font-size:30px}login .login-wrap .login-content header .tips-p{color:#666;line-height:1.75em}login .login-wrap .login-content article li{margin-bottom:15px;height:37px;line-height:37px}login .login-wrap .login-content article li .iconfont:active,login .login-wrap .login-content article li .iconfont:focus,login .login-wrap .login-content article li .iconfont:hover{color:#333}login .login-wrap .login-content article .password-li .iconfont{position:absolute;height:18px;line-height:18px;padding:0 9px;margin-left:-39px;margin-top:9px}login .login-wrap .login-content article li:first-child{margin-top:20px}login .login-wrap .login-content article li:nth-child(n+4){margin-bottom:25px}ace-editor-ams-component,login .login-wrap .login-content article .eo-input{width:-webkit-calc(100% - 2px);width:-ms-calc(100% - 2px);width:calc(100% - 2px)}login .login-wrap .login-content article .eo_theme_btn_default,login .login-wrap .login-content article .eo_theme_btn_success{width:100%}ace-editor-ams-component{display:block;border:1px solid #e5e5e5;margin:0 0 10px;-webkit-border-radius:3px;border-radius:3px;max-width:100%}group-default-common-component .cc-group-container{margin-top:15px;border:1px solid #d9d9d9;margin-left:15px}group-default-common-component .divide-li{border-bottom-style:dashed;border-bottom-width:1px}group-default-common-component .more-btn-box{position:relative}group-default-common-component .more-btn-left{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}group-default-common-component .more-btn-right{border-left:1px solid rgba(0,0,0,.1);-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;padding:0 5px}group-default-common-component .more-btn-right:focus+.more-btn-list{display:block}group-default-common-component .more-btn-list{position:absolute;background-color:#fff;border:1px solid #d9d9d9;-webkit-border-radius:3px;border-radius:3px;z-index:2;left:0;display:none}group-default-common-component .item-li{height:35px;line-height:35px;cursor:pointer;text-align:left;min-width:60px;padding:0 20px;white-space:nowrap}group-default-common-component .item-li:active,group-default-common-component .item-li:focus,group-default-common-component .item-li:hover{background-color:#fafafa;text-decoration:underline}group-default-common-component .shrink-btn:hover{color:#00b775}group-default-common-component .shrink-gdcc{width:60px;background-color:#fff}group-default-common-component .untop-gdcc .group-ul{height:-webkit-calc(100% - 41px);height:-ms-calc(100% - 41px);height:calc(100% - 41px)}.shrink-group-div .home-common-has-group-div{margin:0 0 0 76px}.shrink-group-div .common-scss-group .title-ul{border-bottom:none}group-common-component .home-project-inside-group .account-span{color:#999}group-common-component .home-project-inside-group .sort-group-li .group-li,group-common-component .home-project-inside-group .sort-group-li .group-li .group-name{cursor:move}group-common-component .home-project-inside-group .divide-li{border-bottom:1px dashed #e5e5e5}group-common-component .home-project-inside-group .sv-helper,group-common-component .home-project-inside-group .sv-helper *{background-color:#eee}group-common-component .home-project-inside-group .title-ul>li .tab-last-btn{margin-left:0;border-left:none;-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}group-common-component .home-project-inside-group .title-ul>li .tab-first-btn{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}api-operate .home-common-project-list tip-directive,balance-operate tip-directive,group-common-component .home-project-inside-group .title-ul>li .un-margin-left-btn{margin-left:0}group-common-component .home-project-inside-group .child-group-div .api-list-li{padding-right:0}group-common-component .home-project-inside-group .child-group-div .api-list-li>.group-li{padding-left:2em}group-common-component .home-project-inside-group .child-group-div .api-list-li .group-name{text-indent:0;color:#333}group-common-component .home-project-inside-group .child-group-div .api-list-li .group-function{margin-left:-67px}group-common-component .un-top-group-common-component{margin-top:0!important}group-common-component .un-top-group-common-component .group-ul{height:-webkit-calc(100% - 41px);height:-ms-calc(100% - 41px);height:calc(100% - 41px)}list-default-common-component .bottom-count-div{padding:0 28px;height:50px;line-height:50px}list-default-common-component .common_scss_list .first_level_article thead tr{height:40px}list-default-common-component .first_level_article{width:100%}list-default-common-component .fixed-height-list{position:fixed;-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;margin:0 15px 15px 0;height:-webkit-calc(100% - 130px);height:-ms-calc(100% - 130px);height:calc(100% - 130px);overflow-y:hidden;width:-webkit-calc(100% - 514px);width:-ms-calc(100% - 514px);width:calc(100% - 514px)}list-default-common-component .fixed-height-list .thead_container_ldcc{overflow-y:scroll}list-default-common-component .fixed-height-list .tbody_container_ldcc{position:absolute;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:inherit;overflow-y:scroll;height:-webkit-calc(100% - 41px);height:calc(100% - 41px);overflow-x:hidden}list-default-common-component .thead_container_ldcc{z-index:1;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;position:relative;overflow-x:hidden}list-default-common-component .unplaceholder_thead_ldcc tr{height:0!important;line-height:0}list-default-common-component .placeholder_item{background-color:transparent}list-default-common-component .select_all_box{width:36px;border:1px solid #d9d9d9;padding:3px;-webkit-border-radius:3px;border-radius:3px}list-default-common-component .select_all_box .eo-checkbox{width:20px;margin-right:0;height:20px;line-height:20px}list-default-common-component .select_all_box .iconfont{font-weight:400}list-default-common-component .select_all_show_more{line-height:20px;padding-left:4px}list-default-common-component .placeholder_item{padding:10px}list-default-common-component .select_all_placeholder{z-index:1;padding-top:12px;margin-left:15px;margin-top:-17px}list-default-common-component .select_all_placeholder .select_all_ul{font-weight:400;border:1px solid #d9d9d9;-webkit-border-radius:3px;border-radius:3px}list-default-common-component .select_all_placeholder .select_all_item{height:30px;line-height:30px;padding:0 10px;cursor:pointer;font-size:12px}list-default-common-component .eo-checkbox:disabled{color:#9e9e9e;background-color:#ededed;border:1px solid #d9d9d9}list-default-common-component .conatiner_ldcc{position:relative;height:100%}list-default-common-component .conatiner_ldcc_draggable{overflow-x:auto}list-default-common-component .conatiner_ldcc_has_footer{height:-webkit-calc(100% - 40px);height:calc(100% - 40px)}list-default-common-component .divide_line_ldcc{border-right:1px solid #d9d9d9;right:0;top:0;position:absolute;height:100%}list-default-common-component .drag_divide_line_ldcc:last-child .divide_line_ldcc,list-default-common-component .th_bdr_none .divide_line_ldcc,list-default-common-component th:last-child .divide_line_ldcc{display:none}list-default-common-component .thead_container_ldcc{background-color:#f8f8f8;border-bottom:1px solid #d9d9d9}list-default-common-component .hover_th_ldcc{cursor:pointer}list-default-common-component .hover_th_ldcc:hover{background-color:#efefef}list-default-common-component .focus_orderby{color:red}list-default-common-component .un_focus_orderBy{color:rgba(51,51,51,.2)}list-default-common-component .more-btn{display:inline-block;line-height:initial}list-default-common-component .footer{position:absolute;bottom:0;left:0;right:0;border-top:1px solid #d9d9d9}list-default-common-component .btn-shrink{position:absolute;text-align:center;font-size:24px;border:none;margin-top:-5px;left:0}list-default-common-component .btn-shrink:hover{color:#1890ff}.common_scss_list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.common_scss_list .first_level_article{border:1px solid #d9d9d9;-webkit-border-radius:3px;border-radius:3px}.common_scss_list .first_level_article table{width:100%;border-spacing:0;text-align:left;-webkit-border-radius:3px;border-radius:3px;table-layout:fixed}.common_scss_list .first_level_article thead tr{height:50px}.common_scss_list .first_level_article td,.common_scss_list .first_level_article th{padding-left:20px}.common_scss_list .first_level_article tbody tr{height:43px}.common_scss_list .first_level_article tbody tr td{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border-bottom:1px solid #d9d9d9}.common_scss_list .first_level_article tbody tr .cancel-nowrap{white-space:initial;overflow:initial;text-overflow:initial}.common_scss_list .first_level_article tbody tr .operate-td{overflow:visible}.common_scss_list .first_level_article .more-function{position:absolute;border-style:solid;border-width:1px;-webkit-border-radius:3px;border-radius:3px;right:0;z-index:2;text-align:left}.common_scss_list .first_level_article .more-function li{height:35px;line-height:35px;cursor:pointer;padding:0 20px}.common_scss_list .first_level_article .eo-operate-btn{padding-left:10px;border-left:1px solid #d9d9d9}.common_scss_list .first_level_article .eo-operate-btn:first-child{border-left:none;padding-left:0}.common_scss_list .first_level_article .none_div{background-color:#fff;color:#999;line-height:100px;height:100px;text-align:center}.common_scss_list .first_level_article .hover-tr{cursor:pointer}.common_scss_list .first_level_article .unhover-tr{cursor:default}.common_scss_list .count-span{color:#999;font-weight:initial;font-size:12px}.common_scss_list .eo-tip-container .arrow-li{margin-left:16px}.common_scss_list .eo-tip-container .message-li{margin-left:-50px}.common_scss_list .eo-operate-btn .eo-tip-container .message-li{white-space:pre-line;max-width:170px;min-width:120px}.common_scss_list .eo-operate-btn:hover .eo-tip-container{visibility:visible;margin-top:-70px;margin-left:-8px}.list_default_common_component_has_no_group .fixed-height-list{width:-webkit-calc(100% - 271px);width:-ms-calc(100% - 271px);width:calc(100% - 271px)}.shrink-group-div list-default-common-component .fixed-height-list{width:-webkit-calc(100% - 332px);width:-ms-calc(100% - 332px);width:calc(100% - 332px)}.shrink-div list-default-common-component .fixed-height-list{width:-webkit-calc(100% - 324px);width:-ms-calc(100% - 324px);width:calc(100% - 324px)}.shrink-div .list_default_common_component_has_no_group .fixed-height-list{width:-webkit-calc(100% - 83px);width:-ms-calc(100% - 83px);width:calc(100% - 83px)}.eo_shrink_group_sidebar_container list-default-common-component .fixed-height-list{width:-webkit-calc(100% - 144px);width:-ms-calc(100% - 144px);width:calc(100% - 144px)}select-multistage-common-component .disabled-text-p{color:#999!important;cursor:not-allowed!important;background-color:#fafafa!important}select-multistage-common-component .container-div{width:278px;display:block;position:relative}select-multistage-common-component .text-div{border:1px solid #d9d9d9;background-color:#fff;-webkit-border-radius:3px;border-radius:3px;color:#333;height:32px;line-height:32px;padding:0 10px;cursor:pointer;font-size:12px;-webkit-box-sizing:border-box;box-sizing:border-box}select-multistage-common-component .text-div:hover{border-color:#999;-webkit-transition:all .2s cubic-bezier(.645,.045,.355,1);transition:all .2s cubic-bezier(.645,.045,.355,1)}select-multistage-common-component .text-div:focus{border-color:#089462;-webkit-box-shadow:0 0 0 2px #c8e6c9;box-shadow:0 0 0 2px #c8e6c9}select-multistage-common-component .text-div:disabled{color:#999;cursor:not-allowed;background-color:#fafafa}select-multistage-common-component .select-item-div{width:-webkit-calc(100% - 12px);width:-ms-calc(100% - 12px);width:calc(100% - 12px);display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}select-multistage-common-component .list-container-div{-webkit-border-radius:3px;border-radius:3px;background-color:#fff;border:1px solid #d9d9d9;width:100%;margin-top:5px;font-size:12px;position:absolute;-webkit-box-shadow:0 10px 15px rgba(0,0,0,.12);box-shadow:0 10px 15px rgba(0,0,0,.12);z-index:5}select-multistage-common-component .query-container-child-div{max-height:353px;overflow:auto}select-multistage-common-component .search-p{background-color:#f8f8f8;height:40px;padding:0 10px;line-height:42px}select-multistage-common-component .search-p button,select-multistage-common-component .search-p input[type=text]{border:none;background:0 0;height:40px}select-multistage-common-component .search-p .iconfont{font-size:16px;padding-right:5px}select-multistage-common-component .search-p input[type=text]{width:100%}select-multistage-common-component .search-p input[type=button]{height:28px;line-height:26px;padding:0 10px;margin-top:6px}select-multistage-common-component .common-class-item{cursor:pointer}select-multistage-common-component .common-class-item:hover{background-color:#fafafa}select-multistage-common-component .common-class-item .iconfont{color:#999}select-multistage-common-component .common-class-item,select-multistage-common-component .un-search-response-p{height:35px;line-height:35px;padding:0 10px}cluster-Node-default list-default-common-component .fixed-height-list{height:-webkit-calc(100% - 183px);height:-ms-calc(100% - 183px);height:calc(100% - 183px)}cluster-Node-default .eo-tip-container{margin-left:-14px!important;position:fixed}cluster-Node-Group .common-scss-group{margin-top:65px;height:-webkit-calc(100% - 132px);height:-ms-calc(100% - 132px);height:calc(100% - 132px)}cluster-default list-default-common-component .first-level-article{margin-top:0}cluster-default menu-Default-Common-Component .common_menu_ul .search-form{position:absolute;right:20px;top:10px}cluster-default .menu-title:nth-child(2){padding-bottom:0}cluster-default menu-Default-Common-Component .disabled-operate-has-second-title-placeholder{height:113px}balance-operate .first-level-article{border:1px solid #e5e5e5;background-color:#fff;padding:10px}balance-operate .input_cluster_blo,balance-operate .select_cluster_blo{width:578px}balance-operate input[type=text]:disabled,balance-operate select:disabled,plugin-operate .first-level-article input[type=text]:disabled,plugin-operate .first-level-article select:disabled{background-color:#fafafa;cursor:not-allowed}panel .foot_panel{height:40px;line-height:40px;background-color:#f8f8f8;border-top:1px solid #ddd;position:fixed;bottom:0;width:-webkit-calc(100% - 20px);width:-ms-calc(100% - 20px);width:calc(100% - 20px);left:0;padding-right:20px}panel .first-box{padding-bottom:0;padding-top:30px}panel .basic_data_panel{width:100%}panel .item_panel{width:50%;overflow:hidden}panel list-default-common-component .first-level-article{margin-top:0}panel .icon-bangzhu_o{font-size:50px}panel .time_panel .item_time_panel{background-color:#fff;height:30px;line-height:30px;display:inline-block;text-align:center;padding:0 10px;border:1px solid #ddd}panel .time_panel .item_time_panel:nth-child(n+2){border-left:none}panel .time_panel .item_time_panel:first-child{-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}panel .time_panel .item_time_active_panel{background-color:#00ab6d;color:#fff}panel .time_panel .disable-a{color:#ccc;cursor:not-allowed}panel .time_panel .item_time_panel:last-child{margin-left:0;border-left:none;-webkit-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}panel .panel-ui-div .table-container-div{max-width:1236px}panel .panel-ui-div .eo-tab-menu .item-tab{border-color:transparent;cursor:default}panel .panel-ui-div .item-p{font-size:14px;color:#555;margin:20px 0}panel .panel-ui-div .untop-div{border-top:0}panel .panel-ui-div .default-btn{display:inline-block;height:30px;line-height:30px;border:1px solid #ddd;-webkit-border-radius:3px;border-radius:3px;background-color:#fff;padding:0 10px}gpedit-inside-auth .common-table thead,gpedit-overview .item_gpedit_overview:hover,panel .panel-ui-div .default-btn:hover{background-color:#fafafa}api-default list-default-common-component .fixed-height-list,gpedit-default list-default-common-component .fixed-height-list{height:-webkit-calc(100% - 183px);height:-ms-calc(100% - 183px);height:calc(100% - 183px)}gpedit-default .copy_btn_gd{font-size:12px;padding:2px 3px}gpedit-Group .common-scss-group{margin-top:65px;height:-webkit-calc(100% - 132px);height:-ms-calc(100% - 132px);height:calc(100% - 132px)}.strategy-id-copy-div{position:absolute;right:15px;font-size:14px;line-height:50px;color:#555;z-index:5}.strategy-id-copy-div .copy-a{margin-left:10px;background-color:#fff;-webkit-border-radius:3px;border-radius:3px;border:1px solid #e5e5e5;padding:0 10px;line-height:20px;display:inline-block}.strategy-id-copy-div .copy-a:hover{color:#333}.readonly_strategy_id_copy_gi{border:1px solid #ddd;-webkit-border-radius:3px;border-radius:3px;padding-left:10px;padding-right:10px;position:fixed;background-color:#f0f2f5;top:60px;right:10px;line-height:40px}gpedit-Inside-Api-Plugin .container_giap{margin-top:145px}gpedit-overview .item_gpedit_overview{cursor:pointer}project-Default menu-Default-Common-Component .common_menu_ul .search-form{position:absolute;right:20px;bottom:20px;height:auto}plugin-operate .form_plugin_opr{border:1px solid #e5e5e5;background-color:#fff;font-size:14px;padding:15px;margin-top:10px}plugin-operate .first-level-article{margin:61px 10px 10px}plugin-operate .first-level-article input[type=text]{width:578px}gpedit-inside-auth select,gpedit-inside-plugin-operate select,plugin-operate .first-level-article select{text-indent:0;width:580px}plugin-operate .match-rule-p,plugin-operate .title-p{line-height:50px}plugin-default .icon-jiazai_shuaxin{-webkit-animation:load 1.7s infinite ease;animation:load 1.7s infinite ease;display:inline-block;height:14px;line-height:14px;text-indent:0;margin-left:5px}plugin-default .fun-list-li>div{line-height:30px}plugin-default .fun-list-li{position:absolute;right:230px;bottom:20px}plugin-default .eo-tip-container{margin-left:-14px!important}setting-log .divide_hsl_eoui{border-top:1px solid #ddd;margin:20px 0}setting-log .account-setting-common-scss{margin-top:50px}setting-log button:disabled{cursor:not-allowed!important}setting-log .common-table-div:nth-child(2){margin-top:0}api-operate .home-common-project-list{z-index:0}api-operate .home-common-project-list .first-level-article{margin-left:15px;margin-right:15px;border:1px solid #e5e5e5;background-color:#fff;font-size:14px;padding:10px}api-operate .home-common-project-list .input_common_aop,api-operate .home-common-project-list .select_common_aop,gpedit-inside-auth input[type=text],gpedit-inside-plugin-operate input[type=text]{width:578px}api-operate .home-common-project-list .select_target_protocol_aop{width:100px}api-operate .home-common-project-list .input_target_aop{width:473px}api-Group .common-scss-group{margin-top:65px;height:-webkit-calc(100% - 132px);height:-ms-calc(100% - 132px);height:calc(100% - 132px)}gpedit-inside-auth .first-level-article{border:1px solid #e5e5e5;background-color:#fff;font-size:14px;padding:10px}gpedit-inside-auth .disabled-table td{background-color:#fafafa;cursor:not-allowed}gpedit-inside-auth .title-p{line-height:50px}gpedit-inside-auth input[type=text]:disabled,gpedit-inside-auth select:disabled,gpedit-inside-auth textarea:disabled,gpedit-inside-plugin-operate select:disabled{background-color:#fafafa;cursor:not-allowed}gpedit-inside-auth .common-table{width:100%;border-spacing:0;table-layout:fixed}gpedit-inside-auth .common-table td{font-size:14px;height:40px;line-height:20px;cursor:default;position:relative}gpedit-inside-auth .common-table td .eo-input{border:none;width:100%;-webkit-border-radius:0;border-radius:0;height:40px;display:block}gpedit-inside-auth .common-table td:nth-child(n+2){border-left:1px dashed #e5e5e5}gpedit-inside-auth .common-table td .auto-complete-message{line-height:20px;text-indent:10px;font-size:12px;margin-left:-1px}gpedit-inside-auth .common-table td .disabled-div{background-color:#fafafa;cursor:not-allowed}gpedit-inside-auth .common-table td .item-textarea{border:none;-webkit-border-radius:0;border-radius:0;display:block;position:absolute;text-indent:0;line-height:1.65em;padding:10px;height:100%}gpedit-inside-auth .common-table td .textarea-div{white-space:pre-wrap;height:auto;padding:0 10px;text-indent:0;line-height:1.65em;width:-webkit-calc(100% - 20px);width:-ms-calc(100% - 20px);width:calc(100% - 20px);max-height:200px;min-height:43px}gpedit-inside-auth .common-table .required-td{width:40px;text-align:center;text-indent:0}gpedit-inside-auth .common-table .operation-td{text-indent:0;padding-left:10px;width:100px}gpedit-inside-auth .common-table thead td{text-indent:10px}gpedit-inside-auth .common-table tbody .number-label,gpedit-inside-auth .common-table tbody .radio-input{border:1px solid #e5e5e5;display:inline-block;text-align:center;-webkit-border-radius:3px;border-radius:3px}gpedit-inside-auth .common-table tbody .number-label{background-color:#f2f2f2;color:#9e9e9e;padding:0 5px;height:25px;line-height:27px;font-size:12px}gpedit-inside-auth .common-table tbody .icon-shanchu:hover{background-color:#d32f2f;color:#fff;border:1px solid #c62828}gpedit-inside-auth .common-table tbody .icon-index-magicwand:hover{background-color:#e5e5e5}gpedit-inside-auth .common-table tbody .radio-input{height:23px;line-height:23px;width:23px;font-size:13px;margin-right:4px;cursor:pointer}gpedit-inside-auth .common-table tbody tr td{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;height:40px}gpedit-inside-auth .common-table tbody tr:first-child td{border-top:1px solid #e5e5e5}gpedit-inside-auth .margin-top-60{margin-top:60px}gpedit-inside-api-operate list-default-common-component .fixed-height-list{height:-webkit-calc(100% - 183px);height:-ms-calc(100% - 183px);height:calc(100% - 183px);margin-left:241px;width:-webkit-calc(100% - 755px);width:-ms-calc(100% - 755px);width:calc(100% - 755px)}gpedit-inside-api-operate .common-scss-group{margin-top:65px;height:-webkit-calc(100% - 132px);height:-ms-calc(100% - 132px);height:calc(100% - 132px)}gpedit-inside-api-operate .group-compoment-container .cc-group-container{left:482px}gpedit-inside-api-operate .search_menu_giao .common_menu_ul{margin-left:241px;width:-webkit-calc(100% - 263px);width:-ms-calc(100% - 263px);width:calc(100% - 263px)}gpedit-inside-api-operate .btn-group-div button{height:20px;line-height:22px;padding:0 10px;font-size:12px;margin-right:10px}gpedit-inside-api-operate .btn-group-div button:focus,gpedit-inside-api-operate .btn-group-div button:hover{height:20px;line-height:22px}gpedit-inside-api-operate .btn-group-div button:disabled{background-color:#c3c3c3;cursor:not-allowed;border:none}.shrink-div gpedit-inside-api-operate .group-compoment-container .cc-group-container{left:292px}.shrink-div gpedit-inside-api-operate list-default-common-component .fixed-height-list{width:-webkit-calc(100% - 565px);width:-ms-calc(100% - 565px);width:calc(100% - 565px)}gpedit-Inside-Api-Default .eo-tip-container{position:fixed;margin-left:-14px!important}gpedit-inside-plugin-operate .first-level-article{border:1px solid #e5e5e5;background-color:#fff;font-size:14px;padding:0 15px 5px;margin:66px 15px 15px}gpedit-inside-plugin-operate .match-rule-p,gpedit-inside-plugin-operate .title-p{line-height:50px}
\ No newline at end of file
diff --git a/app/goku-node/main.go b/app/goku-node/main.go
deleted file mode 100644
index 0554b5566d4d216b8d646fd31c00447906b0304a..0000000000000000000000000000000000000000
--- a/app/goku-node/main.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package main
-
-import (
- "encoding/json"
- "flag"
- "fmt"
- endless2 "github.com/eolinker/goku-api-gateway/common/endless"
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "github.com/eolinker/goku-api-gateway/goku-node/cmd"
- "runtime"
-
- node_common "github.com/eolinker/goku-api-gateway/goku-node/node-common"
-
- "github.com/eolinker/goku-api-gateway/common/database"
- "github.com/eolinker/goku-api-gateway/common/general"
- redis_manager "github.com/eolinker/goku-api-gateway/common/redis-manager"
- goku_node "github.com/eolinker/goku-api-gateway/goku-node"
- "github.com/eolinker/goku-api-gateway/server/entity"
-)
-
-var (
- adminHost string
- //adminPort int
- listenPort int
-)
-
-func initConfig(resultInfo map[string]interface{}) *entity.ClusterInfo {
- c := entity.ClusterInfo{}
- clusterConfig, err := json.Marshal(resultInfo["cluster"])
- if err != nil {
- log.Panic(err)
- }
-
- err = json.Unmarshal(clusterConfig, &c)
- if err != nil {
- log.Panic(err)
- }
- return &c
-}
-
-func main() {
-
- runtime.GOMAXPROCS(runtime.NumCPU())
-
- flag.StringVar(&adminHost, "admin", "127.0.0.1:7005", "Please provide a valid host!")
- //flag.IntVar(&adminPort, "P", 7005, "Please provide a valid port")
- flag.IntVar(&listenPort, "port", 6689, "Please provide a valid listen port!")
- isDebug := flag.Bool("debug", false, "")
-
- flag.Parse()
- if *isDebug {
- log.StartDebug()
- }
- //
- node_common.SetAdmin(adminHost)
- node_common.ListenPort = listenPort
-
- success, config := cmd.GetConfig(listenPort)
- if !success {
- log.Fatal(" Fail to get node config!")
- return
- }
-
- node_common.SetClusterName(config.Name)
-
- err := database.InitConnection(&config.DB)
- if err != nil {
- log.Fatal("Fail to Init db:", err)
- return
- }
- goku_node.InitLog()
- log.Debug("gokNode.InitLog")
- r := redis_manager.Create(&config.Redis)
- redis_manager.SetDefault(r)
-
- log.Debug("redis-manager.SetDefault")
- // 其他需要初始化的模块
- _ = general.General()
-
- log.Debug("general.General()")
- goku_node.InitServer()
- go cmd.Heartbeat(listenPort)
- server := goku_node.NewRouter()
-
- err = endless2.ListenAndServe(fmt.Sprintf(":%d", listenPort), server)
- if err != nil {
- log.Fatal(err)
- }
- log.Fatalf("Server on :%d stoped \n", listenPort)
-
-}
diff --git a/app/node/.gitignore b/app/node/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d77a4e0ae9c578c3472a7cdbfa0bbf22f8f1810d
--- /dev/null
+++ b/app/node/.gitignore
@@ -0,0 +1,3 @@
+/work/
+/logs/
+/node
diff --git a/app/node/driver.go b/app/node/driver.go
new file mode 100644
index 0000000000000000000000000000000000000000..88a81bee97c52eb37de396f064d19a65849ceb5d
--- /dev/null
+++ b/app/node/driver.go
@@ -0,0 +1,15 @@
+package main
+
+import (
+
+ "github.com/eolinker/goku-api-gateway/goku-service/driver/consul"
+ "github.com/eolinker/goku-api-gateway/goku-service/driver/eureka"
+ "github.com/eolinker/goku-api-gateway/goku-service/driver/static"
+
+)
+
+func init() {
+ consul.Register()
+ eureka.Register()
+ static.Register()
+}
\ No newline at end of file
diff --git a/app/node/flag.go b/app/node/flag.go
new file mode 100644
index 0000000000000000000000000000000000000000..740d88917f7e56c27ff359ef4120001ba7838017
--- /dev/null
+++ b/app/node/flag.go
@@ -0,0 +1,17 @@
+package main
+
+import "flag"
+
+//ParseFlag 获取命令行参数
+func ParseFlag() (port int, admin string, staticConfigFile string, isDebug bool) {
+ adminP := flag.String("admin", "", "Please provide a valid host!")
+ portP := flag.Int("port", 0, "Please provide a valid listen port!")
+ staticConfigFileP := flag.String("config", "", "Please provide a config file")
+
+ isDebugP := flag.Bool("debug", false, "")
+
+ flag.Parse()
+
+ return *portP, *adminP, *staticConfigFileP, *isDebugP
+
+}
diff --git a/app/node/main.go b/app/node/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..d48b9d070982e00974e775944327ba04bd6c2948
--- /dev/null
+++ b/app/node/main.go
@@ -0,0 +1,66 @@
+package main
+
+import (
+ "flag"
+ "github.com/eolinker/goku-api-gateway/config"
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+ console2 "github.com/eolinker/goku-api-gateway/node/console"
+ "github.com/eolinker/goku-api-gateway/node/gateway"
+ "github.com/eolinker/goku-api-gateway/node/router/httprouter"
+ "github.com/eolinker/goku-api-gateway/node/server"
+ "runtime"
+)
+
+func main() {
+ runtime.GOMAXPROCS(runtime.NumCPU())
+
+ port, admin, staticConfigFile, isDebug := ParseFlag()
+
+ if isDebug {
+ log.StartDebug()
+ }
+
+ if port == 0{
+ flag.Usage()
+
+ return
+ }
+
+ if admin != "" {
+ // 从控制台启动,
+ console := console2.NewConsole(port, admin)
+ ser := server.NewServer(port)
+ ser.SetConsole(console)
+ log.Fatal(ser.Server())
+
+ } else if staticConfigFile != "" {
+
+ // 从静态文件启动
+ c, err := config.ReadConfig(staticConfigFile)
+ if err != nil {
+ log.Panic("read config from :", staticConfigFile, "\t", err)
+ }
+
+ server.SetLog(c.Log)
+ server.SetAccessLog(c.AccessLog)
+
+
+ r, err := gateway.Parse(c, httprouter.Factory())
+ if err != nil {
+ log.Panic("parse config error:", err)
+ }
+
+
+
+ ser := server.NewServer(port)
+ e := ser.SetRouter(r)
+ if e != nil {
+ log.Panic("init router error:", e)
+ }
+ log.Fatal(ser.Server())
+ } else {
+ //
+ flag.Usage()
+ return
+ }
+}
diff --git a/build/cmd/build-node.sh b/build/cmd/build-node.sh
index 48829195b1f026ef3084db425357deb3059f1530..60c65e41bfbd990a4fc02877fd4283115779fe53 100755
--- a/build/cmd/build-node.sh
+++ b/build/cmd/build-node.sh
@@ -17,12 +17,12 @@ then
fi
-buildApp goku-node $VERSION
+buildApp node $VERSION
-OUTPATH="${BasePath}/out/goku-node-${VERSION}"
+OUTPATH="${BasePath}/out/node-${VERSION}"
mkdir ${OUTPATH}/plugin
-cp -a ${BasePath}/build/goku-node/resources/* ${OUTPATH}/
+cp -a ${BasePath}/build/node/resources/* ${OUTPATH}/
if [ -d "${BasePath}/out/plugins" ];then
cp -a ${BasePath}/out/plugins/* ${OUTPATH}/plugin/
fi
diff --git a/build/cmd/package-node.sh b/build/cmd/package-node.sh
index 6a7db33bca02132bd50a21fd4a34e16ea17c3677..8a319850a6be300c33f2130be611a9f43dadf6db 100755
--- a/build/cmd/package-node.sh
+++ b/build/cmd/package-node.sh
@@ -5,7 +5,7 @@ cd ${BasePath}/
VERSION=$(genVersion $1)
-folder="${BasePath}/out/goku-node-${VERSION}"
+folder="${BasePath}/out/node-${VERSION}"
if [[ ! -d "$folder" ]]
then
@@ -15,6 +15,6 @@ then
exit 1
fi
fi
-packageApp goku-node $VERSION
+packageApp node $VERSION
cd ${ORGPATH}
diff --git a/build/console/resources/db/sqlite3/.gitignore b/build/console/resources/db/sqlite3/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/build/console/resources/goku.conf.tpl b/build/console/resources/goku.conf.tpl
index 89c03ea5f180b83f9e5ea6b87968521d8591e9e3..3f3a4fff4ca845e2721f982b7d4c536c1f4d3fb3 100644
--- a/build/console/resources/goku.conf.tpl
+++ b/build/console/resources/goku.conf.tpl
@@ -1,7 +1,2 @@
listen_port: 7000
admin_bind: 127.0.0.1:7005
-db_host: 127.0.0.1
-db_port: 3306
-db_name: goku_ee
-db_user: root
-db_password: root
\ No newline at end of file
diff --git a/build/console/resources/html/currentAlert.html b/build/console/resources/html/currentAlert.html
deleted file mode 100644
index c3d60e8cfe8fdb362fdad5a7b2b01687de369298..0000000000000000000000000000000000000000
--- a/build/console/resources/html/currentAlert.html
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- GoKu Gateway EE
-
-
-
- GoKu告警:$requestURL接口在$alertPeriod分钟内转发失败$alertCount次
-
-
-
-
- GoKu接口网关于 $alertTime 监控到
- $requestURL 接口在 $alertPeriod 分钟内转发失败达到 $alertCount 次,详细告警内容请于
- $alertLogPath 文件夹查看。
-
-
-
-
- 接口基本信息
-
-
-
-
- 接口名称:$apiName
- apiID:$apiID
- 请求路径:$requestURL
- 转发路径:$targetServer
- 映射路径:$proxyURL
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build/console/resources/run.sh b/build/console/resources/run.sh
index f56cfaa5a6b19c556233661e4fc7e5d390d80e71..4f924effcc3dd0f6b70330c90d9e33d8f55f9252 100644
--- a/build/console/resources/run.sh
+++ b/build/console/resources/run.sh
@@ -70,16 +70,14 @@ stop() {
kill $pid >/dev/null 2>&1
if [[ $? != 0 ]];then
echo "$PROG stop error"
-
+ exit 1
fi
rm -f "$WORK_PATH/$PROG.pid"
echo "$PROG stopped"
- else
- echo "Error! $PROG not started!" 1>&2
fi
else
## Program is not running, exit with error.
- echo "Error! $PROG not started!" 1>&2
+ echo "note! $PROG not started!" 1>&2
fi
}
diff --git a/build/console/resources/sql/goku_ce.sql b/build/console/resources/sql/goku_ce.sql
index 44bf7bdd02a8298a85f93d7e4e713f2d5afc71c6..42d76e3b462a5cb3be68efafeb74fd04064b11f9 100644
--- a/build/console/resources/sql/goku_ce.sql
+++ b/build/console/resources/sql/goku_ce.sql
@@ -1,591 +1,456 @@
-USE goku_ce;
-SET FOREIGN_KEY_CHECKS=0;
+PRAGMA foreign_keys = false;
-- ----------------------------
-- Table structure for goku_admin
-- ----------------------------
-DROP TABLE IF EXISTS `goku_admin`;
-CREATE TABLE `goku_admin` (
- `userID` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `loginCall` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
- `loginPassword` varchar(255) NOT NULL,
- `userType` tinyint(4) NOT NULL DEFAULT '0',
- `groupID` int(11) NOT NULL DEFAULT '0',
- `remark` varchar(255) DEFAULT NULL,
- `permissions` text,
- PRIMARY KEY (`userID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_admin
--- ----------------------------
+DROP TABLE IF EXISTS "goku_admin";
+CREATE TABLE "goku_admin" (
+ "userID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "loginCall" text(255) NOT NULL,
+ "loginPassword" text(255) NOT NULL,
+ "userType" integer(4) NOT NULL DEFAULT 0,
+ "groupID" integer(11) NOT NULL DEFAULT 0,
+ "remark" text(255),
+ "permissions" text
+);
-- ----------------------------
-- Table structure for goku_balance
-- ----------------------------
-DROP TABLE IF EXISTS `goku_balance`;
-CREATE TABLE `goku_balance` (
- `balanceID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `balanceName` varchar(255) NOT NULL DEFAULT '',
- `serviceName` varchar(255) NOT NULL DEFAULT '',
- `balanceConfig` text,
- `createTime` timestamp NULL DEFAULT NULL,
- `updateTime` timestamp NULL DEFAULT NULL,
- `balanceDesc` varchar(255) DEFAULT NULL,
- `defaultConfig` text NOT NULL,
- `clusterConfig` text NOT NULL,
- `appName` varchar(255) NOT NULL DEFAULT '',
- `static` text,
- `staticCluster` text,
- PRIMARY KEY (`balanceID`),
- UNIQUE KEY `balanceName` (`balanceName`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_balance
--- ----------------------------
+DROP TABLE IF EXISTS "goku_balance";
+CREATE TABLE "goku_balance" (
+ "balanceID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "balanceName" text(255) NOT NULL,
+ "serviceName" text(255) NOT NULL,
+ "balanceConfig" text,
+ "createTime" text,
+ "updateTime" text,
+ "balanceDesc" text(255),
+ "defaultConfig" text NOT NULL,
+ "clusterConfig" text NOT NULL DEFAULT '',
+ "appName" text(255) NOT NULL DEFAULT '',
+ "static" text,
+ "staticCluster" text
+);
-- ----------------------------
-- Table structure for goku_cluster
-- ----------------------------
-DROP TABLE IF EXISTS `goku_cluster`;
-CREATE TABLE `goku_cluster` (
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(20) NOT NULL DEFAULT '',
- `title` varchar(50) NOT NULL DEFAULT '',
- `note` varchar(255) DEFAULT NULL,
- `db` text,
- `redis` text,
- PRIMARY KEY (`id`),
- UNIQUE KEY `name` (`name`),
- UNIQUE KEY `titel` (`title`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
--- ----------------------------
--- Records of goku_cluster
--- ----------------------------
+DROP TABLE IF EXISTS "goku_cluster";
+CREATE TABLE "goku_cluster" (
+ "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "name" text(20) NOT NULL,
+ "title" text(50) NOT NULL,
+ "note" text(255),
+ "db" text,
+ "redis" text
+);
-- ----------------------------
-- Table structure for goku_config_log
-- ----------------------------
-DROP TABLE IF EXISTS `goku_config_log`;
-CREATE TABLE `goku_config_log` (
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(20) NOT NULL DEFAULT '',
- `enable` int(11) NOT NULL DEFAULT '0',
- `dir` varchar(255) NOT NULL DEFAULT 'logs/',
- `file` varchar(255) NOT NULL DEFAULT '',
- `period` varchar(10) NOT NULL DEFAULT '',
- `level` varchar(10) NOT NULL DEFAULT '',
- `fields` text NOT NULL,
- `expire` int(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`id`),
- UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
--- ----------------------------
--- Records of goku_config_log
--- ----------------------------
+DROP TABLE IF EXISTS "goku_config_log";
+CREATE TABLE "goku_config_log" (
+ "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "name" text(20) NOT NULL,
+ "enable" integer(11) NOT NULL DEFAULT 1,
+ "dir" text(255) NOT NULL,
+ "file" text(255) NOT NULL,
+ "period" text(10) NOT NULL,
+ "level" text(10) NOT NULL,
+ "fields" text NOT NULL,
+ "expire" integer(11) NOT NULL DEFAULT 3
+);
-- ----------------------------
-- Table structure for goku_conn_plugin_api
-- ----------------------------
-DROP TABLE IF EXISTS `goku_conn_plugin_api`;
-CREATE TABLE `goku_conn_plugin_api` (
- `connID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `apiID` int(11) NOT NULL,
- `pluginName` varchar(255) NOT NULL,
- `pluginConfig` text,
- `strategyID` varchar(255) NOT NULL,
- `pluginInfo` text,
- `createTime` timestamp NULL DEFAULT NULL,
- `updateTime` timestamp NULL DEFAULT NULL,
- `pluginStatus` tinyint(4) DEFAULT NULL,
- `updateTag` varchar(32) DEFAULT NULL COMMENT '更新标识位',
- `updaterID` int(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`connID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_conn_plugin_api
--- ----------------------------
+DROP TABLE IF EXISTS "goku_conn_plugin_api";
+CREATE TABLE "goku_conn_plugin_api" (
+ "connID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "apiID" integer(11) NOT NULL,
+ "pluginName" text(255) NOT NULL,
+ "pluginConfig" text,
+ "strategyID" text(255) NOT NULL,
+ "pluginInfo" text,
+ "createTime" text,
+ "updateTime" text,
+ "pluginStatus" integer(4),
+ "updateTag" text(32),
+ "updaterID" integer(11) NOT NULL DEFAULT 0
+);
-- ----------------------------
-- Table structure for goku_conn_plugin_strategy
-- ----------------------------
-DROP TABLE IF EXISTS `goku_conn_plugin_strategy`;
-CREATE TABLE `goku_conn_plugin_strategy` (
- `connID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `strategyID` varchar(255) NOT NULL,
- `pluginName` varchar(255) NOT NULL,
- `pluginConfig` text,
- `pluginInfo` text,
- `createTime` timestamp NULL DEFAULT NULL,
- `updateTime` timestamp NULL DEFAULT NULL,
- `pluginStatus` tinyint(4) DEFAULT NULL,
- `updateTag` varchar(32) DEFAULT NULL COMMENT '更新标识位',
- `updaterID` int(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`connID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_conn_plugin_strategy
--- ----------------------------
+DROP TABLE IF EXISTS "goku_conn_plugin_strategy";
+CREATE TABLE "goku_conn_plugin_strategy" (
+ "connID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "strategyID" text(255) NOT NULL,
+ "pluginName" text(255) NOT NULL,
+ "pluginConfig" text,
+ "pluginInfo" text,
+ "createTime" text,
+ "updateTime" text,
+ "pluginStatus" integer(4),
+ "updateTag" text(32),
+ "updaterID" integer(11) NOT NULL DEFAULT 0
+);
-- ----------------------------
-- Table structure for goku_conn_strategy_api
-- ----------------------------
-DROP TABLE IF EXISTS `goku_conn_strategy_api`;
-CREATE TABLE `goku_conn_strategy_api` (
- `connID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `strategyID` varchar(255) NOT NULL,
- `apiID` int(11) NOT NULL,
- `apiMonitorStatus` int(11) NOT NULL DEFAULT '1',
- `strategyMonitorStatus` int(11) NOT NULL DEFAULT '1',
- `target` varchar(255) DEFAULT NULL,
- `updateTime` datetime DEFAULT NULL,
- PRIMARY KEY (`connID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_conn_strategy_api
--- ----------------------------
+DROP TABLE IF EXISTS "goku_conn_strategy_api";
+CREATE TABLE "goku_conn_strategy_api" (
+ "connID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "strategyID" text(255) NOT NULL,
+ "apiID" integer(11) NOT NULL,
+ "apiMonitorStatus" integer(11) NOT NULL DEFAULT 0,
+ "strategyMonitorStatus" integer(11) NOT NULL DEFAULT 0,
+ "target" text(255),
+ "updateTime" text
+);
-- ----------------------------
-- Table structure for goku_gateway
-- ----------------------------
-DROP TABLE IF EXISTS `goku_gateway`;
-CREATE TABLE `goku_gateway` (
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `successCode` varchar(255) NOT NULL,
- `nodeUpdatePeriod` int(11) NOT NULL,
- `monitorUpdatePeriod` int(11) NOT NULL,
- `alertStatus` tinyint(4) NOT NULL DEFAULT '0',
- `sender` varchar(255) DEFAULT NULL,
- `senderPassword` varchar(255) DEFAULT NULL,
- `smtpAddress` varchar(255) DEFAULT NULL,
- `smtpPort` int(11) NOT NULL DEFAULT '25',
- `smtpProtocol` tinyint(4) NOT NULL DEFAULT '0',
- `monitorTimeout` tinyint(4) NOT NULL DEFAULT '5',
- `apiAlertInfo` text,
- `nodeAlertInfo` text,
- `redisAlertInfo` text,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_gateway
--- ----------------------------
-INSERT INTO `goku_gateway` VALUES ('1', '200', '5', '30', '0', null, null, null, '25', '0', '5', '{\"alertAddr\":\"\",\"alertPeriodType\":0,\"logPath\":\"./log/apiAlert\",\"receiverList\":\"\"}', '{\"alertAddr\":\"\",\"logPath\":\"./log/nodeAlert\",\"receiverList\":\"\"}', '{\"alertAddr\":\"\",\"logPath\":\"./log/redisAlert\",\"receiverList\":\"\"}');
+DROP TABLE IF EXISTS "goku_gateway";
+CREATE TABLE "goku_gateway" (
+ "id" integer(11) NOT NULL,
+ "successCode" text(255) NOT NULL,
+ "nodeUpdatePeriod" integer(11) NOT NULL,
+ "monitorUpdatePeriod" integer(11) NOT NULL,
+ "alertStatus" integer(4) NOT NULL,
+ "alertPeriodType" integer(4) NOT NULL,
+ "alertAddress" text(255),
+ "alertLogPath" text(255),
+ "sender" text(255),
+ "senderPassword" text(255),
+ "smtpAddress" text(255),
+ "smtpPort" integer(11) NOT NULL,
+ "smtpProtocol" integer(4) NOT NULL,
+ "receiverList" text(255),
+ "monitorTimeout" integer(4) NOT NULL,
+ "apiAlertInfo" text,
+ "nodeAlertInfo" text,
+ "redisAlertInfo" text,
+ "versionID" INTEGER NOT NULL DEFAULT 0,
+ PRIMARY KEY ("id")
+);
+
+INSERT INTO "goku_gateway" VALUES (1, 200, 1, 30, 0, 0, NULL, NULL, NULL, NULL, NULL, 25, 0, NULL, 0, NULL, NULL, NULL, 0);
-- ----------------------------
-- Table structure for goku_gateway_alert
-- ----------------------------
-DROP TABLE IF EXISTS `goku_gateway_alert`;
-CREATE TABLE `goku_gateway_alert` (
- `alertID` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `requestURL` varchar(255) NOT NULL,
- `targetServer` varchar(255) NOT NULL,
- `alertPeriodType` tinyint(4) NOT NULL,
- `alertCount` int(11) NOT NULL,
- `updateTime` timestamp NULL DEFAULT NULL,
- `targetURL` varchar(255) NOT NULL,
- `clusterName` varchar(255) DEFAULT NULL,
- `nodeIP` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`alertID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_gateway_alert
--- ----------------------------
+DROP TABLE IF EXISTS "goku_gateway_alert";
+CREATE TABLE "goku_gateway_alert" (
+ "alertID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "requestURL" text(255) NOT NULL,
+ "targetServer" text(255) NOT NULL,
+ "alertPeriodType" integer(4) NOT NULL,
+ "alertCount" integer(11) NOT NULL,
+ "updateTime" text,
+ "targetURL" text(255) NOT NULL,
+ "clusterName" text(255),
+ "nodeIP" text(255)
+);
-- ----------------------------
-- Table structure for goku_gateway_api
-- ----------------------------
-DROP TABLE IF EXISTS `goku_gateway_api`;
-CREATE TABLE `goku_gateway_api` (
- `apiID` int(11) NOT NULL AUTO_INCREMENT,
- `groupID` int(11) NOT NULL,
- `projectID` int(11) NOT NULL,
- `requestURL` varchar(255) NOT NULL,
- `apiName` varchar(255) NOT NULL,
- `requestMethod` varchar(255) NOT NULL,
- `targetServer` varchar(255) DEFAULT NULL,
- `targetURL` varchar(255) DEFAULT NULL,
- `targetMethod` varchar(255) DEFAULT NULL,
- `isFollow` varchar(32) NOT NULL,
- `stripPrefix` varchar(32) DEFAULT NULL,
- `timeout` int(11) DEFAULT NULL,
- `retryCount` int(11) DEFAULT NULL,
- `createTime` timestamp NULL DEFAULT NULL,
- `updateTime` timestamp NULL DEFAULT NULL,
- `alertValve` int(11) NOT NULL DEFAULT '0',
- `monitorStatus` int(11) NOT NULL DEFAULT '0',
- `managerID` int(11) NOT NULL DEFAULT '0',
- `lastUpdateUserID` int(11) NOT NULL DEFAULT '0',
- `createUserID` int(11) NOT NULL,
- `balanceName` varchar(255) DEFAULT NULL,
- `protocol` varchar(20) DEFAULT NULL,
- `stripSlash` varchar(32) NOT NULL DEFAULT '1',
- PRIMARY KEY (`apiID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_gateway_api
--- ----------------------------
+DROP TABLE IF EXISTS "goku_gateway_api";
+CREATE TABLE "goku_gateway_api" (
+ "apiID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "groupID" integer(11) NOT NULL,
+ "projectID" integer(11) NOT NULL,
+ "requestURL" text(255) NOT NULL,
+ "apiName" text(255) NOT NULL,
+ "requestMethod" text(255) NOT NULL,
+ "targetServer" text(255),
+ "targetURL" text(255),
+ "targetMethod" text(255),
+ "isFollow" text(32) NOT NULL,
+ "stripPrefix" text(32),
+ "timeout" integer(11),
+ "retryCount" integer(11),
+ "createTime" text,
+ "updateTime" text,
+ "alertValve" integer(11) NOT NULL DEFAULT 0,
+ "monitorStatus" integer(11) NOT NULL DEFAULT 1,
+ "managerID" integer(11) NOT NULL,
+ "lastUpdateUserID" integer(11) NOT NULL,
+ "createUserID" integer(11) NOT NULL,
+ "balanceName" text(255),
+ "protocol" text(20),
+ "stripSlash" text(32),
+ "apiType" integer NOT NULL DEFAULT 0,
+ "responseDataType" text NOT NULL DEFAULT origin,
+ "linkApis" TEXT,
+ "staticResponse" TEXT
+);
-- ----------------------------
-- Table structure for goku_gateway_api_group
-- ----------------------------
-DROP TABLE IF EXISTS `goku_gateway_api_group`;
-CREATE TABLE `goku_gateway_api_group` (
- `groupID` int(11) NOT NULL AUTO_INCREMENT,
- `projectID` int(11) NOT NULL,
- `groupName` varchar(255) NOT NULL,
- `groupPath` varchar(255) DEFAULT NULL,
- `groupDepth` tinyint(4) NOT NULL DEFAULT '1',
- `parentGroupID` int(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`groupID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_gateway_api_group
--- ----------------------------
+DROP TABLE IF EXISTS "goku_gateway_api_group";
+CREATE TABLE "goku_gateway_api_group" (
+ "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "projectID" integer(11) NOT NULL,
+ "groupName" text(255) NOT NULL,
+ "groupPath" text(255),
+ "groupDepth" text(255),
+ "parentGroupID" integer(11) NOT NULL DEFAULT 0
+);
-- ----------------------------
-- Table structure for goku_gateway_permission_group
-- ----------------------------
-DROP TABLE IF EXISTS `goku_gateway_permission_group`;
-CREATE TABLE `goku_gateway_permission_group` (
- `groupID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `groupName` varchar(255) NOT NULL,
- `permissions` text,
- PRIMARY KEY (`groupID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_gateway_permission_group
--- ----------------------------
+DROP TABLE IF EXISTS "goku_gateway_permission_group";
+CREATE TABLE "goku_gateway_permission_group" (
+ "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "groupName" text(255) NOT NULL,
+ "permissions" text
+);
-- ----------------------------
-- Table structure for goku_gateway_project
-- ----------------------------
-DROP TABLE IF EXISTS `goku_gateway_project`;
-CREATE TABLE `goku_gateway_project` (
- `projectID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `projectName` varchar(255) NOT NULL,
- `createTime` timestamp NULL DEFAULT NULL,
- `updateTime` timestamp NULL DEFAULT NULL,
- PRIMARY KEY (`projectID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_gateway_project
--- ----------------------------
+DROP TABLE IF EXISTS "goku_gateway_project";
+CREATE TABLE "goku_gateway_project" (
+ "projectID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "projectName" text(255) NOT NULL,
+ "createTime" text,
+ "updateTime" text
+);
-- ----------------------------
-- Table structure for goku_gateway_strategy
-- ----------------------------
-DROP TABLE IF EXISTS `goku_gateway_strategy`;
-CREATE TABLE `goku_gateway_strategy` (
- `strategyID` varchar(32) NOT NULL,
- `strategyName` varchar(255) NOT NULL,
- `updateTime` timestamp NULL DEFAULT NULL,
- `createTime` timestamp NULL DEFAULT NULL,
- `auth` varchar(255) NOT NULL DEFAULT '0',
- `groupID` int(11) NOT NULL DEFAULT '1',
- `monitorStatus` int(4) NOT NULL DEFAULT '0',
- `enableStatus` int(11) NOT NULL DEFAULT '1',
- `strategyType` int(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`strategyID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+DROP TABLE IF EXISTS "goku_gateway_strategy";
+CREATE TABLE "goku_gateway_strategy" (
+ "strategyID" text(32) NOT NULL,
+ "strategyName" text(255) NOT NULL,
+ "updateTime" text,
+ "createTime" text,
+ "auth" text(255),
+ "groupID" integer(11) NOT NULL DEFAULT 0,
+ "monitorStatus" integer(4) NOT NULL DEFAULT 0,
+ "enableStatus" integer(11) NOT NULL DEFAULT 0,
+ "strategyType" integer(11) NOT NULL DEFAULT 0,
+ PRIMARY KEY ("strategyID")
+);
-- ----------------------------
--- Records of goku_gateway_strategy
+-- Records of "goku_gateway_strategy"
-- ----------------------------
-INSERT INTO `goku_gateway_strategy` VALUES ('tqvka3', '开放策略', '2019-02-20 09:59:18', '2019-02-20 09:59:21', '0', '1', '0', '1', '1');
+INSERT INTO "goku_gateway_strategy" VALUES ('RGAtKBd', '开放策略', '2019-10-17 00:00:00', '2019-10-17 00:00:00', NULL, 0, 0, 0, 1);
-- ----------------------------
-- Table structure for goku_gateway_strategy_group
-- ----------------------------
-DROP TABLE IF EXISTS `goku_gateway_strategy_group`;
-CREATE TABLE `goku_gateway_strategy_group` (
- `groupID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `groupName` varchar(255) NOT NULL,
- `groupType` int(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`groupID`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_gateway_strategy_group
--- ----------------------------
-INSERT INTO `goku_gateway_strategy_group` VALUES ('1', '开放策略', '1');
+DROP TABLE IF EXISTS "goku_gateway_strategy_group";
+CREATE TABLE "goku_gateway_strategy_group" (
+ "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "groupName" text(255) NOT NULL,
+ "groupType" integer(11) NOT NULL DEFAULT 0
+);
-- ----------------------------
--- Table structure for goku_message
+-- Records of "goku_gateway_strategy_group"
-- ----------------------------
-DROP TABLE IF EXISTS `goku_message`;
-CREATE TABLE `goku_message` (
- `msgID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `updateTime` timestamp NULL DEFAULT NULL,
- `msg` varchar(255) DEFAULT NULL,
- `msgType` tinyint(4) NOT NULL DEFAULT '0',
- PRIMARY KEY (`msgID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+INSERT INTO "goku_gateway_strategy_group" VALUES (1, '开放分组', 1);
-- ----------------------------
--- Records of goku_message
+-- Table structure for goku_gateway_version_config
-- ----------------------------
+DROP TABLE IF EXISTS "goku_gateway_version_config";
+CREATE TABLE "goku_gateway_version_config" (
+ "versionID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "name" TEXT NOT NULL,
+ "version" TEXT,
+ "remark" TEXT,
+ "createTime" TEXT,
+ "updateTime" TEXT,
+ "publishTime" TEXT,
+ "config" TEXT,
+ "balanceConfig" TEXT,
+ "discoverConfig" TEXT
+);
-- ----------------------------
-- Table structure for goku_monitor_cluster
-- ----------------------------
-DROP TABLE IF EXISTS `goku_monitor_cluster`;
-CREATE TABLE `goku_monitor_cluster` (
- `recordID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `strategyID` varchar(20) NOT NULL,
- `apiID` int(11) NOT NULL,
- `clusterID` int(11) NOT NULL,
- `hour` int(11) NOT NULL,
- `gatewayRequestCount` int(11) NOT NULL DEFAULT '0',
- `gatewaySuccessCount` int(11) NOT NULL DEFAULT '0',
- `gatewayStatus2xxCount` int(11) NOT NULL DEFAULT '0',
- `gatewayStatus4xxCount` int(11) NOT NULL DEFAULT '0',
- `gatewayStatus5xxCount` int(11) NOT NULL DEFAULT '0',
- `proxyRequestCount` int(11) NOT NULL DEFAULT '0',
- `proxySuccessCount` int(11) NOT NULL DEFAULT '0',
- `proxyStatus2xxCount` int(11) NOT NULL DEFAULT '0',
- `proxyStatus4xxCount` int(11) NOT NULL DEFAULT '0',
- `proxyStatus5xxCount` int(11) NOT NULL DEFAULT '0',
- `proxyTimeoutCount` int(11) NOT NULL DEFAULT '0',
- `updateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`recordID`),
- UNIQUE KEY `key` (`strategyID`,`apiID`,`clusterID`,`hour`),
- KEY `strategyID_2` (`strategyID`),
- KEY `apiID` (`apiID`),
- KEY `clusterID` (`clusterID`),
- KEY `hour` (`hour`),
- KEY `strategy_api` (`strategyID`,`apiID`,`clusterID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_monitor_cluster
--- ----------------------------
+DROP TABLE IF EXISTS "goku_monitor_cluster";
+CREATE TABLE "goku_monitor_cluster" (
+ "recordID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "strategyID" text(20) NOT NULL,
+ "apiID" integer(11) NOT NULL,
+ "clusterID" integer(11) NOT NULL,
+ "hour" integer(11) NOT NULL,
+ "gatewayRequestCount" integer(11) NOT NULL,
+ "gatewaySuccessCount" integer(11) NOT NULL,
+ "gatewayStatus2xxCount" integer(11) NOT NULL,
+ "gatewayStatus4xxCount" integer(11) NOT NULL,
+ "gatewayStatus5xxCount" integer(11) NOT NULL,
+ "proxyRequestCount" integer(11) NOT NULL,
+ "proxySuccessCount" integer(11) NOT NULL,
+ "proxyStatus2xxCount" integer(11) NOT NULL,
+ "proxyStatus4xxCount" integer(11) NOT NULL,
+ "proxyStatus5xxCount" integer(11) NOT NULL,
+ "proxyTimeoutCount" integer(11) NOT NULL,
+ "updateTime" text NOT NULL
+);
-- ----------------------------
-- Table structure for goku_node_group
-- ----------------------------
-DROP TABLE IF EXISTS `goku_node_group`;
-CREATE TABLE `goku_node_group` (
- `groupID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `groupName` varchar(255) NOT NULL DEFAULT '',
- `groupType` tinyint(4) NOT NULL DEFAULT '0',
- `clusterID` int(11) NOT NULL,
- PRIMARY KEY (`groupID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_node_group
--- ----------------------------
+DROP TABLE IF EXISTS "goku_node_group";
+CREATE TABLE "goku_node_group" (
+ "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "groupName" text(255) NOT NULL,
+ "groupType" integer(4) NOT NULL,
+ "clusterID" integer(11) NOT NULL
+);
-- ----------------------------
-- Table structure for goku_node_info
-- ----------------------------
-DROP TABLE IF EXISTS `goku_node_info`;
-CREATE TABLE `goku_node_info` (
- `nodeID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `nodeIP` varchar(255) NOT NULL,
- `updateStatus` tinyint(4) NOT NULL DEFAULT '0',
- `createTime` timestamp NULL DEFAULT NULL,
- `updateTime` timestamp NULL DEFAULT NULL,
- `groupID` int(11) NOT NULL,
- `nodeName` varchar(255) NOT NULL,
- `nodePort` varchar(255) DEFAULT NULL,
- `nodeStatus` varchar(255) DEFAULT NULL,
- `version` varchar(255) DEFAULT NULL,
- `sshPort` varchar(255) NOT NULL DEFAULT '22',
- `userName` varchar(255) DEFAULT NULL,
- `password` varchar(255) DEFAULT NULL,
- `gatewayPath` varchar(255) DEFAULT NULL,
- `key` text,
- `authMethod` tinyint(4) NOT NULL DEFAULT '0',
- `clusterID` int(11) NOT NULL,
- PRIMARY KEY (`nodeID`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
--- ----------------------------
--- Records of goku_node_info
--- ----------------------------
+DROP TABLE IF EXISTS "goku_node_info";
+CREATE TABLE "goku_node_info" (
+ "nodeID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "nodeIP" text(255) NOT NULL,
+ "updateStatus" integer(4) NOT NULL DEFAULT 0,
+ "createTime" text,
+ "updateTime" text,
+ "groupID" integer(11) NOT NULL DEFAULT 0,
+ "nodeName" text(255) NOT NULL,
+ "nodePort" text(255),
+ "nodeStatus" integer(11) NOT NULL,
+ "version" text(255),
+ "sshPort" text(255) DEFAULT 22,
+ "userName" text(255),
+ "password" text(255),
+ "gatewayPath" text(255),
+ "key" text,
+ "authMethod" integer(4) NOT NULL DEFAULT 0,
+ "clusterID" integer(11) NOT NULL DEFAULT 0
+);
-- ----------------------------
-- Table structure for goku_plugin
-- ----------------------------
-DROP TABLE IF EXISTS `goku_plugin`;
-CREATE TABLE `goku_plugin` (
- `pluginID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `pluginName` varchar(255) NOT NULL,
- `chineseName` varchar(255) DEFAULT NULL,
- `pluginStatus` tinyint(4) NOT NULL DEFAULT '0',
- `pluginPriority` int(4) NOT NULL DEFAULT '0',
- `pluginConfig` text,
- `pluginInfo` text,
- `isStop` tinyint(4) NOT NULL DEFAULT '0',
- `pluginType` tinyint(4) NOT NULL DEFAULT '0',
- `official` varchar(255) NOT NULL,
- `pluginDesc` varchar(255) DEFAULT NULL,
- `version` varchar(255) NOT NULL,
- `isCheck` tinyint(4) NOT NULL DEFAULT '0',
- PRIMARY KEY (`pluginID`)
-) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4;
+DROP TABLE IF EXISTS "goku_plugin";
+CREATE TABLE "goku_plugin" (
+ "pluginID" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "pluginName" text(255) NOT NULL,
+ "chineseName" text(255),
+ "pluginStatus" integer(4) NOT NULL,
+ "pluginPriority" integer(4) NOT NULL,
+ "pluginConfig" text,
+ "pluginInfo" text,
+ "isStop" integer(4) NOT NULL,
+ "pluginType" integer(4) NOT NULL,
+ "official" text(255) NOT NULL,
+ "pluginDesc" text(255),
+ "version" text(255) NOT NULL,
+ "isCheck" integer(4) NOT NULL
+);
--- ----------------------------
--- Table structure for goku_redis_config
--- ----------------------------
-DROP TABLE IF EXISTS `goku_redis_config`;
-CREATE TABLE `goku_redis_config` (
- `id` int(11) unsigned NOT NULL,
- `cluster_id` int(11) NOT NULL DEFAULT '0',
- `name` varchar(20) NOT NULL DEFAULT '',
- `mod` varchar(10) NOT NULL DEFAULT '',
- `addrs` text NOT NULL,
- `password` varchar(255) NOT NULL DEFAULT '',
- PRIMARY KEY (`id`),
- UNIQUE KEY `cluster_id` (`cluster_id`,`name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
--- Records of goku_redis_config
--- ----------------------------
-
--- ----------------------------
--- Table structure for goku_redis_info
+-- Table structure for goku_service_config
-- ----------------------------
-DROP TABLE IF EXISTS `goku_redis_info`;
-CREATE TABLE `goku_redis_info` (
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `server` varchar(20) NOT NULL COMMENT 'ip:port',
- `info` text NOT NULL COMMENT 'info,json',
- `datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`),
- KEY `server` (`server`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+DROP TABLE IF EXISTS "goku_service_config";
+CREATE TABLE "goku_service_config" (
+ "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "name" text(255) NOT NULL,
+ "default" integer(4),
+ "driver" text(20) NOT NULL,
+ "desc" text NOT NULL,
+ "config" text NOT NULL,
+ "clusterConfig" text NOT NULL,
+ "healthCheck" integer(4) NOT NULL,
+ "healthCheckPath" text(255) NOT NULL,
+ "healthCheckPeriod" integer(11) NOT NULL,
+ "healthCheckCode" text(255) NOT NULL,
+ "healthCheckTimeOut" integer(11) NOT NULL,
+ "createTime" text NOT NULL,
+ "updateTime" text NOT NULL
+);
-- ----------------------------
--- Records of goku_redis_info
+-- Table structure for goku_service_discovery
-- ----------------------------
+DROP TABLE IF EXISTS "goku_service_discovery";
+CREATE TABLE "goku_service_discovery" (
+ "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
+ "name" text(30),
+ "type" text(20),
+ "remark" text(500),
+ "config" text,
+ "default" text(255),
+ "createTime" text,
+ "updateTime" text
+);
-- ----------------------------
--- Table structure for goku_redis_memory
+-- Table structure for goku_table_update_record
-- ----------------------------
-DROP TABLE IF EXISTS `goku_redis_memory`;
-CREATE TABLE `goku_redis_memory` (
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `server` varchar(20) DEFAULT NULL COMMENT 'ip:port',
- `used` int(11) DEFAULT NULL,
- `peak` int(11) DEFAULT NULL,
- `datetime` timestamp NULL DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `server` (`server`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+DROP TABLE IF EXISTS "goku_table_update_record";
+CREATE TABLE "goku_table_update_record" (
+ "name" text(64) NOT NULL,
+ "updateTime" text NOT NULL,
+ "tableID" integer NOT NULL PRIMARY KEY AUTOINCREMENT
+);
--- ----------------------------
--- Records of goku_redis_memory
--- ----------------------------
-- ----------------------------
--- Table structure for goku_redis_server
+-- Records of "sqlite_sequence"
-- ----------------------------
-DROP TABLE IF EXISTS `goku_redis_server`;
-CREATE TABLE `goku_redis_server` (
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `server` varchar(20) NOT NULL DEFAULT '' COMMENT 'ip:port',
- `password` varchar(20) DEFAULT NULL,
- `clusterID` int(11) NOT NULL DEFAULT '1',
- `status` int(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`id`),
- UNIQUE KEY `server` (`server`,`clusterID`),
- KEY `status` (`status`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+INSERT INTO "sqlite_sequence" VALUES ('goku_admin', 1);
+INSERT INTO "sqlite_sequence" VALUES ('goku_plugin', 30);
+INSERT INTO "sqlite_sequence" VALUES ('goku_balance', 0);
+INSERT INTO "sqlite_sequence" VALUES ('goku_config_log', 0);
+INSERT INTO "sqlite_sequence" VALUES ('goku_gateway_strategy_group', 1);
-- ----------------------------
--- Records of goku_redis_server
+-- Auto increment value for goku_admin
-- ----------------------------
+UPDATE "sqlite_sequence" SET seq = 1 WHERE name = 'goku_admin';
-- ----------------------------
--- Table structure for goku_service_config
+-- Auto increment value for goku_balance
-- ----------------------------
-DROP TABLE IF EXISTS `goku_service_config`;
-CREATE TABLE `goku_service_config` (
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(255) NOT NULL DEFAULT '',
- `default` tinyint(4) DEFAULT NULL,
- `driver` varchar(20) NOT NULL DEFAULT '' COMMENT 'driver.name',
- `desc` text NOT NULL,
- `config` text NOT NULL,
- `clusterConfig` text NOT NULL,
- `healthCheck` tinyint(4) NOT NULL DEFAULT '0',
- `healthCheckPath` varchar(255) NOT NULL DEFAULT '/',
- `healthCheckPeriod` int(11) NOT NULL DEFAULT '5',
- `healthCheckCode` varchar(255) NOT NULL DEFAULT '200',
- `healthCheckTimeOut` int(11) NOT NULL DEFAULT '200',
- `createTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `updateTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`),
- UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
--- Records of goku_service_config
+-- Indexes structure for table goku_balance
-- ----------------------------
+CREATE INDEX "balanceName"
+ON "goku_balance" (
+ "balanceName" ASC
+);
-- ----------------------------
--- Table structure for goku_service_discovery
+-- Indexes structure for table goku_cluster
-- ----------------------------
-DROP TABLE IF EXISTS `goku_service_discovery`;
-CREATE TABLE `goku_service_discovery` (
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(30) DEFAULT NULL,
- `type` varchar(20) DEFAULT NULL,
- `remark` varchar(500) DEFAULT NULL,
- `config` text,
- `default` varchar(255) DEFAULT NULL,
- `createTime` timestamp NULL DEFAULT NULL,
- `updateTime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`id`),
- UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE INDEX "name"
+ON "goku_cluster" (
+ "name" ASC
+);
-- ----------------------------
--- Records of goku_service_discovery
+-- Auto increment value for goku_config_log
-- ----------------------------
-- ----------------------------
--- Table structure for goku_table_update_record
+-- Auto increment value for goku_gateway_strategy_group
-- ----------------------------
-DROP TABLE IF EXISTS `goku_table_update_record`;
-CREATE TABLE `goku_table_update_record` (
- `name` varchar(64) NOT NULL,
- `updateTime` datetime NOT NULL,
- `tableID` int(10) unsigned NOT NULL AUTO_INCREMENT,
- PRIMARY KEY (`tableID`),
- UNIQUE KEY `name` (`name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+UPDATE "sqlite_sequence" SET seq = 1 WHERE name = 'goku_gateway_strategy_group';
-- ----------------------------
--- Records of goku_table_update_record
+-- Auto increment value for goku_plugin
-- ----------------------------
+UPDATE "sqlite_sequence" SET seq = 30 WHERE name = 'goku_plugin';
--- ----------------------------
--- Table structure for goku_version
--- ----------------------------
-DROP TABLE IF EXISTS `goku_version`;
-CREATE TABLE `goku_version` (
- `version` varchar(20) NOT NULL DEFAULT '',
- `sol` int(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`version`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
--- ----------------------------
--- Records of goku_version
--- ----------------------------
-INSERT INTO `goku_version` VALUES ('3.0.0', '0');
+PRAGMA foreign_keys = true;
diff --git a/app/console/static/assets/font/icomoon.eot b/build/console/resources/static/assets/font/icomoon.eot
similarity index 100%
rename from app/console/static/assets/font/icomoon.eot
rename to build/console/resources/static/assets/font/icomoon.eot
diff --git a/app/console/static/assets/font/icomoon.svg b/build/console/resources/static/assets/font/icomoon.svg
similarity index 100%
rename from app/console/static/assets/font/icomoon.svg
rename to build/console/resources/static/assets/font/icomoon.svg
diff --git a/app/console/static/assets/font/icomoon.ttf b/build/console/resources/static/assets/font/icomoon.ttf
similarity index 100%
rename from app/console/static/assets/font/icomoon.ttf
rename to build/console/resources/static/assets/font/icomoon.ttf
diff --git a/app/console/static/assets/font/icomoon.woff b/build/console/resources/static/assets/font/icomoon.woff
similarity index 100%
rename from app/console/static/assets/font/icomoon.woff
rename to build/console/resources/static/assets/font/icomoon.woff
diff --git a/app/console/static/assets/font/iconfont.eot b/build/console/resources/static/assets/font/iconfont.eot
similarity index 100%
rename from app/console/static/assets/font/iconfont.eot
rename to build/console/resources/static/assets/font/iconfont.eot
diff --git a/app/console/static/assets/font/iconfont.svg b/build/console/resources/static/assets/font/iconfont.svg
similarity index 100%
rename from app/console/static/assets/font/iconfont.svg
rename to build/console/resources/static/assets/font/iconfont.svg
diff --git a/app/console/static/assets/font/iconfont.ttf b/build/console/resources/static/assets/font/iconfont.ttf
similarity index 100%
rename from app/console/static/assets/font/iconfont.ttf
rename to build/console/resources/static/assets/font/iconfont.ttf
diff --git a/app/console/static/assets/font/iconfont.woff b/build/console/resources/static/assets/font/iconfont.woff
similarity index 100%
rename from app/console/static/assets/font/iconfont.woff
rename to build/console/resources/static/assets/font/iconfont.woff
diff --git a/app/console/static/assets/font/iconfont.woff2 b/build/console/resources/static/assets/font/iconfont.woff2
similarity index 100%
rename from app/console/static/assets/font/iconfont.woff2
rename to build/console/resources/static/assets/font/iconfont.woff2
diff --git a/app/console/static/assets/images/eolinker_sim_0.png b/build/console/resources/static/assets/images/eolinker_sim_0.png
similarity index 100%
rename from app/console/static/assets/images/eolinker_sim_0.png
rename to build/console/resources/static/assets/images/eolinker_sim_0.png
diff --git a/app/console/static/assets/images/favicon.ico b/build/console/resources/static/assets/images/favicon.ico
similarity index 100%
rename from app/console/static/assets/images/favicon.ico
rename to build/console/resources/static/assets/images/favicon.ico
diff --git a/app/console/static/assets/images/logo_admin.png b/build/console/resources/static/assets/images/logo_admin.png
similarity index 100%
rename from app/console/static/assets/images/logo_admin.png
rename to build/console/resources/static/assets/images/logo_admin.png
diff --git a/app/console/static/assets/images/logo_white_mini.png b/build/console/resources/static/assets/images/logo_white_mini.png
similarity index 100%
rename from app/console/static/assets/images/logo_white_mini.png
rename to build/console/resources/static/assets/images/logo_white_mini.png
diff --git a/app/console/static/assets/images/upload_icons.png b/build/console/resources/static/assets/images/upload_icons.png
similarity index 100%
rename from app/console/static/assets/images/upload_icons.png
rename to build/console/resources/static/assets/images/upload_icons.png
diff --git a/app/console/static/index.html b/build/console/resources/static/index.html
similarity index 95%
rename from app/console/static/index.html
rename to build/console/resources/static/index.html
index 87bdc5194358259a02d405cb6e65fd48eb490989..9040743ba9c77541fde8ecc1325edfbe9c284e56 100644
--- a/app/console/static/index.html
+++ b/build/console/resources/static/index.html
@@ -17,7 +17,7 @@
GoKu Gateway | 企业微服务架构的首选解决方案,加速企业数字化转型
-
+
- 单位时间
- *单位时间内,API请求失败到达设定阀值则进行告警
-
-
-
-
-
-
-
告警地址
- *接收告警信息的API地址
-
-
-
-
-
-
接收邮箱
-
-
-
-
-
-
-
- 保存
- 取消
-
-
- 编辑
-
-
-
-
\ No newline at end of file
diff --git a/console/static/src/app/ui/content/alert/setting/index.js b/console/static/src/app/ui/content/alert/setting/index.js
deleted file mode 100644
index ec804cb38d4f2b07f1a5edfd056dc5ab12499d61..0000000000000000000000000000000000000000
--- a/console/static/src/app/ui/content/alert/setting/index.js
+++ /dev/null
@@ -1,179 +0,0 @@
-(function () {
- 'use strict';
- /*
- * author:广州银云信息科技有限公司
- * 环境管理相关js
- */
- angular.module('eolinker')
- .component('alertSetting', {
- templateUrl: 'app/ui/content/alert/setting/index.html',
- controller: indexController
- })
-
- indexController.$inject = ['$rootScope', 'CODE', 'GatewayResource', '$scope', 'Authority_CommonService'];
-
- function indexController($rootScope, CODE, GatewayResource, $scope, Authority_CommonService) {
- var vm = this;
- vm.data = {
- isEdit: false,
- menu:'api'
- }
- vm.ajaxResponse = {
- alertInfo: {}
- }
- vm.fun = {};
- vm.CONST = {
- ALERT_METHOD_ARR:[{
- key:'API告警',
- value:'api',
- tip:"请求成功状态码在 [网关设置>基本设置] 页面设置,返回非成功状态码则视为请求失败;API的告警阀值在API编辑页面设置"
- }],
- ALERT_PROTOCOL_ARR: [{
- key: '不设置任何协议',
- value: 0
- }, {
- key: 'SSL协议',
- value: 1
- }, {
- key: 'TLS协议',
- value: 2
- }],
- alertPeriodTypeQuery: [{
- key: '1分钟',
- value: 0
- }, {
- key: '5分钟',
- value: 1
- }, {
- key: '15分钟',
- value: 2
- }, {
- key: '30分钟',
- value: 3
- }, {
- key: '60分钟',
- value: 4
- }]
- }
- vm.service = {
- authority: Authority_CommonService
- }
- var cache = {
- alertInfo: {}
- },privateFun={};
- vm.fun.startAlert = function () {
- if (vm.data.isEdit) {
- vm.ajaxResponse.alertInfo.alertStatus = vm.ajaxResponse.alertInfo.alertStatus ? 0 : 1;
- }
- }
- vm.fun.changeNotice = function (arg) {
- if (arg.$last) {
- vm.ajaxResponse.alertInfo[vm.data.menu+'AlertInfo'].userEmail.push({
- value: ''
- });
- }
- }
- vm.fun.authorityToEdit = function () {
- vm.data.isEdit = true;
- if(vm.ajaxResponse.alertInfo.apiAlertInfo.userEmail[vm.ajaxResponse.alertInfo.apiAlertInfo.userEmail.length-1].value){
- vm.ajaxResponse.alertInfo.apiAlertInfo.userEmail.push({
- value: ''
- });
- }
- }
- vm.fun.changeAlertMenu=(inputMenuType)=>{
- vm.data.menu=inputMenuType;
- }
- vm.fun.deleteNotice = function (arg) {
- vm.ajaxResponse.alertInfo[vm.data.menu+'AlertInfo'].userEmail.splice(arg.$index, 1);
- }
- vm.fun.checkIsValidEmail=(inputEmail)=>{
- return !/^[0-9A-Za-z-_.]+@[0-9a-z-]+\.[a-z]{2,20}(\.[a-z]{2,20}){0,1}$/.test(inputEmail)&&inputEmail;
- }
- privateFun.spliceUserEmailArr=(inputMarkArr)=>{
- for(let val of inputMarkArr){
- if(vm.ajaxResponse.alertInfo[val+'AlertInfo'].userEmail.length>1)vm.ajaxResponse.alertInfo[val+'AlertInfo'].userEmail.splice(vm.ajaxResponse.alertInfo[val+'AlertInfo'].userEmail.length - 1, 1);
- }
- }
- privateFun.setReceiverList=(inputArr)=>{
- let tmpOutput=[];
- for(let val of inputArr){
- if(vm.fun.checkIsValidEmail(val.value))return false;
- if (val.value) tmpOutput.push(val.value);
- }
- return tmpOutput.join(',');
- }
- vm.fun.editAlert = function () {
- vm.data.submitted=true;
- if ($scope.ConfirmForm.$invalid) {
- $rootScope.InfoModal('编辑失败,请检查信息是否填写完整!', 'error');
- return;
- }
- let tmpAjaxRequest = {
- alertStatus: vm.ajaxResponse.alertInfo.alertStatus,
- sender: vm.ajaxResponse.alertInfo.sender,
- senderPassword: vm.ajaxResponse.alertInfo.senderPassword,
- smtpAddress: vm.ajaxResponse.alertInfo.smtpAddress,
- smtpPort: vm.ajaxResponse.alertInfo.smtpPort,
- smtpProtocol: vm.ajaxResponse.alertInfo.smtpProtocol,
- apiAlertInfo: angular.copy(vm.ajaxResponse.alertInfo.apiAlertInfo)
- }
- tmpAjaxRequest.apiAlertInfo.receiverList=privateFun.setReceiverList(tmpAjaxRequest.apiAlertInfo.userEmail);
- if(tmpAjaxRequest.apiAlertInfo.receiverList===false){
- $rootScope.InfoModal('编辑失败,请检查信息是否填写完整!', 'error');
- return;
- }
- delete tmpAjaxRequest.apiAlertInfo.userEmail;
- tmpAjaxRequest.apiAlertInfo=JSON.stringify(tmpAjaxRequest.apiAlertInfo);
- GatewayResource.Config.AlertEdit(tmpAjaxRequest).$promise.then(function (response) {
- switch (response.statusCode) {
- case CODE.COMMON.SUCCESS: {
- $rootScope.InfoModal('修改成功!', 'success');
- vm.data.isEdit = false;
- privateFun.spliceUserEmailArr(['api','node','redis']);
- angular.copy(vm.ajaxResponse.alertInfo, cache.alertInfo);
- break;
- }
- }
- })
- }
- vm.fun.cancleAlert = function () {
- vm.data.isEdit = false;
- vm.data.userEmail = angular.copy(cache.userEmail);
- vm.ajaxResponse.alertInfo = angular.copy(cache.alertInfo);
- }
- privateFun.splitMailStr=(inputMailStr)=>{
- let tmpOutput=[];
- (inputMailStr.split(',')).map(function (val, key) {
- tmpOutput.push({
- value: val
- })
- });
- return tmpOutput;
- }
- vm.$onInit = function () {
- GatewayResource.Config.AlertInfo().$promise.then(function (response) {
- switch (response.statusCode) {
- case CODE.COMMON.SUCCESS: {
- vm.ajaxResponse.alertInfo = response.gatewayConfig || {
- "alertStatus": 0,
- "sender": "",
- "senderPassword": "",
- "smtpAddress": "",
- "smtpPort": '',
- "smtpProtocol": 0,
- "apiAlertInfo": {
- alertPeriodType:0,
- receiverList:'',
- alertAddr:''
- }
- };
- vm.ajaxResponse.alertInfo.apiAlertInfo.userEmail=privateFun.splitMailStr(vm.ajaxResponse.alertInfo.apiAlertInfo.receiverList);
- angular.copy(vm.ajaxResponse.alertInfo, cache.alertInfo);
- break;
- }
- }
- })
- };
- }
-})();
\ No newline at end of file
diff --git a/console/static/src/app/ui/content/cluster/_default/index.html b/console/static/src/app/ui/content/cluster/_default/index.html
index 2c33a1b029e653fcc2aa8f148946b3c010c414f6..84aba940f5905f09aaee64652384c62472a594d3 100644
--- a/console/static/src/app/ui/content/cluster/_default/index.html
+++ b/console/static/src/app/ui/content/cluster/_default/index.html
@@ -1,5 +1,5 @@
-
+
diff --git a/console/static/src/app/ui/content/cluster/_default/index.js b/console/static/src/app/ui/content/cluster/_default/index.js
index 3ad1c1a11e89dce3eb5a07c28933b9a6f4521c83..f8d4530644fbb6c208b6c5cca7b81dfe73c8f0bb 100644
--- a/console/static/src/app/ui/content/cluster/_default/index.js
+++ b/console/static/src/app/ui/content/cluster/_default/index.js
@@ -6,9 +6,9 @@
controller: indexController
})
- indexController.$inject = ['$scope', 'GatewayResource', '$rootScope', '$state'];
+ indexController.$inject = ['$scope', 'GatewayResource','CODE', '$rootScope', '$state'];
- function indexController($scope, GatewayResource, $rootScope, $state) {
+ function indexController($scope, GatewayResource,CODE, $rootScope, $state) {
var vm = this;
vm.ajaxResponse = {
query: []
@@ -26,7 +26,7 @@
return $rootScope.global.ajax.Query_Cluster.$promise;
}
/**
- * @name 进入集群内页
+ * @desc 进入集群内页
*/
privateFun.inToCluster=(inputArg)=>{
$state.go('home.cluster.node.default',{
@@ -34,11 +34,102 @@
clusterName:inputArg.item.title
});
}
+ /**
+ * @desc 编辑集群
+ */
+ privateFun.editCluster = function (inputArg) {
+ let tmpObj={
+ edit:{
+ title:"修改集群",
+ opr:"Edit",
+ disabled:true,
+ item:inputArg.item
+ },
+ add:{
+ title:"新增集群",
+ opr:"Add",
+ item:{},
+ tip:"创建后不可修改"
+ }
+ };
+ inputArg.item=tmpObj[inputArg.status].item;
+ let tmpModal = {
+ title: tmpObj[inputArg.status].title,
+ resource: GatewayResource.Cluster[tmpObj[inputArg.status].opr],
+ textArray: [{
+ type: 'input',
+ title: `Primary Key`,
+ value: inputArg.item.name||"",
+ key:"name",
+ disabled:tmpObj[inputArg.status].disabled,
+ placeholder:"具有唯一性,支持英文(不区分大小写)、下划线、数字",
+ pattern:"^[a-zA-Z][a-zA-z0-9_]*$",
+ tip:tmpObj[inputArg.status].tip||"",
+ required:true
+ },{
+ type: 'input',
+ title: '集群名称',
+ value: inputArg.item.title||"",
+ key:"title",
+ placeholder:"具有唯一性,支持中文、英文(不区分大小写)、下划线、数字",
+ required:true
+ },{
+ type: 'input',
+ title: '备注',
+ key:"note",
+ value: inputArg.item.note||"",
+ placeholder:"集群备注"
+ }]
+ }
+ $rootScope.MixInputModal(tmpModal,(callback)=>{
+ if(callback){
+ vm.fun.init();
+ $rootScope.InfoModal(`${tmpModal.title}成功`,'success');
+ }
+ })
+ }
+ privateFun.delete = function (inputArg) {
+ let tmpAjaxRequest={
+ name:inputArg.item.name
+ },tmpModal={
+ title:"删除集群"
+ }
+ $rootScope.EnsureModal(tmpModal.title, null, '确认删除?', {btnMessage:'删除'}, function (callback) {
+ if (callback) {
+ GatewayResource.Cluster.Delete(tmpAjaxRequest).$promise.then(function (response) {
+ switch (response.statusCode) {
+ case CODE.COMMON.SUCCESS:
+ {
+ vm.ajaxResponse.query.splice(inputArg.$index, 1);
+ $rootScope.InfoModal(tmpModal.title + '成功', 'success');
+ break;
+ }
+ }
+ })
+ }
+ });
+ }
vm.$onInit = function () {
$scope.$emit('$WindowTitleSet', {
list: ['网关节点']
});
vm.component.menuObject = {
+ list: [{
+ type: 'btn',
+ class: 'btn-group-li pull-left',
+ btnList: [{
+ name: '新建集群',
+ icon: 'jiahao',
+ class: 'eo_theme_btn_success block-btn',
+ fun: {
+ default: privateFun.editCluster,
+ params: {
+ status: 'add'
+ }
+ }
+ }]
+
+ }],
setting: {
class: "common-menu-fixed-seperate common-menu-lg",
titleAuthority: 'showTitle',
@@ -59,17 +150,28 @@
key: '备注',
html: '{{item.note}}'
}, {
- key: '数据库地址',
- html: `{{item.db.host+':'+item.db.port+'/'+item.db.database}}`
+ key: 'Primary Key',
+ html: '{{item.name}}'
}],
operate: {
funArr: [{
key: '查看详情',
fun: privateFun.inToCluster
+ },
+ {
+ key: '修改',
+ fun: privateFun.editCluster,
+ params: {
+ status: 'edit'
+ }
+ }, {
+ key: `删除 `,
+ fun: privateFun.delete,
+ itemExpression:`ng-disabled="item.nodeCount"`
}
],
power: -1,
- class:'w_100'
+ class:'w_200'
}
},
baseFun:{
diff --git a/console/static/src/app/ui/content/cluster/_default/index.scss b/console/static/src/app/ui/content/cluster/_default/index.scss
index 93a3d5534ee6e70a8b594bfc971c763637db881e..9dc553f7a6e6068516f87308b7f3a473d11a7bf1 100644
--- a/console/static/src/app/ui/content/cluster/_default/index.scss
+++ b/console/static/src/app/ui/content/cluster/_default/index.scss
@@ -1,16 +1,8 @@
cluster-default{
- list-default-common-component .first-level-article{
- margin-top: 0;
+ list-default-common-component tip-directive{
+ margin-left: 0;
}
- menu-Default-Common-Component .common_menu_ul .search-form {
- position: absolute;
- right: 20px;
- top: 10px;
- }
- .menu-title:nth-child(2){
- padding-bottom: 0;
- }
- menu-Default-Common-Component .disabled-operate-has-second-title-placeholder{
- height: 113px;
+ list-default-common-component .eo-tip-container{
+ margin-left: -15px !important;
}
}
\ No newline at end of file
diff --git a/console/static/src/app/ui/content/gpedit/common/group/index.js b/console/static/src/app/ui/content/gpedit/common/group/index.js
index 35a777f4d61a94f1f61adbda6f0ae3760d40eed6..3b2c58d6f98dc794686a650057a832156d55cf50 100644
--- a/console/static/src/app/ui/content/gpedit/common/group/index.js
+++ b/console/static/src/app/ui/content/gpedit/common/group/index.js
@@ -80,7 +80,7 @@
params: {
modal: {
title: '删除分组',
- message: '删除分组后,该分组内的网关节点也将被删除,该操作无法撤销,确认删除?'
+ message: '删除分组后,该分组内的策略也将被删除,该操作无法撤销,确认删除?'
}
}
}]
diff --git a/console/static/src/app/ui/content/gpedit/inside/content/api/_default/index.js b/console/static/src/app/ui/content/gpedit/inside/content/api/_default/index.js
index b924b47783eee32907f203a7e99dffde66cba000..12578f20fa601678dd629471aa29c2c0764bab35 100644
--- a/console/static/src/app/ui/content/gpedit/inside/content/api/_default/index.js
+++ b/console/static/src/app/ui/content/gpedit/inside/content/api/_default/index.js
@@ -238,7 +238,7 @@
primaryKey:'apiID',
default: [{
key: 'APIs',
- html: '{{item.apiName}}',
+ html: `{{item.apiType?"编排":"普通"}} {{item.apiName}} `,
draggableCacheMark: 'name'
},{
key: '请求方式',
diff --git a/console/static/src/app/ui/content/gpedit/inside/content/api/operate/index.js b/console/static/src/app/ui/content/gpedit/inside/content/api/operate/index.js
index bdd952cf957f0716a0f5a037a362f0cdd76a3705..169a8b2a61325b0331116ac769eac33f602fbf2d 100644
--- a/console/static/src/app/ui/content/gpedit/inside/content/api/operate/index.js
+++ b/console/static/src/app/ui/content/gpedit/inside/content/api/operate/index.js
@@ -228,7 +228,7 @@
primaryKey: 'apiID',
default: [{
key: 'APIs',
- html: '{{item.apiName}}'
+ html: `{{item.apiType?"编排":"普通"}} {{item.apiName}} `,
}, {
key: '请求方式',
html: '{{item.requestMethod}}'
diff --git a/console/static/src/app/ui/content/monitor/global/index.html b/console/static/src/app/ui/content/monitor/global/index.html
index ba4f01cca903e57de6965727f3e07cf2aef00677..72ef63fdd8f80419f14415818927e446656c3dad 100644
--- a/console/static/src/app/ui/content/monitor/global/index.html
+++ b/console/static/src/app/ui/content/monitor/global/index.html
@@ -19,10 +19,6 @@
节点
-
-
{{$ctrl.ajaxResponse.monitorInfo.baseInfo.redisCount}}
-
REDIS
-
@@ -44,63 +40,6 @@
-
-
-
-
-
-
-
{{$ctrl.ajaxResponse.monitorInfo.gatewayRequestInfo.gatewayRequestCount}}
-
请求到达总数
-
-
-
{{$ctrl.ajaxResponse.monitorInfo.gatewayRequestInfo.gatewayErrorCount||0}}
-
请求异常数量
-
-
-
- {{$ctrl.ajaxResponse.monitorInfo.gatewayRequestInfo.gatewaySuccessRate}}
-
-
请求成功率
-
-
-
-
-
-
-
-
{{$ctrl.ajaxResponse.monitorInfo.proxyRequestInfo.proxyRequestCount}}
-
请求转发总数
-
-
-
{{$ctrl.ajaxResponse.monitorInfo.proxyRequestInfo.proxyErrorCount||0}}
-
转发异常数量
-
-
-
- {{$ctrl.ajaxResponse.monitorInfo.proxyRequestInfo.proxySuccessRate}}
-
-
转发成功率
-
-
-
-
diff --git a/console/static/src/app/ui/content/monitor/global/index.js b/console/static/src/app/ui/content/monitor/global/index.js
index f4b193451841500c8ea1ffaa2a1df76af0d39cac..faf8786e61f9918b2ead8574cee2ed6fef538e6a 100644
--- a/console/static/src/app/ui/content/monitor/global/index.js
+++ b/console/static/src/app/ui/content/monitor/global/index.js
@@ -13,32 +13,9 @@
var vm = this,
privateFun = {}
- vm.data = {
- cluster:'',
- tabSummaryList: [{
- name: '今天',
- active: 0
- }, {
- name: '近3天',
- active: 1
- }, {
- name: '近7天',
- active: 2
- }, {
- active: 3,
- type: 'html'
- }],
- granularityList: [{
- name: '小时',
- active: 1
- }, {
- name: '天',
- active: 0
- }]
- }
+ vm.data = {}
vm.fun = {};
vm.ajaxRequest={
- projectHashKey: $state.params.projectHashKey,
table: {
beginTime: null,
endTime: null,
@@ -61,60 +38,13 @@
overviewObject: {},
listDefaultCommonObject: null
}
- privateFun.filterTime = function (mark) {
- var template = {
- startTime: uibDateParser.filter(vm.directive[mark + 'TimeObject'].request.startTime, 'yyyy-M!-dd'),
- endTime: uibDateParser.filter(vm.directive[mark + 'TimeObject'].request.endTime, 'yyyy-M!-dd')
- }
- if (!template.startTime) {
- $rootScope.InfoModal('请选择开始日期', 'error');
- } else if (!template.endTime) {
- $rootScope.InfoModal('请选择结束日期', 'error');
- } else {
-
- vm.ajaxRequest[mark].period = 3;
- vm.directive[mark + 'TimeObject'].show = false;
- if (template.startTime > template.endTime) {
- template.templateTime = template.startTime;
- template.startTime = template.endTime;
- template.endTime = template.templateTime;
- }
- vm.ajaxRequest[mark].beginTime = template.startTime;
- vm.ajaxRequest[mark].endTime = template.endTime;
- privateFun.initTable();
- }
- }
- vm.fun.tableFilterTime = function (arg) {
- if (arg) arg.$event.stopPropagation();
- privateFun.filterTime('table')
- }
- vm.fun.changeMenu = function (mark, arg) {
- if (arg.item.active == 3) {
- vm.directive.tableTimeObject.show = true;
- arg.$event.stopPropagation();
- return;
- } else {
- vm.directive.tableTimeObject.request = {};
- vm.ajaxRequest.table.beginTime = null;
- }
- vm.ajaxRequest.table.period = arg.item.active;
- privateFun.initTable();
- }
privateFun.initTable=function(){
- var template = {
- promise: null,
- request: {
- beginTime: vm.ajaxRequest.table.beginTime,
- endTime: vm.ajaxRequest.table.endTime,
- period: vm.ajaxRequest.table.period,
- cluster:vm.data.cluster
- }
- }
- template.promise = GatewayResource.Monitor.Info(template.request).$promise;
- template.promise.then(function (response) {
+ let tmpPromise;
+ tmpPromise = GatewayResource.Monitor.Info().$promise;
+ tmpPromise.then(function (response) {
vm.ajaxResponse.monitorInfo = response || {};
})
- return template.promise;
+ return tmpPromise;
}
privateFun.refresh=function(){
var tmpPromise=GatewayResource.Monitor.Refresh().$promise;
@@ -146,23 +76,12 @@
type:'default'
}
switch(arg.type){
- case 'default':{
- if(vm.data.cluster){
- return privateFun.initTable();
- }else{
- let tmpPromise=privateFun.initCluster();
- tmpPromise.finally(()=>{
- privateFun.initTable();
- })
- return tmpPromise;
- }
+ default:{
+ return privateFun.initTable();;
}
case 'refresh':{
return privateFun.refresh();
}
- case 'cluster':{
- return privateFun.initTable();
- }
}
}
@@ -175,28 +94,9 @@
}
});
}
- vm.fun.changeClutser=()=>{
- $scope.$emit('$TransferStation', {
- state: '$Init_LoadingCommonComponent',
- data:{
- type:'cluster'
- }
- });
- }
- privateFun.initCluster=()=>{
- let tmpPromise=GatewayResource.Cluster.SimpleQuery().$promise;
- tmpPromise.then((response)=>{
- vm.ajaxResponse.clusterArr=[{
- title:"所有集群",
- name:null
- }].concat(response.clusters||[]);
- vm.data.cluster=vm.ajaxResponse.clusterArr[0].name;
- })
- return tmpPromise;
- }
vm.$onInit = function () {
$scope.$emit('$WindowTitleSet', {
- list: ['监控面板']
+ list: ['首页']
});
privateFun.initComponent();
}
diff --git a/console/static/src/app/ui/content/project/api/_default/index.js b/console/static/src/app/ui/content/project/api/_default/index.js
index a7bac182d41eb672f66095c68eb6e33b33eac1b8..671bf7f92e64a8e25d7d6e55c63a49d9195ee593 100644
--- a/console/static/src/app/ui/content/project/api/_default/index.js
+++ b/console/static/src/app/ui/content/project/api/_default/index.js
@@ -309,7 +309,7 @@
primaryKey: 'apiID',
default: [{
key: 'APIs',
- html: '{{item.apiName}}',
+ html: `
{{item.apiType?"编排":"普通"}} {{item.apiName}} `,
draggableCacheMark: 'name'
}, {
key: '请求方式',
@@ -397,11 +397,19 @@
class: 'pull-left',
btnClass: 'eo_theme_btn_success',
btnList: [{
- name: '新建接口',
+ name: '普通接口',
fun: {
default: privateFun.edit,
params: {
- status: 'add'
+ status: 'add-common'
+ }
+ }
+ }, {
+ name: '链式调用(服务编排)',
+ fun: {
+ default: privateFun.edit,
+ params: {
+ status: 'add-link'
}
}
}, {
diff --git a/console/static/src/app/ui/content/project/api/_default/index.scss b/console/static/src/app/ui/content/project/api/_default/index.scss
index 4d54c311bb7700ba3e832d63f229cf3442f26c60..3b7b2421aa88106d9d8472a4c48d78035e2d3ffa 100644
--- a/console/static/src/app/ui/content/project/api/_default/index.scss
+++ b/console/static/src/app/ui/content/project/api/_default/index.scss
@@ -2,6 +2,9 @@ api-default{
list-default-common-component .fixed-height-list{
@include eo-height(100%,183px);
}
+ menu-Default-Common-Component .more-btn-div{
+ right: auto !important;
+ }
}
api-Group{
.common-scss-group{
diff --git a/console/static/src/app/ui/content/project/api/group/index.js b/console/static/src/app/ui/content/project/api/group/index.js
index 6ac2e514cf0cc5c6817f37cf12ca51d7faaadb20..a14e27b417e4b30b85ea3cb221c0877c74396957 100644
--- a/console/static/src/app/ui/content/project/api/group/index.js
+++ b/console/static/src/app/ui/content/project/api/group/index.js
@@ -135,7 +135,7 @@
params: {
modal: {
title: '删除分组',
- message: '删除分组后,该分组下的api将全部移入接口回收站,该操作无法撤销,确认删除?'
+ message: '删除分组后,该分组内的API也将被删除,该操作无法撤销,确认删除?'
}
},
key: '删除'
diff --git a/console/static/src/app/ui/content/project/api/operate/index.html b/console/static/src/app/ui/content/project/api/operate/index.html
index 2935d14b69e85929fa3b8bf75302d0edef978a5a..e24ab76a6cec532efee2c7f8e3a1899fdd81e361 100644
--- a/console/static/src/app/ui/content/project/api/operate/index.html
+++ b/console/static/src/app/ui/content/project/api/operate/index.html
@@ -1,137 +1,137 @@
-
-
-
-
-
-
-
分组:
-
-
-
-
-
名称:
-
-
-
+
+
+
+
+ 分组:
+
+
+
+
+
+ 返回数据类型:
+
+
+
+
+ 不转换
+ JSON
+ XML
+
+
+ 名称:
+
+
+
+
+
+ 请求方式:
+
+
+
+
+
+ {{item.checkbox?'':' '}}
+ {{item.key}}
+
+
+
+ 请求路径:
+
+
+
+
+
+
- 请求方式:
-
-
-
-
-
-
{{item.checkbox?'':' '}}
-
{{item.key}}
+
转发地址/负载后端(Target/Upstream):
+
+
+
-
-
- 请求路径:
-
-
-
-
-
+
+ 转发路径:
+
+
+
+
+
+
+ 转发方式:
+
+
+
+
+ 跟随用户请求方式
+ POST
+ GET
+ PUT
+ DELETE
+ HEAD
+ OPTIONS
+ PATCH
+
+
+
+
+ 超时限制(ms):
+
+
+
+
+
+
- 转发地址/负载后端(Target/Upstream):
-
-
-
+
+
+
+
+ 异常返回:
+
-
- 转发路径:
-
-
-
-
-
-
-
-
- 转发时去除匹配网关请求路径,实际转发路径:{{$ctrl.ajaxResponse.apiInfo.targetURL}}{{$ctrl.ajaxResponse.apiInfo.stripPrefix?'':($ctrl.ajaxResponse.apiInfo.requestURL|Filter_SlashSymbol)}}
-
-
-
-
- 转发时去除路径中多余的"/",例如“//login”会被解析成“/login”
-
-
+
-
- 转发方式:
-
-
-
-
- 跟随用户请求方式
- POST
- GET
- PUT
- DELETE
- HEAD
- OPTIONS
- PATCH
-
-
-
- 超时限制(ms):
-
-
-
-
-
-
- 重试次数[非必填]:
-
-
-
-
-
-
告警阀值(次)[非必填]:*单位时间内,请求失败到达该阀值进行告警,0代表不进行告警;单位时间在告警管理处设定
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/console/static/src/app/ui/content/project/api/operate/index.js b/console/static/src/app/ui/content/project/api/operate/index.js
index e452a8ba5999ceeb048c3da5e9a1b5c776cb8250..6b2a7d05fc359187d20b27208025a84bca4a3dfa 100644
--- a/console/static/src/app/ui/content/project/api/operate/index.js
+++ b/console/static/src/app/ui/content/project/api/operate/index.js
@@ -20,6 +20,8 @@
function indexController($scope, GatewayResource, $state, CODE, $rootScope, GroupService) {
var vm = this;
vm.data = {
+ status:$state.params.status,
+ isSpreedStaticResponse:true,
requestMethod: false,
apiGroup: null,
requestMethodList: [{
@@ -51,6 +53,15 @@
groupID: $state.params.groupID || -1,
apiID: $state.params.apiID
}
+ vm.CONST = {
+ PROTOCOL_ARR: [{
+ key: 'HTTP',
+ value: 'http'
+ }, {
+ key: 'HTTPS',
+ value: 'https'
+ }]
+ }
vm.ajaxResponse = {
apiInfo: {
apiName: '',
@@ -60,12 +71,12 @@
targetURL: '/',
targetMethod: '-1',
isFollow: true,
- stripPrefix: true,
- stripSlash:true,
timeout: '2000',
- retryCount: '',
- alertValve: 0,
- protocol: 'http'
+ retryCount: 0,
+ protocol: 'http',
+ responseDataType:$state.params.status==="add-link"?"json":"origin",
+ linkApis:[],
+ apiType:$state.params.status==="add-link"?1:0
},
balanceList:[]
}
@@ -77,26 +88,83 @@
menuObject: {
list: []
},
- balanceAutoCompleteObj:{required:true,pattern:'[\\w\\._\\/\\-\\:]+'}
+ balanceAutoCompleteObj:{required:true,pattern:'[\\w\\._\\/\\-\\:]+'},
+ apiLinkStepObj:{
+ CONST:{
+ PROTOCOL_ARR:vm.CONST.PROTOCOL_ARR
+ }
+ }
};
- vm.CONST = {
- PROTOCOL_ARR: [{
- key: 'HTTP',
- value: 'http'
- }, {
- key: 'HTTPS',
- value: 'https'
- }]
- }
+
var privateFun = {};
vm.fun.back = function () {
$state.go('home.project.api.default', {
'groupID': $state.params.groupID
});
}
+ privateFun.parseLinkApis=()=>{
+ if(vm.ajaxResponse.apiInfo.apiType===0)return true;
+ let tmpLinkApis=angular.copy(vm.ajaxResponse.apiInfo.linkApis);
+ for(let key in tmpLinkApis){
+ let val=tmpLinkApis[key];
+ if(!/^[1-9]\d*$/.test(val.timeout)){
+ return false;
+ }
+ val.timeout=parseInt(val.timeout);
+ if(!/(^[1-9]\d*$)|(^0$)/.test(val.retry)){
+ return false;
+ }
+ val.retry=parseInt(val.retry);
+ let tmpList=[];
+ val.blackList.map((childItem)=>{
+ if(childItem.ip){
+ tmpList.push(childItem.ip);
+ }
+ })
+ val.blackList=tmpList;
+ tmpList=[];
+ val.whiteList.map((childItem)=>{
+ if(childItem.ip){
+ tmpList.push(childItem.ip);
+ }
+ })
+ val.whiteList=tmpList;
+ val.delete=val.delete.filter((childItem)=>{
+ if(childItem.origin)return childItem;
+ });
+ tmpList=[];
+ for(let childKey in val.move){
+ let childItem =val.move[childKey];
+ if(childItem.target){
+ if(childItem.origin){
+ tmpList.push(childItem)
+ }else return;
+ }
+ }
+ val.move=tmpList;
+ tmpList=[];
+ for(let childKey in val.rename){
+ let childItem =val.rename[childKey];
+ if(childItem.target){
+ if(childItem.origin){
+ childItem.target=(childItem.prefixStr||"")+childItem.target;
+ tmpList.push(childItem)
+ }else return;
+ }
+ }
+ val.rename=tmpList;
+ }
+ return JSON.stringify(tmpLinkApis,(tmpInputKey,tmpInputItem)=>{
+ if (/(prefixStr)|(prefixStr)|($$hashKey)/.test(tmpInputKey)) {
+ return undefined;
+ }
+ return tmpInputItem;
+ })
+ }
privateFun.confirm = function () {
vm.data.requestMethod = false;
var tmpOutput = {
+ apiType:vm.ajaxResponse.apiInfo.apiType,
projectID: vm.ajaxRequest.projectID,
groupID: vm.component.selectMultistageCommonComponentObject.new.value==-1?0:vm.component.selectMultistageCommonComponentObject.new.value,
apiName: vm.ajaxResponse.apiInfo.apiName,
@@ -105,12 +173,11 @@
balanceName: vm.ajaxResponse.apiInfo.balanceName,
targetURL: vm.ajaxResponse.apiInfo.targetURL,
targetMethod: vm.ajaxResponse.apiInfo.targetMethod,
- stripPrefix: vm.ajaxResponse.apiInfo.stripPrefix,
+ responseDataType: vm.ajaxResponse.apiInfo.responseDataType,
timeout: vm.ajaxResponse.apiInfo.timeout,
retryCount: vm.ajaxResponse.apiInfo.retryCount,
- alertValve: vm.ajaxResponse.apiInfo.alertValve,
protocol:vm.ajaxResponse.apiInfo.protocol,
- stripSlash:vm.ajaxResponse.apiInfo.stripSlash
+ staticResponse:vm.ajaxResponse.apiInfo.staticResponse
}
for (var key in vm.data.requestMethodList) {
if (vm.data.requestMethodList[key].checkbox) {
@@ -122,7 +189,7 @@
} else {
vm.data.requestMethod = true;
}
- switch ($state.params.status) {
+ switch (vm.data.status) {
case 'edit': {
tmpOutput.apiID = vm.ajaxRequest.apiID
break;
@@ -141,12 +208,13 @@
});
}
vm.fun.requestProcessing = function (arg) {
- var tmpAjaxRequest = privateFun.confirm(),
- tmpPromise = null;
+ var tmpPromise = null,tmpLinkApis=privateFun.parseLinkApis(),tmpAjaxRequest=privateFun.confirm();
vm.data.submitted = true;
- if ($scope.ConfirmForm.$valid && !vm.data.requestMethod) {
+ if ($scope.ConfirmForm.$valid && !vm.data.requestMethod&&tmpLinkApis) {
tmpPromise = privateFun.edit({
- request: tmpAjaxRequest
+ request: tmpLinkApis!==true?Object.assign({},tmpAjaxRequest,{
+ linkApis:tmpLinkApis
+ }):tmpAjaxRequest
});
} else {
$rootScope.InfoModal('API编辑失败,请检查信息是否填写完整!', 'error');
@@ -156,7 +224,7 @@
}
privateFun.edit = function (arg) {
var tmpPromise = null;
- if ($state.params.status == 'edit') {
+ if (vm.data.status == 'edit') {
tmpPromise = GatewayResource.Api.Edit(arg.request).$promise;
tmpPromise.then(function (response) {
switch (response.statusCode) {
@@ -196,7 +264,7 @@
projectID: vm.ajaxRequest.projectID,
apiID: vm.ajaxRequest.apiID
}
- switch ($state.params.status) {
+ switch (vm.data.status) {
case 'edit': {
GatewayResource.Api.Info(tmpAjaxRequest).$promise.then(function (response) {
switch (response.statusCode) {
@@ -237,6 +305,46 @@
}
}
}
+ if(response.apiInfo.apiType===1){
+ vm.ajaxResponse.apiInfo.linkApis.map((val)=>{
+ let tmpList=[];
+ val.timeout=(val.timeout||2000).toString();
+ val.blackList.map((childItem)=>{
+ tmpList.push({
+ ip:childItem
+ })
+ })
+ val.blackList=tmpList.concat([{ip:""}]);
+ tmpList=[];
+ val.whiteList.map((childItem)=>{
+ tmpList.push({
+ ip:childItem
+ })
+ })
+ val.whiteList=tmpList.concat([{ip:""}]);
+ tmpList=[];
+ val.delete.map((childItem)=>{
+ tmpList.push(childItem)
+ })
+ val.delete=tmpList.concat([{origin:""}]);
+
+ tmpList=[];
+ val.move.map((childItem)=>{
+ tmpList.push(childItem)
+ })
+ val.move=tmpList.concat([{origin:"",target:""}]);
+
+ tmpList=[];
+ val.rename.map((childItem)=>{
+ let tmpArr=childItem.target.split('.');
+ childItem.prefixStr=tmpArr.slice(0,tmpArr.length-1).join('.');
+ if(childItem.prefixStr)childItem.prefixStr+=".";
+ childItem.target=tmpArr[tmpArr.length-1];
+ tmpList.push(childItem)
+ })
+ val.rename=tmpList.concat([{origin:"",target:""}]);
+ })
+ }
break;
}
}
diff --git a/console/static/src/app/ui/content/project/api/operate/index.scss b/console/static/src/app/ui/content/project/api/operate/index.scss
index 18936898b9e4e614d167e05dd61c9a791365ae23..f70b4e03783eb782623dd319b02fe6c6eeb356cb 100644
--- a/console/static/src/app/ui/content/project/api/operate/index.scss
+++ b/console/static/src/app/ui/content/project/api/operate/index.scss
@@ -1,27 +1,33 @@
api-operate {
- .home-common-project-list {
- z-index: 0;
- tip-directive{
- margin-left: 0;
- }
- .first-level-article {
- margin-left: $PLATE_PADDING;
- margin-right:$PLATE_PADDING;
+ z-index: 0;
+ tip-directive{
+ margin-left: 0;
+ }
+ .abnormal_container_aop{
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ width: 578px;
+ }
+ .abnormal_text_aop{
+ background-color: #fafafa;
+ }
+ .first-level-article {
+ margin-left: $PLATE_PADDING;
+ margin-right:$PLATE_PADDING;
- border: 1px solid #e5e5e5;
- background-color: #fff;
- font-size: 14px;
- padding: 10px;
- }
- .select_common_aop,.input_common_aop {
- width: 578px;
- }
- .select_target_protocol_aop{
- width: 100px;
- }
- .input_target_aop{
- width: 473px;
- }
+ border: 1px solid #e5e5e5;
+ background-color: #fff;
+ font-size: 14px;
+ padding: 10px;
+ }
+ .select_common_aop,.input_common_aop {
+ width: 578px;
+ }
+ .select_target_protocol_aop{
+ width: 100px;
+ }
+ .input_target_aop{
+ width: 473px;
}
}
\ No newline at end of file
diff --git a/console/static/src/app/ui/content/publish/index.html b/console/static/src/app/ui/content/publish/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..1837483c707e017329c9e312aa747318af5a4e13
--- /dev/null
+++ b/console/static/src/app/ui/content/publish/index.html
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/console/static/src/app/ui/content/publish/index.js b/console/static/src/app/ui/content/publish/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..022ddf3cdc5a7303267065f000fb587b8bb9fd11
--- /dev/null
+++ b/console/static/src/app/ui/content/publish/index.js
@@ -0,0 +1,279 @@
+(function () {
+ 'use strict';
+ angular.module('eolinker')
+ .config(['$stateProvider', 'RouteHelpersProvider', function ($stateProvider, helper) {
+ $stateProvider
+ .state('home.publish', {
+ url: '/publish',
+ template: '
'
+ })
+ }])
+ .component('publish', {
+ templateUrl: 'app/ui/content/publish/index.html',
+ controller: indexController
+ })
+
+ indexController.$inject = ['$scope', 'GatewayResource', '$state', '$rootScope', 'CODE', 'Authority_CommonService'];
+
+ function indexController($scope, GatewayResource, $state, $rootScope, CODE, Authority_CommonService) {
+ var vm = this;
+ vm.data = {
+ batch: {},
+ alreadyHadPublishConf:false //是否已经存在已发布的配置
+ }
+ vm.ajaxRequest = {
+ versionID: [],
+ keyword: window.sessionStorage.getItem('COMMON_SEARCH_TIP')
+ };
+ vm.ajaxResponse = {};
+ vm.fun = {};
+ vm.service = {
+ authority: Authority_CommonService
+ }
+ vm.component = {
+ menuObject: null
+ }
+ var privateFun = {},cache={
+ publishQuery:[]
+ };
+
+ vm.fun.init = function () {
+ let tmpAjaxRequest = {};
+ if (vm.ajaxRequest.keyword) {
+ tmpAjaxRequest.keyword = vm.ajaxRequest.keyword;
+ }
+ vm.data.alreadyHadPublishConf=false;
+ $rootScope.global.ajax.Query_Version = GatewayResource.Version.Query(tmpAjaxRequest);
+ $rootScope.global.ajax.Query_Version.$promise.then(function (response) {
+ vm.ajaxResponse.query = response.configList || [];
+ if(vm.ajaxResponse.query.length>0&&vm.ajaxResponse.query[0].publishStatus===1){
+ vm.data.alreadyHadPublishConf=true;
+ }
+ })
+ return $rootScope.global.ajax.Query_Version.$promise;
+ }
+ privateFun.generateConf = function () {
+ let tmpModal = {
+ title: "生成配置",
+ resource: GatewayResource.Version.Add,
+ btnObject:{
+ text:"保存"
+ },
+ tmpBtnObj:{
+ ajaxRequest:{
+ publish:1
+ },
+ text:"保存并发布"
+ },
+ textArray: [{
+ type: 'input',
+ title: "名称",
+ key:"name",
+ placeholder:"配置名称",
+ required:true
+ },{
+ type: 'input',
+ title: '版本号',
+ key:"version",
+ placeholder:"配置版本号,如1.0"
+ },{
+ type: 'input',
+ title: '备注',
+ key:"remark",
+ placeholder:"配置备注"
+ }]
+ }
+ $rootScope.MixInputModal(tmpModal,(callback)=>{
+ if(callback){
+ vm.fun.init();
+ $rootScope.InfoModal(`${tmpModal.title}成功`,'success');
+ }
+ })
+ }
+ privateFun.publish = function (inputArg) {
+ let tmpModal = {
+ title: "发布配置"
+ },tmpAjaxRequest={
+ versionID:inputArg.item.versionID
+ }
+ $rootScope.EnsureModal(tmpModal.title, null, '配置发布立即生效,确定对各节点发布配置?', {
+ btnType:2,
+ btnMessage:"确定"
+ }, function (callback) {
+ if (callback) {
+ GatewayResource.Version.Publish(tmpAjaxRequest).$promise.then(function (response) {
+ switch (response.statusCode) {
+ case CODE.COMMON.SUCCESS: {
+ vm.fun.init();
+ $rootScope.InfoModal(tmpModal.title + '成功', 'success');
+ break;
+ }
+ }
+ })
+ }
+ });
+ }
+ privateFun.delete = function (inputArg) {
+ let tmpAjaxRequest = {
+ ids: inputArg.status == 'batch' ? vm.data.batch.query : [inputArg.item.versionID]
+ },
+ tmpModal = {
+ title: "删除配置"
+ };
+ $rootScope.EnsureModal(tmpModal.title, null, '确认删除配置?', {}, function (callback) {
+ if (callback) {
+ tmpAjaxRequest.ids=JSON.stringify(tmpAjaxRequest.ids);
+ GatewayResource.Version.Delete(tmpAjaxRequest).$promise.then(function (response) {
+ switch (response.statusCode) {
+ case CODE.COMMON.SUCCESS: {
+ switch (inputArg.status) {
+ case 'batch': {
+ privateFun.resetBatchInfo();
+ vm.fun.init();
+ break;
+ }
+ case 'single': {
+ vm.ajaxResponse.query.splice(inputArg.$index, 1);
+ break;
+ }
+ }
+ $rootScope.InfoModal(tmpModal.title + '成功', 'success');
+ break;
+ }
+ }
+ })
+ }
+ });
+ }
+ privateFun.resetBatchInfo = function () {
+ vm.data.batch.isOperating = false;
+ vm.data.batch.selectAll = false;
+ vm.data.batch.query = [];
+ vm.data.batch.indexAddress = {};
+ vm.ajaxResponse.query=cache.publishQuery.concat(vm.ajaxResponse.query);
+ };
+ privateFun.search = function (arg) {
+ window.sessionStorage.setItem('COMMON_SEARCH_TIP', arg.item.keyword);
+ $state.reload($state.current.name);
+ }
+ vm.$onInit = function () {
+ $scope.$emit('$WindowTitleSet', {
+ list: ['配置列表']
+ });
+ vm.component.listDefaultCommonObject = {
+ item: {
+ primaryKey: 'versionID',
+ resource: GatewayResource.Version,
+ default: [{
+ key: '状态',
+ html: `
{{item.publishStatus?"已发布":"未发布"}} `,
+ class: 'w_80'
+ },{
+ key: '名称',
+ html: '{{item.name}}',
+ contentClass: 'item-title-li'
+ },{
+ key: '版本号',
+ html: '{{item.version}}',
+ contentClass: 'item-title-li'
+ },{
+ key: '备注',
+ html: '{{item.remark}}',
+ contentClass: 'item-title-li'
+ },
+ {
+ key: '保存时间',
+ html: '{{item.createTime}}',
+ class: 'w_150'
+ },
+ {
+ key: '发布时间',
+ html: '{{item.publishTime}}',
+ class: 'w_150',
+ isUnneccessary: true
+ }
+ ],
+ operate: {
+ funArr: [{
+ key: '发布',
+ fun: privateFun.publish,
+ itemExpression:`ng-disabled="item.publishStatus"`
+ },
+ {
+ key: '删除',
+ fun: privateFun.delete,
+ itemExpression:`ng-disabled="item.publishStatus"`,
+ params: {
+ status: 'single'
+ }
+ }
+ ],
+ class: 'w_150'
+ }
+ },
+ setting: {
+ batch: true,
+ warning: '尚未生成任何配置',
+ defaultFoot: true,
+ unhover:true
+ }
+ }
+ vm.component.menuObject = {
+ list: [{
+ type: 'btn',
+ authority: 'edit',
+ class: 'pull-left',
+ btnList: [{
+ name: '生成配置',
+ icon: 'jiahao',
+ class: 'eo_theme_btn_success block-btn',
+ fun: {
+ default: privateFun.generateConf,
+ params: {
+ status: 'add'
+ }
+ }
+ }]
+ }, {
+ type: 'search',
+ class: 'pull-right mr15',
+ keyword: vm.ajaxRequest.keyword,
+ fun: privateFun.search,
+ placeholder: "输入搜索内容"
+ }
+ ],
+ batchList: [{
+ type: 'btn',
+ disabledPoint: 'isBatchSelected',
+ class: 'pull-left',
+ btnList: [{
+ name: '删除',
+ icon: 'shanchu',
+ disabled: false,
+ fun: {
+ default: privateFun.delete,
+ params: {
+ status: 'batch'
+ }
+ }
+ }]
+ }],
+ baseFun: {
+ batchDefault: () => {
+ if(vm.data.alreadyHadPublishConf){
+ cache.publishQuery=[vm.ajaxResponse.query.shift()]
+ }
+ }
+ },
+ setting: {
+ batch: true,
+ batchInitFun: privateFun.resetBatchInfo,
+ class: "common-menu-fixed-seperate common-menu-lg",
+ title: "配置管理",
+ secondTitle:"网关的配置内容支持版本管理,可以对配置进行发布和回滚
注意:配置发布后会立即生效,请谨慎操作",
+ titleAuthority: "showTitle"
+ }
+ }
+ }
+ }
+})();
\ No newline at end of file
diff --git a/console/static/src/app/ui/content/publish/index.scss b/console/static/src/app/ui/content/publish/index.scss
new file mode 100644
index 0000000000000000000000000000000000000000..f99b5794be0a851adc7f437a255a412c85bf7261
--- /dev/null
+++ b/console/static/src/app/ui/content/publish/index.scss
@@ -0,0 +1,11 @@
+publish {
+ menu-Default-Common-Component .common_menu_ul .search-form {
+ position: absolute;
+ right: 20px;
+ bottom: 20px;
+ height: auto;
+ }
+ menu-Default-Common-Component .can-operate-has-second-title-placeholder{
+ height: 190px;
+ }
+}
\ No newline at end of file
diff --git a/console/static/src/app/ui/content/setting/basic/index.html b/console/static/src/app/ui/content/setting/basic/index.html
deleted file mode 100644
index 705c7355518c0c0f471e0e45c303a0f429dddc03..0000000000000000000000000000000000000000
--- a/console/static/src/app/ui/content/setting/basic/index.html
+++ /dev/null
@@ -1,43 +0,0 @@
-
\ No newline at end of file
diff --git a/console/static/src/app/ui/content/setting/basic/index.js b/console/static/src/app/ui/content/setting/basic/index.js
deleted file mode 100644
index 1ad184cfba0995fdd83ec79e8107ca59f08decc6..0000000000000000000000000000000000000000
--- a/console/static/src/app/ui/content/setting/basic/index.js
+++ /dev/null
@@ -1,99 +0,0 @@
-(function () {
- 'use strict';
- /*
- * author:广州银云信息科技有限公司
- * 网关设置,基础配置相关js
- */
- angular.module('eolinker')
- .component('settingBasic', {
- templateUrl: 'app/ui/content/setting/basic/index.html',
- controller: indexController
- })
-
- indexController.$inject = ['$rootScope', 'CODE', 'GatewayResource','$scope','Authority_CommonService'];
-
- function indexController($rootScope, CODE, GatewayResource,$scope,Authority_CommonService) {
- var vm = this;
- vm.data = {
- status: {
- config: {
- isEdit: false
- }
- },
- userEmail: [{
- value: ''
- }]
- }
- vm.interaction = {
- response: {
- gatewayConfig: {}
- }
- }
- vm.fun = {};
- vm.constant = {
- monitorUpdatePeriodQuery: [{
- key: '30秒',
- value: 30
- }, {
- key: '60秒',
- value: 60
- }, {
- key: '180秒',
- value: 180
- }]
- }
- var data = {
- template: {
- gatewayConfig: {}
- }
- }
- vm.service={
- authority:Authority_CommonService
- }
- vm.fun.editBasicInfo = function () {
- vm.data.status.config.submitted = true;
- if ($scope.BasicForm.$invalid) return;
- var template = {
- request: {
- successCode: vm.interaction.response.gatewayConfig.successCode,
- monitorUpdatePeriod: vm.interaction.response.gatewayConfig.monitorUpdatePeriod,
- nodeUpdatePeriod: vm.interaction.response.gatewayConfig.nodeUpdatePeriod
- }
- }
- GatewayResource.Config.BaseEdit(template.request).$promise.then(function (response) {
- switch (response.statusCode) {
- case CODE.COMMON.SUCCESS:
- {
- $rootScope.InfoModal('修改成功!', 'success');
- vm.data.status.config.isEdit = false;
- angular.copy(vm.interaction.response.gatewayConfig, data.template.gatewayConfig);
- break;
- }
- }
- })
- }
- vm.fun.cancleBasicInfo = function () {
- vm.data.status.config.isEdit = false;
- vm.interaction.response.gatewayConfig = angular.copy(data.template.gatewayConfig);
- }
- vm.$onInit = function () {
- $scope.$emit('$WindowTitleSet', {
- list: ['基本设置','网关设置']
- });
- GatewayResource.Config.BaseInfo().$promise.then(function (response) {
- switch (response.statusCode) {
- case CODE.COMMON.SUCCESS:
- {
- vm.interaction.response.gatewayConfig = {
- successCode: response.gatewayConfig.successCode,
- monitorUpdatePeriod: response.gatewayConfig.monitorUpdatePeriod,
- nodeUpdatePeriod: response.gatewayConfig.nodeUpdatePeriod
- }
- angular.copy(vm.interaction.response.gatewayConfig, data.template.gatewayConfig);
- break;
- }
- }
- })
- };
- }
-})();
\ No newline at end of file
diff --git a/console/static/src/app/ui/content/setting/index.router.js b/console/static/src/app/ui/content/setting/index.router.js
index b2709222fffda77573b7a846dac1a21c41fa2206..783c7f6545dd127b4a996cfc1839199c141fcd85 100644
--- a/console/static/src/app/ui/content/setting/index.router.js
+++ b/console/static/src/app/ui/content/setting/index.router.js
@@ -13,10 +13,6 @@
.state('home.setting.log', {
url: '/log',
template: '
'
- })
- .state('home.setting.basic', {
- url: '/',
- template: '
'
});
}])
})()
\ No newline at end of file
diff --git a/console/static/src/app/ui/navbar/nav1/index.html b/console/static/src/app/ui/navbar/nav1/index.html
index 98b8720d350f0f4a51db4b606dceac2fd007db12..a1f50691675c15f932a7cdefae59445c070487f7 100644
--- a/console/static/src/app/ui/navbar/nav1/index.html
+++ b/console/static/src/app/ui/navbar/nav1/index.html
@@ -14,7 +14,8 @@
-
+
{{$ctrl.data.userInfo.remark||$ctrl.data.userInfo.loginCall||' '}}
= 'a' && ch <= 'z') ||
-// (ch >= 'A' && ch <= 'Z') ||
-// (ch >= '0' && ch <= '9') ||
-// ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
-// return true
-// }
-// }
-// return false
-//}
func (f *AccessLogFormatter) appendValue(b *bytes.Buffer, value interface{}) {
stringVal, ok := value.(string)
if !ok {
@@ -81,6 +72,8 @@ func (f *AccessLogFormatter) appendValue(b *bytes.Buffer, value interface{}) {
// b.WriteString(fmt.Sprintf("%q", stringVal))
//}
}
+
+//NewAccessLogFormatter 创建AccessLogFormatter
func NewAccessLogFormatter(fields []access_field.AccessFieldKey) *AccessLogFormatter {
return &AccessLogFormatter{fields: fields}
}
diff --git a/goku-node/access-log/log.go b/goku-node/access-log/log.go
index 9df461d90c6e469b87949b8da0cbb7ec5bbc171a..15af67e7782155de034c4bd055bac36849b6bcdb 100644
--- a/goku-node/access-log/log.go
+++ b/goku-node/access-log/log.go
@@ -1,10 +1,11 @@
package access_log
import (
+ "time"
+
log "github.com/eolinker/goku-api-gateway/goku-log"
access_field "github.com/eolinker/goku-api-gateway/server/access-field"
"github.com/sirupsen/logrus"
- "time"
)
var (
@@ -13,14 +14,10 @@ var (
writer *log.FileWriterByPeriod
)
-//func InitLogger(enable bool,fields []string,dir,file string,period log.LogPeriod) {
-//
-// SetFields(fields)
-// SetOutput(enable,dir,file,period)
-//
-//}
+//Fields 域
type Fields = logrus.Fields
+//Log log
func Log(fields Fields) {
if logger == nil {
return
@@ -28,6 +25,7 @@ func Log(fields Fields) {
logger.WithFields(fields).Info()
}
+//SetFields 设置access域
func SetFields(fields []access_field.AccessFieldKey) {
if formatter == nil {
formatter = NewAccessLogFormatter(fields)
@@ -35,6 +33,8 @@ func SetFields(fields []access_field.AccessFieldKey) {
formatter.SetFields(fields)
}
}
+
+//SetOutput 设置输出
func SetOutput(enable bool, dir, file string, period log.LogPeriod, expire int) {
if enable {
diff --git a/goku-node/cmd/cluster.go b/goku-node/cmd/cluster.go
deleted file mode 100644
index 5415fd5a9fe6214611185dd6590c332cd003ebfe..0000000000000000000000000000000000000000
--- a/goku-node/cmd/cluster.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package cmd
-
-import "github.com/eolinker/goku-api-gateway/server/entity"
-
-//CMD cmd
-type CMD struct {
- StatusCode string `json:"statuscode"`
-}
-
-//ClusterConfig clusterConfig
-type ClusterConfig struct {
- CMD
- Cluster *entity.ClusterInfo `json:"cluster"`
-}
diff --git a/goku-node/cmd/config.go b/goku-node/cmd/config.go
deleted file mode 100644
index 4bf5f08b478c354221bb46783fb0f0cb49bacf23..0000000000000000000000000000000000000000
--- a/goku-node/cmd/config.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package cmd
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- log "github.com/eolinker/goku-api-gateway/goku-log"
- node_common "github.com/eolinker/goku-api-gateway/goku-node/node-common"
- "github.com/eolinker/goku-api-gateway/server/entity"
- "io/ioutil"
- "net/http"
- "time"
-)
-
-//GetConfig 获取节点配置
-func GetConfig(listenPort int) (bool, *entity.ClusterInfo) {
- client := &http.Client{
- Timeout: time.Second * 10,
- }
- addr := node_common.GetAdminURL(fmt.Sprintf("/register?port=%d", listenPort))
- reader := bytes.NewReader([]byte(""))
- request, err := http.NewRequest("GET", addr, reader)
- if err != nil {
- return false, nil
- }
- // request.Header.Set("Content-Type", "application/json;charset=UTF-8")
- resp, err := client.Do(request)
- if err != nil {
- log.Info(err)
- return false, nil
- }
- defer resp.Body.Close()
- if resp.StatusCode != 200 {
- errReason := "[Error] Fail to match code!"
- log.Info(errReason)
- return false, nil
- }
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- log.Info(err)
- return false, nil
- }
- content := new(ClusterConfig)
- err = json.Unmarshal(body, &content)
- if err != nil {
- log.Info(err)
- return false, nil
- }
- if content.StatusCode != "000000" {
- errReason := "[Error] Fail to match status code!"
- log.Info(errReason)
- return false, nil
- }
- return true, content.Cluster
-}
diff --git a/goku-node/cmd/heartbeat.go b/goku-node/cmd/heartbeat.go
deleted file mode 100644
index f4a9b6eab731e82508306af182059e624af1f790..0000000000000000000000000000000000000000
--- a/goku-node/cmd/heartbeat.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package cmd
-
-import (
- "fmt"
- log "github.com/eolinker/goku-api-gateway/goku-log"
- node_common "github.com/eolinker/goku-api-gateway/goku-node/node-common"
- "net/http"
-
- "time"
-)
-
-//HeartBeatProid heartBeatProid
-const HeartBeatProid = time.Second * 5
-
-var (
- serverPort = 0
- closeChan chan bool
-)
-
-//Heartbeat heartBeat
-func Heartbeat(port int) {
- closeChan = make(chan bool)
- serverPort = port
- tick := time.NewTicker(HeartBeatProid)
- defer tick.Stop()
- for {
- select {
- case <-tick.C:
- {
- sendHeartBeat(port)
- }
-
- case <-closeChan:
- {
- return
- }
- }
- }
-}
-
-func sendHeartBeat(port int) {
- addr := node_common.GetAdminURL(fmt.Sprintf("node/heartbeat?port=%d", port))
- r, err := http.Get(addr)
- if err != nil {
- log.Warn("fail to send heartbeat:", err)
- return
- }
- e:=r.Body.Close()
- if e!=nil{
- log.Warn("close response error:", err)
- return
- }
-}
-
-//StopNode stopNode
-func StopNode() {
- close(closeChan)
-
- log.Debug("stop node")
- addr := node_common.GetAdminURL(fmt.Sprintf("node/stop?port=%d", serverPort))
- _, err := http.Get(addr)
- if err != nil {
- log.Warn("fail to send heartbeat:", err)
- }
-}
diff --git a/goku-node/cmd/request.go b/goku-node/cmd/request.go
deleted file mode 100644
index 11fa123190adf9584a94b891bb7f5dd3852dea19..0000000000000000000000000000000000000000
--- a/goku-node/cmd/request.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package cmd
-
-import (
- "errors"
- "io/ioutil"
- "net/http"
- "net/url"
- "strconv"
- "strings"
- "time"
-
- node_common "github.com/eolinker/goku-api-gateway/goku-node/node-common"
-)
-
-//AddAlertMessage 新增报警信息
-func AddAlertMessage(apiID int, apiName, requestURL, targetServer, targetURL, requestMethod, proxyMethod, headerList, queryParamList, formParamList, responseHeaderList string, alertPeriodType, alertCount, responseStatus int, isAlert string, strategyID string, strategyName, requestID string) (bool, string, error) {
- client := &http.Client{
- Timeout: time.Millisecond * 700,
- }
- var data = url.Values{}
- data.Add("requestID", requestID)
- data.Add("apiID", strconv.Itoa(apiID))
- data.Add("apiName", apiName)
- data.Add("requestURL", requestURL)
- data.Add("targetServer", targetServer)
- data.Add("targetURL", targetURL)
- data.Add("clusterName", node_common.ClusterName())
- data.Add("requestMethod", requestMethod)
- data.Add("proxyMethod", proxyMethod)
- data.Add("headerList", headerList)
- data.Add("queryParamList", queryParamList)
- data.Add("formParamList", formParamList)
- data.Add("responseHeaderList", responseHeaderList)
- data.Add("alertPeriodType", strconv.Itoa(alertPeriodType))
- data.Add("alertCount", strconv.Itoa(alertCount))
- data.Add("responseStatus", strconv.Itoa(responseStatus))
- data.Add("isAlert", isAlert)
- data.Add("strategyID", strategyID)
- data.Add("strategyName", strategyName)
- data.Add("nodePort", strconv.Itoa(node_common.ListenPort))
- request, err := http.NewRequest("POST", node_common.GetAdminURL("/alert/msg/add"), strings.NewReader(data.Encode()))
- request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
- if err != nil {
-
- return false, "[ERROR]Fail to create request!", err
- }
- response, err := client.Do(request)
- if err != nil {
-
- return false, "[ERROR]Fail to get response!", err
- }
- defer response.Body.Close()
- _, err = ioutil.ReadAll(response.Body)
- if err != nil {
-
- return false, "[ERROR]Fail to get body!", err
- }
-
- return true, "", nil
-}
-
-//SendRequestToAlertAddress 发送告警请求
-func SendRequestToAlertAddress(alertAddress, requestURL, targetServer, proxyURL, msg, apiName string, apiID int) (bool, string, error) {
- if alertAddress == "" {
- return false, "[ERROR] Illegal alertAddress!", errors.New("[error] illegal alertAddress")
- }
- _, err := url.Parse(alertAddress)
- if err != nil {
- return false, err.Error(), err
- }
- client := &http.Client{
- Timeout: time.Millisecond * 700,
- }
- now := time.Now().Format("2006-01-02 15:04:05")
- var data = url.Values{}
- data.Add("requestURL", requestURL)
- data.Add("targetServer", targetServer)
- data.Add("targetURL", proxyURL)
- data.Add("alertTime", now)
- data.Add("apiName", apiName)
- data.Add("apiID", strconv.Itoa(apiID))
- data.Add("msg", msg)
- request, err := http.NewRequest("POST", alertAddress, strings.NewReader(data.Encode()))
- request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
- if err != nil {
- return false, "[ERROR]Fail to create request!", err
- }
- _, err = client.Do(request)
- if err != nil {
- return false, "[ERROR]Fail to get response!", err
- }
- return true, "", nil
-}
diff --git a/goku-node/common/body-request.go b/goku-node/common/body-request.go
index 6eb64d0d3dd88930c70514cc2e82262b4f7cf682..2153fb69b0b4291d704f54f3656e869c52793e5c 100644
--- a/goku-node/common/body-request.go
+++ b/goku-node/common/body-request.go
@@ -2,6 +2,8 @@ package common
import (
"bytes"
+ "encoding/json"
+ "encoding/xml"
"errors"
goku_plugin "github.com/eolinker/goku-plugin"
@@ -16,24 +18,26 @@ import (
const defaultMultipartMemory = 32 << 20 // 32 MB
var (
- errNotForm = errors.New("contentType is not Form")
- errNotMultipart = errors.New("contentType is not Multipart")
- errNotAllowRaw = errors.New("contentType is not allow Raw")
+ errorNotForm = errors.New("contentType is not Form")
+ errorNotMultipart = errors.New("contentType is not Multipart")
+ errorNotAllowRaw = errors.New("contentType is not allow Raw")
)
-//BodyRequestHandler body request handler
+//BodyRequestHandler body请求处理器
type BodyRequestHandler struct {
form url.Values
- rawbody []byte
+ rawBody []byte
orgContentParam map[string]string
contentType string
files map[string]*goku_plugin.FileHeader
isInit bool
isWriteRaw bool
+
+ object interface{}
}
-//Files files
+//Files 获取文件参数
func (b *BodyRequestHandler) Files() (map[string]*goku_plugin.FileHeader, error) {
err := b.Parse()
@@ -45,7 +49,7 @@ func (b *BodyRequestHandler) Files() (map[string]*goku_plugin.FileHeader, error)
}
-//Parse parse
+//Parse 解析
func (b *BodyRequestHandler) Parse() error {
if b.isInit {
@@ -55,9 +59,25 @@ func (b *BodyRequestHandler) Parse() error {
contentType, _, _ := mime.ParseMediaType(b.contentType)
switch contentType {
+ case goku_plugin.JSON:
+ {
+ e := json.Unmarshal(b.rawBody, &b.object)
+ if e != nil {
+ return e
+ }
+ }
+ case goku_plugin.AppLicationXML, goku_plugin.TextXML:
+ {
+ e := xml.Unmarshal(b.rawBody, &b.object)
+ if e != nil {
+ return e
+ }
+
+ }
+
case goku_plugin.MultipartForm:
{
- r, err := multipartReader(b.contentType, false, b.rawbody)
+ r, err := multipartReader(b.contentType, false, b.rawBody)
if err != nil {
return err
}
@@ -93,20 +113,25 @@ func (b *BodyRequestHandler) Parse() error {
}
}
}
+
+ b.object = b.form
}
case goku_plugin.FormData:
{
- form, err := url.ParseQuery(string(b.rawbody))
+ form, err := url.ParseQuery(string(b.rawBody))
if err != nil {
return err
}
if b.form == nil {
- b.form = form
+
+ b.object = form
} else {
for k, v := range form {
b.form[k] = append(b.form[k], v...)
}
+
}
+ b.object = b.form
}
}
@@ -114,7 +139,7 @@ func (b *BodyRequestHandler) Parse() error {
return nil
}
-//GetForm get form
+//GetForm 获取表单参数
func (b *BodyRequestHandler) GetForm(key string) string {
contentType, _, _ := mime.ParseMediaType(b.contentType)
@@ -129,7 +154,7 @@ func (b *BodyRequestHandler) GetForm(key string) string {
return b.form.Get(key)
}
-//GetFile getFile
+//GetFile 获取文件参数
func (b *BodyRequestHandler) GetFile(key string) (file *goku_plugin.FileHeader, has bool) {
contentType, _, _ := mime.ParseMediaType(b.contentType)
@@ -149,12 +174,12 @@ func (b *BodyRequestHandler) GetFile(key string) (file *goku_plugin.FileHeader,
return f, has
}
-//SetToForm setToForm
+//SetToForm 设置表单参数
func (b *BodyRequestHandler) SetToForm(key, value string) error {
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
- return errNotForm
+ return errorNotForm
}
err := b.Parse()
@@ -172,11 +197,11 @@ func (b *BodyRequestHandler) SetToForm(key, value string) error {
return nil
}
-//AddForm addForm
+//AddForm 新增表单参数
func (b *BodyRequestHandler) AddForm(key, value string) error {
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
- return errNotForm
+ return errorNotForm
}
err := b.Parse()
if err != nil {
@@ -191,12 +216,12 @@ func (b *BodyRequestHandler) AddForm(key, value string) error {
return nil
}
-//AddFile 新建文件参数
+//AddFile 新增文件参数
func (b *BodyRequestHandler) AddFile(key string, file *goku_plugin.FileHeader) error {
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
- return errNotMultipart
+ return errorNotMultipart
}
err := b.Parse()
if err != nil {
@@ -215,21 +240,19 @@ func (b *BodyRequestHandler) AddFile(key string, file *goku_plugin.FileHeader) e
return nil
}
-//Clone 请求克隆
+//Clone 克隆body
func (b *BodyRequestHandler) Clone() *BodyRequestHandler {
-
rawbody, _ := b.RawBody()
-
return NewBodyRequestHandler(b.contentType, rawbody)
}
-//ContentType contentType
+//ContentType 获取contentType
func (b *BodyRequestHandler) ContentType() string {
return b.contentType
}
-//BodyForm 获取body参数
+//BodyForm 获取表单参数
func (b *BodyRequestHandler) BodyForm() (url.Values, error) {
err := b.Parse()
@@ -239,12 +262,33 @@ func (b *BodyRequestHandler) BodyForm() (url.Values, error) {
return b.form, nil
}
+//BodyInterface 获取请求体对象
+func (b *BodyRequestHandler) BodyInterface() (interface{}, error) {
+ err := b.Parse()
+ if err != nil {
+ return nil, err
+ }
+
+ return b.object, nil
+}
+
+//RawBody 获取raw数据
+func (b *BodyRequestHandler) RawBody() ([]byte, error) {
+
+ err := b.Encode()
+ if err != nil {
+ return nil, err
+ }
+ return b.rawBody, nil
+
+}
+
//Encode encode
func (b *BodyRequestHandler) Encode() error {
if b.isWriteRaw {
return nil
-
}
+
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
b.isWriteRaw = true
@@ -255,8 +299,8 @@ func (b *BodyRequestHandler) Encode() error {
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
- for fieldname, file := range b.files {
- part, err := writer.CreateFormFile(fieldname, file.FileName)
+ for name, file := range b.files {
+ part, err := writer.CreateFormFile(name, file.FileName)
if err != nil {
return err
}
@@ -266,11 +310,11 @@ func (b *BodyRequestHandler) Encode() error {
}
}
- for fieldname, values := range b.form {
+ for key, values := range b.form {
temp := make(url.Values)
- temp[fieldname] = values
+ temp[key] = values
value := temp.Encode()
- err := writer.WriteField(fieldname, value)
+ err := writer.WriteField(key, value)
if err != nil {
return err
}
@@ -280,35 +324,24 @@ func (b *BodyRequestHandler) Encode() error {
return err
}
b.contentType = writer.FormDataContentType()
- b.rawbody = body.Bytes()
+ b.rawBody = body.Bytes()
b.isWriteRaw = true
} else {
if b.form != nil {
- b.rawbody = []byte(b.form.Encode())
+ b.rawBody = []byte(b.form.Encode())
} else {
- b.rawbody = make([]byte, 0, 0)
+ b.rawBody = make([]byte, 0, 0)
}
}
return nil
}
-//RawBody rawBody
-func (b *BodyRequestHandler) RawBody() ([]byte, error) {
-
- err := b.Encode()
- if err != nil {
- return nil, err
- }
- return b.rawbody, nil
-
-}
-
//SetForm 设置表单参数
func (b *BodyRequestHandler) SetForm(values url.Values) error {
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
- return errNotForm
+ return errorNotForm
}
b.Parse()
b.form = values
@@ -322,7 +355,7 @@ func (b *BodyRequestHandler) SetFile(files map[string]*goku_plugin.FileHeader) e
contentType, _, _ := mime.ParseMediaType(b.contentType)
if contentType != goku_plugin.FormData && contentType != goku_plugin.MultipartForm {
- return errNotForm
+ return errorNotForm
}
b.Parse()
b.files = files
@@ -332,10 +365,10 @@ func (b *BodyRequestHandler) SetFile(files map[string]*goku_plugin.FileHeader) e
return nil
}
-//SetRaw 设置Raw
+//SetRaw 设置raw数据
func (b *BodyRequestHandler) SetRaw(contentType string, body []byte) {
- b.rawbody, b.contentType, b.isInit, b.isWriteRaw = body, contentType, false, true
+ b.rawBody, b.contentType, b.isInit, b.isWriteRaw = body, contentType, false, true
_, b.orgContentParam, _ = mime.ParseMediaType(contentType)
return
diff --git a/goku-node/common/body.go b/goku-node/common/body.go
index a7402828981a3d81acddcb258ec23edb2258ff15..de56ebb0a02c5a291731e7e2a8b9c99bc899e276 100644
--- a/goku-node/common/body.go
+++ b/goku-node/common/body.go
@@ -1,6 +1,6 @@
package common
-//BodyHandler body处理器
+//BodyHandler 请求体处理器
type BodyHandler struct {
body []byte
}
@@ -18,7 +18,7 @@ func (r *BodyHandler) SetBody(body []byte) {
r.body = body
}
-//NewBodyHandler 创建body处理器
+//NewBodyHandler 创建BodyHandler
func NewBodyHandler(body []byte) *BodyHandler {
return &BodyHandler{body: body}
}
diff --git a/goku-node/common/context.go b/goku-node/common/context.go
index 89e6c148e881115f478f62a14956b63fdb6158c3..d4faa168ded58c968b67b2e28b01f0c3d9af797f 100644
--- a/goku-node/common/context.go
+++ b/goku-node/common/context.go
@@ -4,6 +4,8 @@ import (
"net/http"
"strconv"
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+
goku_plugin "github.com/eolinker/goku-plugin"
)
@@ -26,29 +28,32 @@ type Context struct {
requestID string
finalTargetServer string
retryTargetServers string
+
+ RestfulParam map[string]string
+ LogFields log.Fields
}
-//FinalTargetServer 获取最终目标转发服务器
+//FinalTargetServer 获取最终转发服务器地址
func (ctx *Context) FinalTargetServer() string {
return ctx.finalTargetServer
}
-//SetFinalTargetServer 设置最终目标服务器
+//SetFinalTargetServer 设置最终转发地址
func (ctx *Context) SetFinalTargetServer(finalTargetServer string) {
ctx.finalTargetServer = finalTargetServer
}
-//RetryTargetServers 重试目标服务器
+//RetryTargetServers 重试转发地址
func (ctx *Context) RetryTargetServers() string {
return ctx.retryTargetServers
}
-//SetRetryTargetServers 设置重试目标服务器
+//SetRetryTargetServers 设置重试地址
func (ctx *Context) SetRetryTargetServers(retryTargetServers string) {
ctx.retryTargetServers = retryTargetServers
}
-//Finish 请求结束
+//Finish finish
func (ctx *Context) Finish() (n int, statusCode int) {
header := ctx.PriorityHeader.header
@@ -106,12 +111,12 @@ func (ctx *Context) Finish() (n int, statusCode int) {
return n, statusCode
}
-//RequestId 获取请求ID
+//RequestId 请求ID
func (ctx *Context) RequestId() string {
return ctx.requestID
}
-//NewContext 创建context
+//NewContext 创建Context
func NewContext(r *http.Request, requestID string, w http.ResponseWriter) *Context {
requestreader := NewRequestReader(r)
return &Context{
@@ -124,19 +129,25 @@ func NewContext(r *http.Request, requestID string, w http.ResponseWriter) *Conte
ProxyResponseHandler: nil,
requestID: requestID,
w: w,
+ LogFields: make(log.Fields),
}
}
//SetProxyResponse 设置转发响应
func (ctx *Context) SetProxyResponse(response *http.Response) {
- ctx.ProxyResponseHandler = newResponseReader(response)
+ ctx.SetProxyResponseHandler(newResponseReader(response))
+
+}
+
+//SetProxyResponseHandler 设置转发响应处理器
+func (ctx *Context) SetProxyResponseHandler(response *ResponseReader) {
+ ctx.ProxyResponseHandler = response
if ctx.ProxyResponseHandler != nil {
ctx.Body = ctx.ProxyResponseHandler.body
ctx.SetStatus(ctx.ProxyResponseHandler.StatusCode(), ctx.ProxyResponseHandler.Status())
ctx.header = ctx.ProxyResponseHandler.header
}
-
}
func (ctx *Context) Write(w http.ResponseWriter) {
if ctx.StatusCode() == 0 {
@@ -150,17 +161,17 @@ func (ctx *Context) Write(w http.ResponseWriter) {
}
-//GetBody 获取body内容
+//GetBody 获取请求body
func (ctx *Context) GetBody() []byte {
return ctx.Body
}
-//SetBody 设置body内容
+//SetBody 设置body
func (ctx *Context) SetBody(data []byte) {
ctx.Body = data
}
-//ProxyResponse 转发响应
+//ProxyResponse 返回响应
func (ctx *Context) ProxyResponse() goku_plugin.ResponseReader {
return ctx.ProxyResponseHandler
}
@@ -191,16 +202,16 @@ func (ctx *Context) ApiID() int {
}
//SetAPIID 设置接口ID
-func (ctx *Context) SetAPIID(apiID int) {
- ctx.apiID = apiID
+func (ctx *Context) SetAPIID(apiId int) {
+ ctx.apiID = apiId
}
-//Request 获取请求原始数据
+//Request 获取原始请求
func (ctx *Context) Request() goku_plugin.RequestReader {
return ctx.RequestOrg
}
-//Proxy 获取代理请求
+//Proxy 代理
func (ctx *Context) Proxy() goku_plugin.Request {
return ctx.ProxyRequest
}
diff --git a/goku-node/common/cookies.go b/goku-node/common/cookies.go
index 8ecf4eb40c1f8eac0899d0aa7a77109dd19f83a0..3ba45a8877fe59d779de74ed59bff4a037c15f68 100644
--- a/goku-node/common/cookies.go
+++ b/goku-node/common/cookies.go
@@ -7,7 +7,7 @@ type CookiesHandler struct {
req http.Request
}
-//AddCookie 新增cookie
+//AddCookie 新增cookiess
func (cs *CookiesHandler) AddCookie(c *http.Cookie) {
cs.req.AddCookie(c)
}
diff --git a/goku-node/common/header.go b/goku-node/common/header.go
index a522e9cb609116411b97af7cdbd26451d8a28d85..1c12b0fc262ade3904078a7a9507e5bb7e2ec5f5 100644
--- a/goku-node/common/header.go
+++ b/goku-node/common/header.go
@@ -1,9 +1,10 @@
package common
import (
- goku_plugin "github.com/eolinker/goku-plugin"
"net/http"
"net/url"
+
+ goku_plugin "github.com/eolinker/goku-plugin"
)
//Header header
@@ -11,7 +12,7 @@ type Header struct {
header http.Header
}
-//Headers 返回headers
+//Headers 获取头部
func (h *Header) Headers() http.Header {
n := make(http.Header)
@@ -23,42 +24,30 @@ func (h *Header) Headers() http.Header {
func (h *Header) String() string {
return url.Values(h.header).Encode()
- //buf:=bytes.NewBuffer(nil)
- //for k,v:=range h.header{
- // buf.WriteByte('&')
- // buf.WriteString(k)
- // buf.WriteString("=")
- // buf.WriteString(strings.Join(v,","))
- //
- //}
- //data:=buf.Bytes()
- //if len(data)>1{
- // data=data[1:]
- //}
- //return string(data)
+
}
-//SetHeader 设置请求头
+//SetHeader 设置请求头部
func (h *Header) SetHeader(key, value string) {
h.header.Set(key, value)
}
-//AddHeader 新增请求头
+//AddHeader 新增头部
func (h *Header) AddHeader(key, value string) {
h.header.Add(key, value)
}
-//DelHeader 删除请求头
+//DelHeader 删除头部
func (h *Header) DelHeader(key string) {
h.header.Del(key)
}
-//GetHeader 通过名字获取请求头
+//GetHeader 根据名称获取头部
func (h *Header) GetHeader(name string) string {
return h.header.Get(name)
}
-//NewHeader 创建header请求头
+//NewHeader 创建Header
func NewHeader(header http.Header) *Header {
if header == nil {
header = make(http.Header)
@@ -68,7 +57,7 @@ func NewHeader(header http.Header) *Header {
}
}
-//PriorityHeader proorityHeader
+//PriorityHeader priorityHeader
type PriorityHeader struct {
*Header
setHeader *Header
@@ -91,7 +80,7 @@ func (h *PriorityHeader) Append() goku_plugin.Header {
return h.setHeader
}
-//NewPriorityHeader 创建优先级header
+//NewPriorityHeader 创建PriorityHeader
func NewPriorityHeader() *PriorityHeader {
return &PriorityHeader{
Header: NewHeader(nil),
diff --git a/goku-node/common/request-reader.go b/goku-node/common/request-reader.go
index bd00b23ce1e064fbeb7dc2746a34cde47ea458ab..72ded1dd25be63dc4a5eec184bea3d6d7b71eda6 100644
--- a/goku-node/common/request-reader.go
+++ b/goku-node/common/request-reader.go
@@ -5,7 +5,7 @@ import (
"net/url"
)
-//RequestReader 请求header
+//RequestReader 请求reader
type RequestReader struct {
*Header
*BodyRequestHandler
@@ -17,7 +17,7 @@ func (r *RequestReader) Proto() string {
return r.req.Proto
}
-//NewRequestReader 获取新请求header
+//NewRequestReader 创建RequestReader
func NewRequestReader(req *http.Request) *RequestReader {
r := new(RequestReader)
r.req = req
@@ -39,8 +39,6 @@ func (r *RequestReader) ParseRequest() {
} else {
r.BodyRequestHandler = NewBodyRequestHandler(r.req.Header.Get("Content-Type"), nil)
}
-
- // todo
}
//Cookie 获取cookie
@@ -53,12 +51,12 @@ func (r *RequestReader) Cookies() []*http.Cookie {
return r.req.Cookies()
}
-//Method 获取方法
+//Method 获取请求方式
func (r *RequestReader) Method() string {
return r.req.Method
}
-//URL 获取URL
+//URL url
func (r *RequestReader) URL() *url.URL {
return r.req.URL
}
@@ -73,7 +71,7 @@ func (r *RequestReader) Host() string {
return r.req.Host
}
-//RemoteAddr 获取客户端地址
+//RemoteAddr 远程地址
func (r *RequestReader) RemoteAddr() string {
return r.req.RemoteAddr
}
diff --git a/goku-node/common/request.go b/goku-node/common/request.go
index 9048fe2ba50b10d1373b846f5df5b69c394dd347..acc938523849be565fc5339505529fa3f36443ac 100644
--- a/goku-node/common/request.go
+++ b/goku-node/common/request.go
@@ -13,7 +13,7 @@ type Request struct {
Method string
}
-//TargetURL 转发URL
+//TargetURL 获取转发url
func (r *Request) TargetURL() string {
return r.targetURL
}
@@ -28,7 +28,7 @@ func (r *Request) TargetServer() string {
return r.targetServer
}
-//SetTargetServer 设置转发服务器地址
+//SetTargetServer 设置最终转发地址
func (r *Request) SetTargetServer(targetServer string) {
r.targetServer = targetServer
}
@@ -38,7 +38,7 @@ func (r *Request) Querys() url.Values {
return r.querys
}
-//NewRequest 新请求
+//NewRequest 创建请求
func NewRequest(r *RequestReader) *Request {
if r == nil {
return nil
diff --git a/goku-node/common/response.go b/goku-node/common/response.go
index d56e6823ea3f75f214e41804b416846f0c4bbe05..ed34b9fda030ffa9812ee151b25bb43b328131cc 100644
--- a/goku-node/common/response.go
+++ b/goku-node/common/response.go
@@ -5,7 +5,7 @@ import (
"net/http"
)
-//ResponseReader 响应读取器
+//ResponseReader 响应结构体
type ResponseReader struct {
*CookiesHandler
*Header
@@ -33,3 +33,21 @@ func newResponseReader(response *http.Response) *ResponseReader {
return r
}
+
+//NewResponseReader 新增ResponseReader
+func NewResponseReader(header http.Header, statusCode int, status string, body []byte) *ResponseReader {
+ r := new(ResponseReader)
+ r.Header = NewHeader(header)
+ r.CookiesHandler = newCookieHandle(header)
+ r.StatusHandler = NewStatusHandler()
+ r.SetStatus(statusCode, status)
+ // if response.ContentLength > 0 {
+ // body, _ := ioutil.ReadAll(response.Body)
+ // r.BodyHandler = NewBodyHandler(body)
+ // } else {
+ // r.BodyHandler = NewBodyHandler(nil)
+ // }
+
+ r.BodyHandler = NewBodyHandler(body)
+ return r
+}
diff --git a/goku-node/common/status.go b/goku-node/common/status.go
index 5800a54062b6811a847d58358a402237cc5dce5e..166ac8675bb669d5893be582e3a7de265c456a65 100644
--- a/goku-node/common/status.go
+++ b/goku-node/common/status.go
@@ -1,12 +1,12 @@
package common
-//StatusHandler 状态码处理器
+//StatusHandler 状态处理器
type StatusHandler struct {
code int
status string
}
-//SetStatus 设置状态
+//SetStatus 设置状态信息
func (s *StatusHandler) SetStatus(code int, status string) {
s.code, s.status = code, status
}
@@ -16,12 +16,12 @@ func (s *StatusHandler) StatusCode() int {
return s.code
}
-//Status 获取状态描述
+//Status 获取状态
func (s *StatusHandler) Status() string {
return s.status
}
-//NewStatusHandler 创建状态处理器
+//NewStatusHandler 状态处理器
func NewStatusHandler() *StatusHandler {
return new(StatusHandler)
}
diff --git a/goku-node/common/store.go b/goku-node/common/store.go
index bd75052f9d74af87c39b81da3df720c7fdd48dac..90314ef92911bc88531ed25e688ada9a51eadf5b 100644
--- a/goku-node/common/store.go
+++ b/goku-node/common/store.go
@@ -2,7 +2,7 @@ package common
import goku_plugin "github.com/eolinker/goku-plugin"
-//Store 存储器
+//Store 存储
type Store struct {
value interface{}
}
@@ -17,14 +17,14 @@ func (s *Store) Get() (value interface{}) {
return s.value
}
-//StoreHandler 存储处理器
+//StoreHandler 存储器
type StoreHandler struct {
Cache map[string]interface{}
Stores map[string]goku_plugin.Store
CurrentPluginName string
}
-//SetPlugin 设置插件
+//SetPlugin 设置plugin
func (s *StoreHandler) SetPlugin(name string) {
s.CurrentPluginName = name
}
@@ -60,7 +60,7 @@ func (s *StoreHandler) Store() goku_plugin.Store {
return store
}
-//NewStoreHandler 创建存储处理器
+//NewStoreHandler 储存器
func NewStoreHandler() *StoreHandler {
return new(StoreHandler)
}
diff --git a/goku-node/driver.go b/goku-node/driver.go
deleted file mode 100644
index 384514236a172595212fa78730b3b314d7b3911a..0000000000000000000000000000000000000000
--- a/goku-node/driver.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package gokunode
-
-
-import (
- // 驱动加载
- _ "github.com/eolinker/goku-api-gateway/goku-node/manager/service-manager"
- _ "github.com/eolinker/goku-api-gateway/goku-service/driver/consul"
- _ "github.com/eolinker/goku-api-gateway/goku-service/driver/eureka"
- _ "github.com/eolinker/goku-api-gateway/goku-service/driver/static"
-)
diff --git a/goku-node/handler/handler.go b/goku-node/handler/handler.go
deleted file mode 100644
index 789eb2ce806bc9869b52b3355df5883411c95f34..0000000000000000000000000000000000000000
--- a/goku-node/handler/handler.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package handler
-
-import (
- "net/http"
-)
-
-//Entry entry
-type Entry struct {
- Pattern string
- HandlerFunc func(w http.ResponseWriter, r *http.Request)
-}
-
-func init() {
-
-}
-
-//Handler handler
-func Handler() []Entry {
-
- return []Entry{
- {
- Pattern: "/goku-update", HandlerFunc: gokuUpdate,
- },
- {
- Pattern: "/goku-check_update", HandlerFunc: gokuCheckUpdate},
- {
- Pattern: "/goku-check_plugin", HandlerFunc: gokuCheckPlugin},
- {
- Pattern: "/goku-monitor", HandlerFunc: gokuMonitor},
- }
-}
diff --git a/goku-node/handler/monitor.go b/goku-node/handler/monitor.go
deleted file mode 100644
index 3c77afbca14c157a745e6ecfee5c31cf7c12e481..0000000000000000000000000000000000000000
--- a/goku-node/handler/monitor.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package handler
-
-import "net/http"
-
-func gokuMonitor(w http.ResponseWriter, req *http.Request) {
- w.WriteHeader(200)
- return
-}
diff --git a/goku-node/handler/plugin.go b/goku-node/handler/plugin.go
deleted file mode 100644
index 2c75ae7b77050b010997fb3e09a362c0c5149400..0000000000000000000000000000000000000000
--- a/goku-node/handler/plugin.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package handler
-
-import (
- "encoding/json"
- log "github.com/eolinker/goku-api-gateway/goku-log"
-
- plugin_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/plugin-manager"
- "net/http"
-)
-
-func gokuCheckPlugin(w http.ResponseWriter, req *http.Request) {
- req.ParseForm()
- pluginName := req.PostFormValue("pluginName")
-
- code, e := plugin_manager.Check(pluginName)
-
- if code != plugin_manager.LoadOk {
- switch code {
- case plugin_manager.LoadFileError:
- log.Info(e)
- result := map[string]string{
- "statusCode": "210015",
- "type": "plugin",
- "resultDesc": "[GOKU] " + pluginName + ".so can not be found in plugin catalog",
- }
- resultByte, _ := json.Marshal(result)
- w.Write(resultByte)
- return
- case plugin_manager.LoadLookupError:
- log.Info(e)
- result := map[string]string{
- "statusCode": "210017",
- "type": "plugin",
- "resultDesc": "[GOKU] Object named '" + pluginName + "' can not be found in " + pluginName + ".so",
- }
- resultByte, _ := json.Marshal(result)
- w.Write(resultByte)
- case plugin_manager.LoadInterFaceError:
-
- result := map[string]string{
- "statusCode": "210016",
- "type": "plugin",
- "resultDesc": "[GOKU] Object named '" + pluginName + "' did not inherit necessary methods from utils.PluginHandle",
- }
- log.Info(result["resultDesc"])
- resultByte, _ := json.Marshal(result)
- w.Write(resultByte)
-
- }
- return
- }
- result := map[string]string{
- "statusCode": "000000",
- "type": "plugin",
- "resultDesc": "[GOKU]Success",
- }
- resultByte, _ := json.Marshal(result)
- w.Write(resultByte)
-
- return
-}
diff --git a/goku-node/handler/update.go b/goku-node/handler/update.go
deleted file mode 100644
index b8d0af97b03ea4c70f6b02ba6ac54434e41cccaf..0000000000000000000000000000000000000000
--- a/goku-node/handler/update.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package handler
-
-import (
- "encoding/json"
- v "github.com/eolinker/goku-api-gateway/common/version"
- "github.com/eolinker/goku-api-gateway/goku-node/manager/updater"
- "net/http"
-)
-
-func gokuUpdate(w http.ResponseWriter, r *http.Request) {
- updater.Update()
-}
-func gokuCheckUpdate(w http.ResponseWriter, r *http.Request) {
- resultInfo := map[string]interface{}{
- "type": "update",
- "statusCode": "000000",
- "version": v.Version,
- }
- resultStr, _ := json.Marshal(resultInfo)
-
- w.WriteHeader(200)
- _, _ = w.Write(resultStr)
- return
-}
diff --git a/goku-node/manager/api-manager/api.go b/goku-node/manager/api-manager/api.go
deleted file mode 100644
index b2452e5e161aee671fffc102ab272e42633799cd..0000000000000000000000000000000000000000
--- a/goku-node/manager/api-manager/api.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package apimanager
-
-import (
- "sync"
-
- "github.com/eolinker/goku-api-gateway/goku-node/manager/updater"
- dao_api "github.com/eolinker/goku-api-gateway/server/dao/node-mysql/dao-api"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-func init() {
- updater.Add(load, 5, "goku_gateway_api")
-}
-
-// apiList: api列表全局变量
-var (
- apiList map[int]*entity.API
- locker sync.RWMutex
-)
-
-//GetAPI 通过id获取API信息
-func GetAPI(id int) (*entity.API, bool) {
- locker.RLock()
- defer locker.RUnlock()
- a, has := apiList[id]
- return a, has
-}
-
-//GetAPIs 获取接口信息列表
-func GetAPIs(ids []int) []*entity.API {
-
- apis := make([]*entity.API, 0, len(ids))
-
- locker.RLock()
- defer locker.RUnlock()
- for _, id := range ids {
- if api, has := apiList[id]; has {
- apis = append(apis, api)
- }
- }
-
- return apis
-}
-
-func reset(list map[int]*entity.API) {
- locker.Lock()
- defer locker.Unlock()
- apiList = list
-}
-
-func load() {
- apis, e := dao_api.GetAllAPI()
- if e != nil {
- return
- }
- reset(apis)
-}
diff --git a/goku-node/manager/balance-manager/balance.go b/goku-node/manager/balance-manager/balance.go
deleted file mode 100644
index 6bf28c23349c87e3d06a05db84698a7c7cf40d72..0000000000000000000000000000000000000000
--- a/goku-node/manager/balance-manager/balance.go
+++ /dev/null
@@ -1,82 +0,0 @@
-package balancemanager
-
-import (
- "encoding/json"
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "github.com/eolinker/goku-api-gateway/goku-node/manager/updater"
- node_common "github.com/eolinker/goku-api-gateway/goku-node/node-common"
- "github.com/eolinker/goku-api-gateway/goku-service/application"
- "github.com/eolinker/goku-api-gateway/goku-service/balance"
- dao_balance "github.com/eolinker/goku-api-gateway/server/dao/node-mysql/dao-balance"
- "github.com/eolinker/goku-api-gateway/server/driver"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
- "strings"
-)
-
-func init() {
- updater.Add(loadBalanceInfo, 3, "goku_balance")
-}
-
-//Get get
-func Get(name string) (application.IHttpApplication, bool) {
-
- return balance.GetByName(name)
-}
-
-// 加载负载均衡信息
-func loadBalanceInfo() {
-
- balanceList, err := getAllBalance()
- if err != nil {
- log.Info(err)
- return
- }
-
- balance.ResetBalances(balanceList)
-}
-func genBalance(e *entity.Balance) *balance.Balance {
- b := &balance.Balance{
- Name: e.Name,
- Discovery: e.ServiceName,
- AppConfig: "",
- }
-
- switch e.ServiceType {
- case driver.Static:
- {
- var m map[string]string
- b.AppConfig = e.Static
- if err := json.Unmarshal([]byte(e.StaticCluster), &m); err == nil {
- if v, has := m[node_common.ClusterName()]; has {
- if len(strings.Trim(v, " ")) > 0 {
- b.AppConfig = v
- }
- }
- }
- return b
- }
- case driver.Discovery:
- {
- b.AppConfig = e.AppName
- return b
- }
-
- }
- return nil
-}
-func getAllBalance() ([]*balance.Balance, error) {
-
- entities, e := dao_balance.GetAllBalance()
- if e != nil {
- return nil, e
- }
- infos := make([]*balance.Balance, 0, len(entities))
-
- for _, ent := range entities {
- b := genBalance(ent)
- if b != nil {
- infos = append(infos, b)
- }
- }
- return infos, nil
-}
diff --git a/goku-node/manager/config-manager/field.go b/goku-node/manager/config-manager/field.go
deleted file mode 100644
index eee660d99b645950655f944b338b881cd7b4a807..0000000000000000000000000000000000000000
--- a/goku-node/manager/config-manager/field.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package configmanager
-
-//AccessField access字段
-type AccessField struct {
- Name string `json:"name"`
- Select bool `json:"select"`
-}
diff --git a/goku-node/manager/gateway-manager/gateway.go b/goku-node/manager/gateway-manager/gateway.go
deleted file mode 100644
index 2680136293e2aa7b458a2c2f8aea0c780b002d03..0000000000000000000000000000000000000000
--- a/goku-node/manager/gateway-manager/gateway.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package gatewaymanager
-
-import (
- "strconv"
- "strings"
- "sync"
-
- dao_gateway "github.com/eolinker/goku-api-gateway/server/dao/node-mysql/dao-gateway"
-)
-
-var (
- locker = sync.RWMutex{}
- _SuccessCode = "200"
- _UpdatePeriod = 5
- _AlertStatus = 0
- _AlertInfo = "{\"alertAddr\":\"\",\"alertPeriodType\":0,\"logPath\":\"./log/apiAlert\",\"receiverList\":\"\"}"
-)
-
-//GetUpdatePeriod 获取更新周期
-func GetUpdatePeriod() int {
- locker.RLock()
- defer locker.RUnlock()
- return _UpdatePeriod
-}
-
-//GetAlertStatus 获取告警状态
-func GetAlertStatus() int {
- locker.RLock()
- defer locker.RUnlock()
- return _AlertStatus
-}
-
-//GetAlertInfo 获取告警信息
-func GetAlertInfo() string {
- locker.RLock()
- defer locker.RUnlock()
- return _AlertInfo
-}
-
-//LoadGatewayConfig 加载网关配置
-func LoadGatewayConfig() {
- code, period := dao_gateway.GetGatewayBaseInfo()
- alertInfo, alrtStatus := dao_gateway.GetGatewayAlertInfo()
- locker.Lock()
- defer locker.Unlock()
- _SuccessCode = code
- _UpdatePeriod = period
- _AlertStatus = alrtStatus
- _AlertInfo = alertInfo
-}
-
-//IsSucess 是否成功
-func IsSucess(statusCode int) bool {
- locker.RLock()
- defer locker.RUnlock()
- return strings.Contains(_SuccessCode, strconv.Itoa(statusCode))
-}
diff --git a/goku-node/manager/plugin-manager/errorCode.go b/goku-node/manager/plugin-manager/errorCode.go
deleted file mode 100644
index e935aa1eb23f7d17d0eb6cf0d237181c19c48532..0000000000000000000000000000000000000000
--- a/goku-node/manager/plugin-manager/errorCode.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package pluginmanager
-
-const (
- //LoadOk load ok
- LoadOk = iota
- LoadFileError
- LoadLookupError
- LoadInterFaceError
-)
diff --git a/goku-node/manager/plugin-manager/handle.go b/goku-node/manager/plugin-manager/handle.go
deleted file mode 100644
index 6aec556fc3e0142a7d38f12ea8230891fb5613ab..0000000000000000000000000000000000000000
--- a/goku-node/manager/plugin-manager/handle.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package pluginmanager
-
-import (
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-//GetDefaultPlugins 获取默认插件列表
-func GetDefaultPlugins() []*entity.PluginHandlerExce {
- return defaultPlugins
-}
-
-//GetBeforPlugins 获取默认插件列表
-func GetBeforPlugins() []*entity.PluginHandlerExce {
- return beforPlugins
-}
-
-//Check check
-func Check(name string) (int, error) {
- return globalPluginManager.check(name)
-}
diff --git a/goku-node/manager/plugin-manager/manager.go b/goku-node/manager/plugin-manager/manager.go
deleted file mode 100644
index 8c5ef1515139ad863d60b41d1b4f32b9201904e2..0000000000000000000000000000000000000000
--- a/goku-node/manager/plugin-manager/manager.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package pluginmanager
-
-import (
- "sort"
- "sync"
-
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-// 写插件管理包对外接口
-var (
- pluginHandles = make(map[string]*entity.PluginFactoryHandler)
- defaultPlugins []*entity.PluginHandlerExce
- locker = sync.RWMutex{}
-
- beforPlugins []*entity.PluginHandlerExce
-)
-
-//GetPluginHandle 获取单一插件handle
-func GetPluginHandle(name string) *entity.PluginFactoryHandler {
- locker.RLock()
- handle := pluginHandles[name]
- locker.RUnlock()
-
- return handle
-}
-func reset(pis map[string]*entity.PluginInfo) {
- plugins, def, before := LoadPlugin(pis)
-
- sort.Sort(sort.Reverse(entity.PluginSlice(def)))
- sort.Sort(sort.Reverse(entity.PluginSlice(before)))
- locker.Lock()
- defer locker.Unlock()
-
- pluginHandles = plugins
- defaultPlugins = def
- beforPlugins = before
-}
diff --git a/goku-node/manager/plugin-manager/plugin.go b/goku-node/manager/plugin-manager/plugin.go
deleted file mode 100644
index 8b3cf2c2c99d4970ed0cf36bbfa9be041d62f6dc..0000000000000000000000000000000000000000
--- a/goku-node/manager/plugin-manager/plugin.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package pluginmanager
-
-import (
- "github.com/eolinker/goku-api-gateway/goku-node/manager/updater"
- dao_plugin "github.com/eolinker/goku-api-gateway/server/dao/node-mysql/dao-plugin"
-)
-
-func init() {
- updater.Add(load, 1, "goku_plugin")
-}
-
-func load() {
- pis, e := dao_plugin.GetAll()
- if e != nil {
- return
- }
- reset(pis)
-}
diff --git a/goku-node/manager/service-manager/service.go b/goku-node/manager/service-manager/service.go
deleted file mode 100644
index 1fc5f649328d2c831fd65d625f51e64876b25e71..0000000000000000000000000000000000000000
--- a/goku-node/manager/service-manager/service.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package servicemanager
-
-import (
- "encoding/json"
- log "github.com/eolinker/goku-api-gateway/goku-log"
-
- "github.com/eolinker/goku-api-gateway/goku-node/manager/updater"
- node_common "github.com/eolinker/goku-api-gateway/goku-node/node-common"
- "github.com/eolinker/goku-api-gateway/goku-service/discovery"
- dao_service "github.com/eolinker/goku-api-gateway/server/dao/node-mysql/dao-service"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
- "strings"
-)
-
-func init() {
- updater.Add(loadBalanceInfo, 2, "goku_service_config")
-}
-
-func loadBalanceInfo() {
-
- services, err := dao_service.GetAll()
- if err != nil {
- log.Info(err)
- }
-
- confs := make([]*discovery.Config, 0, len(services))
- for _, s := range services {
- confs = append(confs, toDiscoverConfig(s))
- }
- discovery.ResetAllServiceConfig(confs)
-}
-
-func toDiscoverConfig(e *entity.Service) *discovery.Config {
- c := &discovery.Config{
- Name: e.Name,
- Driver: e.Driver,
- Config: e.Config,
- HealthCheckConfig: discovery.HealthCheckConfig{
- IsHealthCheck: e.HealthCheck,
- Url: e.HealthCheckPath,
- Second: e.HealthCheckPeriod,
- TimeOutMill: e.HealthCheckTimeOut,
- StatusCode: e.HealthCheckCode,
- },
- }
-
- if len(e.ClusterConfig) > 0 {
- var clusterConfigObj map[string]string
- err := json.Unmarshal([]byte(e.ClusterConfig), &clusterConfigObj)
- if err == nil {
-
- clusterName := node_common.ClusterName()
- if v, has := clusterConfigObj[clusterName]; has {
- if len(strings.Trim(v, " ")) > 0 {
- c.Config = v
- }
- }
- }
-
- }
-
- return c
-}
diff --git a/goku-node/manager/strategy-api-manager/apis.go b/goku-node/manager/strategy-api-manager/apis.go
deleted file mode 100644
index fdda1dd362c1ade89dd755385207fc32275af631..0000000000000000000000000000000000000000
--- a/goku-node/manager/strategy-api-manager/apis.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package strategyapimanager
-
-import entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-
-type _APIMap struct {
- apis map[int]*entity.StrategyAPI
-}
-
-func (m *_APIMap) Get(id int) (*entity.StrategyAPI, bool) {
- api, has := m.apis[id]
- return api, has
-}
diff --git a/goku-node/manager/strategy-api-manager/match.go b/goku-node/manager/strategy-api-manager/match.go
deleted file mode 100644
index bf167ad457fb17bbae49951e2de9e6b9c00535a5..0000000000000000000000000000000000000000
--- a/goku-node/manager/strategy-api-manager/match.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package strategyapimanager
-
-import (
- "github.com/eolinker/goku-api-gateway/utils"
- "strings"
-
- api_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/api-manager"
- node_common "github.com/eolinker/goku-api-gateway/goku-node/node-common"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-//CheckAPIFromStrategy 判断接口是否在策略中
-func CheckAPIFromStrategy(strategyID, requestPath string, requestMethod string) (*entity.APIExtend, string, []string, bool) {
- apiMap, has := getAPis(strategyID)
- if !has {
- return nil, "", nil, false
- }
- for _, strategyAPI := range apiMap.apis {
- apiInfo, has := api_manager.GetAPI(strategyAPI.APIID)
- if !has {
- continue
- }
- if apiInfo.StripSlash {
- requestPath = node_common.FilterSlash(requestPath)
- apiInfo.RequestURL = node_common.FilterSlash(apiInfo.RequestURL)
- }
-
- isMatch, splitURL, param := node_common.MatchURI(requestPath, apiInfo.RequestURL)
- if isMatch {
- method := strings.ToUpper(apiInfo.RequestMethod)
- if strings.Contains(method, requestMethod) {
- apiextend := &entity.APIExtend{API: apiInfo}
-
- if strategyAPI.Target != "" {
- apiextend.Target = strategyAPI.Target
- } else {
- apiextend.Target = apiInfo.BalanceName
- }
-
- apiextend.Target = utils.TrimSuffixAll(apiextend.Target, "/")
-
- return apiextend, splitURL, param, true
- }
- }
- }
- return nil, "", nil, false
-}
diff --git a/goku-node/manager/strategy-api-manager/strategy-api.go b/goku-node/manager/strategy-api-manager/strategy-api.go
deleted file mode 100644
index 405e9153e70cbb855021863614bc848be762d6aa..0000000000000000000000000000000000000000
--- a/goku-node/manager/strategy-api-manager/strategy-api.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package strategyapimanager
-
-import (
- "sync"
-
- "github.com/eolinker/goku-api-gateway/goku-node/manager/updater"
- dao_strategy "github.com/eolinker/goku-api-gateway/server/dao/node-mysql/dao-strategy"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-func init() {
- updater.Add(loadStategyAPI, 6, "goku_conn_strategy_api", "goku_gateway_strategy", "goku_gateway_api")
-}
-
-var (
- apiOfStrategy = make(map[string]*_APIMap)
- apiLocker sync.RWMutex
-)
-
-//GetAPIForStategy 获取指定策略、API 对应的 配置
-func GetAPIForStategy(stategyID string, apiID int) (*entity.StrategyAPI, bool) {
- apis, has := getAPis(stategyID)
- if !has {
- return nil, false
- }
- return apis.Get(apiID)
-}
-
-func getAPis(strategyID string) (*_APIMap, bool) {
- apis, has := apiOfStrategy[strategyID]
- return apis, has
-}
-func resetAPIs(apis map[string]*_APIMap) {
- apiLocker.Lock()
- defer apiLocker.Unlock()
-
- apiOfStrategy = apis
-}
-func loadStategyAPI() {
- apis, e := dao_strategy.GetAllStrategyAPI()
- if e != nil {
- return
- }
-
- tem := make(map[string]*_APIMap)
- for _, api := range apis {
-
- as, has := tem[api.StrategyID]
- if !has {
- as = &_APIMap{
- apis: make(map[int]*entity.StrategyAPI),
- }
- }
- as.apis[api.APIID] = api
- tem[api.StrategyID] = as
- }
- resetAPIs(tem)
-}
diff --git a/goku-node/manager/strategy-api-plugin-manager/strategy-api-plugin.go b/goku-node/manager/strategy-api-plugin-manager/strategy-api-plugin.go
deleted file mode 100644
index 23ec1c71dbe5d3df2ca40770d2b04a63e8dbcbfb..0000000000000000000000000000000000000000
--- a/goku-node/manager/strategy-api-plugin-manager/strategy-api-plugin.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package strategyapipluginmanager
-
-import (
- "fmt"
- "github.com/eolinker/goku-api-gateway/goku-node/node-common"
- "sort"
- "strconv"
- "sync"
-
- plugin_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/plugin-manager"
- strategy_plugin_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/strategy-plugin-manager"
- "github.com/eolinker/goku-api-gateway/goku-node/manager/updater"
- dao_strategy "github.com/eolinker/goku-api-gateway/server/dao/node-mysql/dao-strategy"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-func init() {
- updater.Add(loadStategyAPIPlugin, 8, "goku_conn_plugin_strategy", "goku_conn_plugin_api", "goku_conn_strategy_api", "goku_gateway_strategy", "goku_gateway_api", "goku_plugin")
-}
-
-var (
- pluginsOfAPI = make(map[string][]*entity.PluginHandlerExce)
- locker sync.RWMutex
-)
-
-func get(strategyID string, apiID int) ([]*entity.PluginHandlerExce, bool) {
- locker.RLock()
- defer locker.RUnlock()
- key := strategyID + ":" + strconv.Itoa(apiID)
- p, has := pluginsOfAPI[key]
- return p, has
-
-}
-
-//GetPluginsOfAPI 获取接口插件
-func GetPluginsOfAPI(strategyID string, apiID int) ([]*entity.PluginHandlerExce, bool) {
- p, has := get(strategyID, apiID)
- if !has {
- return strategy_plugin_manager.GetPluginsOfStrategy(strategyID)
- }
- return p, true
-}
-
-func reset(plugins map[string][]*entity.PluginHandlerExce) {
- for name := range plugins {
- sort.Sort(sort.Reverse(entity.PluginSlice(plugins[name])))
- }
-
- locker.Lock()
- defer locker.Unlock()
-
- pluginsOfAPI = plugins
-
-}
-
-func loadStategyAPIPlugin() {
- plugins, err := dao_strategy.GetAPIPlugin()
- if err != nil {
- return
- }
-
- phsa := make(map[string]map[int][]*entity.PluginHandlerExce)
- for _, p := range plugins {
- apiID, _ := strconv.Atoi(p.APIId)
-
- phs, has := phsa[p.StrategyID]
- if !has {
- phs = make(map[int][]*entity.PluginHandlerExce)
- }
- phsa[p.StrategyID] = phs
-
- handle := plugin_manager.GetPluginHandle(p.PluginName)
- if handle == nil {
- continue
- }
-
- obj, err := handle.Factory.Create(p.PluginConfig, nodecommon.ClusterName(), p.UpdateTag, p.StrategyID, apiID)
- if err != nil {
- continue
- }
- handleExec := &entity.PluginHandlerExce{
- PluginObj: obj,
- Priority: handle.Info.Priority,
- Name: p.PluginName,
- IsStop: handle.Info.IsStop,
- }
- list, has := phsa[p.StrategyID][apiID]
- if !has {
- list = make([]*entity.PluginHandlerExce, 0)
- phsa[p.StrategyID][apiID] = list
- }
- phsa[p.StrategyID][apiID] = append(list, handleExec)
-
- }
-
- phl := make(map[string][]*entity.PluginHandlerExce)
- for strategyID, pla := range phsa {
- pls, ok := strategy_plugin_manager.GetPluginsOfStrategy(strategyID)
-
- for apiID, list := range pla {
- key := fmt.Sprintf("%s:%d", strategyID, apiID)
-
- if ok {
- list = append(list, pls...)
- }
- phl[key] = list
-
- }
- }
-
- reset(phl)
-}
diff --git a/goku-node/manager/strategy-manager/strategy.go b/goku-node/manager/strategy-manager/strategy.go
deleted file mode 100644
index 7229bff47e48fb6bad5f25b0499f9efe715656c2..0000000000000000000000000000000000000000
--- a/goku-node/manager/strategy-manager/strategy.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package strategymanager
-
-import (
- "sync"
-
- "github.com/eolinker/goku-api-gateway/goku-node/manager/updater"
- dao_strategy "github.com/eolinker/goku-api-gateway/server/dao/node-mysql/dao-strategy"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-func init() {
- updater.Add(loadStategy, 4, "goku_gateway_strategy")
- // loadStategy()
-}
-
-//GetAnonymous 获取匿名策略
-//return: 开放策略ID,是否有效
-func GetAnonymous() (*entity.Strategy, bool) {
- if defStrategy == nil || defStrategy.EnableStatus != 1 {
- return nil, false
- }
- return defStrategy, true
-}
-
-//CheckStategy 测试策略ID是否生效
-func CheckStategy(stategyID string) bool {
- lockerStategy.RLock()
- defer lockerStategy.RUnlock()
- _, has := strategys[stategyID]
- return has
-}
-
-var (
- strategys = make(map[string]*entity.Strategy)
- defStrategy *entity.Strategy
- lockerStategy sync.RWMutex
-)
-
-func reset(s map[string]*entity.Strategy, def *entity.Strategy) {
- lockerStategy.Lock()
- defer lockerStategy.Unlock()
- strategys = s
- defStrategy = def
-}
-
-//Get get
-func Get(id string) (*entity.Strategy, bool) {
- lockerStategy.RLock()
- defer lockerStategy.RUnlock()
- s, has := strategys[id]
- return s, has
-}
-
-//Has has
-func Has(id string) bool {
- lockerStategy.RLock()
- defer lockerStategy.RUnlock()
-
- _, has := strategys[id]
- return has
-}
-func loadStategy() {
- strategies, def, e := dao_strategy.GetAllStrategy()
- if e != nil {
- return
- }
- reset(strategies, def)
-}
diff --git a/goku-node/manager/strategy-plugin-manager/plugins.go b/goku-node/manager/strategy-plugin-manager/plugins.go
deleted file mode 100644
index 8a22dcf7e920018f4b479f0eb41fab8f68eac0fd..0000000000000000000000000000000000000000
--- a/goku-node/manager/strategy-plugin-manager/plugins.go
+++ /dev/null
@@ -1 +0,0 @@
-package strategypluginmanager
diff --git a/goku-node/manager/strategy-plugin-manager/stategy-plugin.go b/goku-node/manager/strategy-plugin-manager/stategy-plugin.go
deleted file mode 100644
index ee2cb60d8f2c77f930be2e95175de2581553d582..0000000000000000000000000000000000000000
--- a/goku-node/manager/strategy-plugin-manager/stategy-plugin.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package strategypluginmanager
-
-import (
- "github.com/eolinker/goku-api-gateway/goku-node/node-common"
- "sort"
- "sync"
-
- plugin_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/plugin-manager"
- "github.com/eolinker/goku-api-gateway/goku-node/manager/updater"
- dao_strategy "github.com/eolinker/goku-api-gateway/server/dao/node-mysql/dao-strategy"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-func init() {
- updater.Add(loadStategyPlugin, 7, "goku_conn_plugin_strategy", "goku_gateway_strategy", "goku_plugin")
-}
-
-var (
- pluginsOfStrategy = make(map[string][]*entity.PluginHandlerExce)
- locker sync.RWMutex
-)
-
-//GetPluginsOfStrategy 获取策略插件
-func GetPluginsOfStrategy(strategyID string) ([]*entity.PluginHandlerExce, bool) {
- locker.RLock()
- defer locker.RUnlock()
- p, has := pluginsOfStrategy[strategyID]
- if !has {
- return nil, false
- }
- return p, true
-}
-
-func reset(plugins map[string][]*entity.PluginHandlerExce) {
- for name := range plugins {
- //plugins[name] = append(list,def...)
- sort.Sort(sort.Reverse(entity.PluginSlice(plugins[name])))
- }
- locker.Lock()
- defer locker.Unlock()
-
- pluginsOfStrategy = plugins
-
-}
-
-func loadStategyPlugin() {
- plugins, err := dao_strategy.GetAllStrategyPluginList()
- if err != nil {
- return
- }
- phl := make(map[string][]*entity.PluginHandlerExce)
- for _, p := range plugins {
- if _, ok := phl[p.StrategyID]; !ok {
- phl[p.StrategyID] = make([]*entity.PluginHandlerExce, 0)
- }
- handle := plugin_manager.GetPluginHandle(p.PluginName)
- if handle == nil {
- continue
- }
- excer, err := handle.Factory.Create(p.PluginConfig, nodecommon.ClusterName(), p.UpdateTag, p.StrategyID, 0)
- if err != nil {
-
- continue
- }
- handleExec := &entity.PluginHandlerExce{
- PluginObj: excer,
- Name: p.PluginName,
- Priority: handle.Info.Priority,
- IsStop: handle.Info.IsStop,
- }
- phl[p.StrategyID] = append(phl[p.StrategyID], handleExec)
- }
- reset(phl)
-}
diff --git a/goku-node/manager/type.go b/goku-node/manager/type.go
deleted file mode 100644
index 5d04392c762c155e5048e1498e88ead4b61f8bb7..0000000000000000000000000000000000000000
--- a/goku-node/manager/type.go
+++ /dev/null
@@ -1 +0,0 @@
-package manager
diff --git a/goku-node/manager/updater/table.go b/goku-node/manager/updater/table.go
deleted file mode 100644
index ea0be2259e55881bd5077913ac1b10dfb52e2530..0000000000000000000000000000000000000000
--- a/goku-node/manager/updater/table.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package updater
-
-type updateHandlerExec struct {
- name string
- priority int
- *updateHandler
-}
-
-type handlerSlice []*updateHandlerExec
-
-func (p handlerSlice) Len() int { // 重写 Len() 方法
- return len(p)
-}
-func (p handlerSlice) Swap(i, j int) { // 重写 Swap() 方法
- p[i], p[j] = p[j], p[i]
-}
-func (p handlerSlice) Less(i, j int) bool { // 重写 Less() 方法, 从小到大排序
- return p[i].priority < p[j].priority
-}
diff --git a/goku-node/manager/updater/update.go b/goku-node/manager/updater/update.go
deleted file mode 100644
index 701e98213acbf6a5274816584546be21bd4267ab..0000000000000000000000000000000000000000
--- a/goku-node/manager/updater/update.go
+++ /dev/null
@@ -1,147 +0,0 @@
-package updater
-
-import (
- "fmt"
- "sort"
- "strings"
- "sync"
- "time"
-
- log "github.com/eolinker/goku-api-gateway/goku-log"
-
- gateway_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/gateway-manager"
- "github.com/eolinker/goku-api-gateway/server/dao"
-)
-
-var (
- isInit = false
- handlers = make(map[string]*updateHandler)
- ch = make(chan bool, 1)
- periodCh = make(chan int, 1)
- locker sync.Mutex
- handlerExecs = make([]*updateHandlerExec, 0)
-)
-
-//UpdateHandleFunc update handle func
-type UpdateHandleFunc func()
-
-func init() {
- Add(func() {
- gateway_manager.LoadGatewayConfig()
- updatePeriod(gateway_manager.GetUpdatePeriod())
- }, 2, "goku_gateway")
-}
-
-type updateHandler struct {
- tables []string
- UpdateHandlers []UpdateHandleFunc
- last time.Time
-}
-
-func updatePeriod(period int) {
- periodCh <- period
-}
-
-//Add add
-func Add(handler UpdateHandleFunc, priority int, tables ...string) {
- sort.Strings(tables)
- key := strings.Join(tables, ":")
- locker.Lock()
- defer locker.Unlock()
- hfs, has := handlers[key]
- if !has {
- hfs = &updateHandler{
- tables: tables,
- }
- }
- hfs.UpdateHandlers = append(hfs.UpdateHandlers, handler)
- if !has {
- handlerExec := &updateHandlerExec{
- name: key,
- priority: priority,
- updateHandler: hfs,
- }
- handlerExecs = append(handlerExecs, handlerExec)
- }
- handlers[key] = hfs
-}
-
-//Update update
-func Update() {
- ch <- true
-}
-
-//InitUpdate init update
-func InitUpdate() {
- locker.Lock()
- defer locker.Unlock()
- if isInit {
- return
- }
- isInit = true
- // 排序
- log.Debug("update sort handler")
- sort.Sort(handlerSlice(handlerExecs))
- log.Debug("update sort handler done")
- doFirst()
- go doUpdate(gateway_manager.GetUpdatePeriod())
-}
-func doFirst() {
- log.Debug("update doFirst")
- handlerExecsTmp := handlerExecs
- for _, handler := range handlerExecsTmp {
-
- if handler != nil {
- log.Debug("update ", handler.name, handler.tables)
- handler.last = time.Now()
- for _, fn := range handler.UpdateHandlers {
- fn()
- }
- log.Debug("update done")
- }
- }
-}
-func doUpdate(sec int) {
- fmt.Println(sec)
- period := time.Duration(sec) * time.Second
- t := time.NewTimer(period)
- for {
- select {
- case <-t.C:
- case <-ch:
- case p := <-periodCh:
- {
- period = time.Duration(p) * time.Second
- continue
- }
- }
- updates()
- t.Reset(period)
- }
-}
-
-func updates() {
- handlerExecsTmp := handlerExecs
- for _, handler := range handlerExecsTmp {
- if handler != nil {
- if u, nt := CheckUpdate(handler.last, handler.tables...); u {
- handler.last = nt
- for _, fn := range handler.UpdateHandlers {
- fn()
- }
- }
- }
- }
-}
-
-//CheckUpdate check update
-func CheckUpdate(last time.Time, tables ...string) (bool, time.Time) {
- t, err := dao.GetLastUpdateOfAPI(tables...)
- if err != nil {
- return false, last
- }
- if t.After(last) {
- return true, t
- }
- return false, last
-}
diff --git a/goku-node/node-common/constant.go b/goku-node/node-common/constant.go
deleted file mode 100644
index 85fa1be80efdedb131c6a8646fef5e8ca0f553fc..0000000000000000000000000000000000000000
--- a/goku-node/node-common/constant.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package nodecommon
-
-import (
- "fmt"
- "strings"
-)
-
-var (
- //ListenPort 网关监听端口
- ListenPort = 6689
- clusterName string
- adminURL = ""
-)
-
-//SetClusterName 设置集群名称
-func SetClusterName(name string) {
- clusterName = name
-}
-
-//ClusterName 获取集群名称
-func ClusterName() string {
- return clusterName
-}
-
-//SetAdmin 设置admin地址
-func SetAdmin(host string) {
- h := strings.TrimPrefix(host, "http://")
- h = strings.TrimSuffix(h, "/")
- adminURL = fmt.Sprintf("http://%s", h)
-}
-
-//GetAdminURL 获取adminURL
-func GetAdminURL(path string) string {
- p := strings.TrimPrefix(path, "/")
- return fmt.Sprintf("%s/%s", adminURL, p)
-}
diff --git a/goku-node/node-common/match.go b/goku-node/node-common/match.go
deleted file mode 100644
index 8471d066c174fb3be9b1b2430c97dd0f5a7188b3..0000000000000000000000000000000000000000
--- a/goku-node/node-common/match.go
+++ /dev/null
@@ -1,111 +0,0 @@
-package nodecommon
-
-import "strings"
-
-//MatchRestful 匹配restful参数
-func MatchRestful(requestURL string, params []string) string {
- if len(params) == 0 {
- return requestURL
- }
- // 将匹配URI中的query参数清除
- requestURL = InterceptURL(requestURL, "?")
- var postfix = false
- // 将URI最后放的"/"去掉
- if string(requestURL[len(requestURL)-1]) == "/" {
- postfix = true
- requestURL = requestURL[:len(requestURL)-1]
- }
- requestArray := strings.Split(requestURL, "/")
- url := "/"
- n := 0
- for _, v := range requestArray {
- if len(v) > 0 {
- if string(v[0]) == ":" {
- url += params[n] + "/"
- n = n + 1
- } else if string(v[0]) == "{" && string(v[len(v)-1]) == "}" {
- url += params[n] + "/"
- n = n + 1
- } else {
- url += v + "/"
- }
- }
- }
- if !postfix {
- return url[:len(url)-1]
- }
- return url
-}
-
-//MatchURI 匹配URI
-func MatchURI(requestPath string, matchURI string) (bool, string, []string) {
- // 将匹配URI中的query参数清除
- matchURI = InterceptURL(matchURI, "?")
- // 将请求参数分组
- if requestPath == matchURI {
- return true, "", nil
- }
- var postfix = false
- // 将URI最后的"/"去掉
- if string(requestPath[len(requestPath)-1]) == "/" {
- postfix = true
- requestPath = requestPath[:len(requestPath)-1]
- }
- if string(matchURI[len(matchURI)-1]) == "/" {
- postfix = true
- matchURI = matchURI[:len(matchURI)-1]
- }
-
- requestArray := strings.Split(requestPath, "/")
- matchArray := strings.Split(matchURI, "/")
- // 比较数组长度
- if len(requestArray) < len(matchArray) {
- return false, "", nil
- }
-
- n := 0
- param := make([]string, 0)
- for i, v := range matchArray {
- n = n + 1
- if v == requestArray[i] {
- continue
- } else {
- // 匹配restful参数
- if string(v[0]) == ":" {
- param = append(param, requestArray[i])
- continue
- } else if string(v[0]) == "{" && string(v[len(v)-1]) == "}" {
- param = append(param, requestArray[i])
- continue
- } else {
- return false, "", nil
- }
- }
- }
- splitURL := "/"
- for _, v := range requestArray[n:] {
- splitURL += v + "/"
- }
- if !postfix {
- return true, splitURL[:len(splitURL)-1], param
- }
- return true, splitURL, param
-}
-
-//InterceptURL 过滤URL
-func InterceptURL(str, substr string) string {
- result := strings.Index(str, substr)
- var rs string
- if result != -1 {
- rs = str[:result]
- } else {
- rs = str
- }
- return rs
-}
-
-//FilterSlash 过滤双斜杠
-func FilterSlash(uri string) string {
- replaceURI := strings.ReplaceAll(uri, "//", "/")
- return replaceURI
-}
diff --git a/goku-node/plugin-flow/access.go b/goku-node/plugin-flow/access.go
deleted file mode 100644
index c4399377b63c528bf5da136f80a3cf1a835b25f3..0000000000000000000000000000000000000000
--- a/goku-node/plugin-flow/access.go
+++ /dev/null
@@ -1,122 +0,0 @@
-package pluginflow
-
-import (
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "github.com/eolinker/goku-api-gateway/goku-node/common"
- plugin_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/plugin-manager"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
- "reflect"
- "time"
-)
-
-var (
- authNames = map[string]string{
- "Oauth2": "goku-oauth2_auth",
- "Apikey": "goku-apikey_auth",
- "Basic": "goku-basic_auth",
- "Jwt": "goku-jwt_auth",
- }
- authPluginNames = map[string]string{
- "goku-oauth2_auth": "Oauth2",
- "goku-apikey_auth": "Apikey",
- "goku-basic_auth": "Basic",
- "goku-jwt_auth": "Jwt",
- }
-)
-
-func getPluginNameByType(authType string) (string, bool) {
- name, has := authNames[authType]
- return name, has
-}
-
-//AccessFunc 执行插件的Access函数
-func AccessFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (bool, int) {
- requestID := ctx.RequestId()
- authType := ctx.Request().GetHeader("Authorization-Type")
- authName, _ := getPluginNameByType(authType)
- defer func(ctx *common.Context) {
- log.Debug(requestID, " access plugin default: begin")
- for _, handler := range plugin_manager.GetDefaultPlugins() {
- if handler.PluginObj.Access == nil || reflect.ValueOf(handler.PluginObj.Access).IsNil() {
- continue
- }
- ctx.SetPlugin(handler.Name)
- log.Info(requestID, " access plugin:", handler.Name)
- now := time.Now()
- _, err := handler.PluginObj.Access.Access(ctx)
- log.Debug(requestID, " access plugin:", handler.Name, " Duration", time.Since(now))
- if err != nil {
- log.Warn(requestID, " access plugin:", handler.Name, " error:", err.Error())
- }
- }
- log.Debug(requestID, " access plugin default: end")
- }(ctx)
- isAuthSucess := false
- isNeedAuth := false
-
- log.Debug(requestID, " access plugin auth check: begin")
- for _, handler := range handleFunc {
- if _, has := authPluginNames[handler.Name]; has {
- isNeedAuth = true
- if handler.Name != authName {
- continue
- }
- if handler.PluginObj.Access == nil || reflect.ValueOf(handler.PluginObj.Access).IsNil() {
- continue
- }
- ctx.SetPlugin(handler.Name)
- log.Debug(requestID, " access plugin:", handler.Name, " begin")
- now := time.Now()
- flag, err := handler.PluginObj.Access.Access(ctx)
- log.Debug(requestID, " access plugin:", handler.Name, " Duration", time.Since(now))
- if flag == false {
- // 校验失败
- if err != nil {
- log.Warn(requestID, " access auth:[", handler.Name, "] error:", err.Error())
- }
- log.Info(requestID, " auth [", authName, "] refuse")
-
- return false, 0
- }
- log.Debug(requestID, " auth [", authName, "] pass")
- isAuthSucess = true
- }
- }
- log.Debug(requestID, " access plugin auth check: end")
- // 需要校验但是没有执行校验
- if isNeedAuth && !isAuthSucess {
- log.Warn(requestID, " Illegal authorization type:", authType)
- ctx.SetStatus(403, "403")
- ctx.SetBody([]byte("[ERROR]Illegal authorization type!"))
- return false, 0
- }
- lastIndex := 0
- log.Debug(requestID, " access plugin : begin")
- // 执行校验以外的插件
- for index, handler := range handleFunc {
- lastIndex = index
- if _, has := authPluginNames[handler.Name]; has {
- continue
- }
-
- if handler.PluginObj.Access == nil || reflect.ValueOf(handler.PluginObj.Access).IsNil() {
- continue
- }
-
- ctx.SetPlugin(handler.Name)
- log.Debug(requestID, " access plugin:", handler.Name)
- now := time.Now()
- flag, err := handler.PluginObj.Access.Access(ctx)
- log.Debug(requestID, " access plugin:", handler.Name, " Duration:", time.Since(now))
- if err != nil {
- log.Warn(requestID, " access plugin:", handler.Name, " error:", err.Error())
- }
- if flag == false && handler.IsStop {
- log.Info(requestID, " access plugin:", handler.Name, " stop")
- return false, index
- }
- log.Debug(requestID, " access plugin:", handler.Name, " continue")
- }
- log.Debug(requestID, " access plugin : end")
- return true, lastIndex
-}
diff --git a/goku-node/plugin-flow/before.go b/goku-node/plugin-flow/before.go
deleted file mode 100644
index 3cc29ac35172aeabe1197f415d6ec7652d0b223e..0000000000000000000000000000000000000000
--- a/goku-node/plugin-flow/before.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package pluginflow
-
-import (
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "github.com/eolinker/goku-api-gateway/goku-node/common"
- plugin_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/plugin-manager"
- "reflect"
- "time"
-)
-
-//BeforeMatch 执行插件的BeforeMatch函数
-func BeforeMatch(ctx *common.Context) bool {
- requestID := ctx.RequestId()
- defer func(ctx *common.Context) {
- log.Debug(requestID, " before plugin default: begin")
- for _, handler := range plugin_manager.GetDefaultPlugins() {
- if handler.PluginObj.BeforeMatch == nil || reflect.ValueOf(handler.PluginObj.BeforeMatch).IsNil() {
- continue
- }
- ctx.SetPlugin(handler.Name)
- log.Debug(requestID, " before plugin :", handler.Name, " start")
- now := time.Now()
- _, err := handler.PluginObj.BeforeMatch.BeforeMatch(ctx)
- log.Debug(requestID, " before plugin :", handler.Name, " Duration:", time.Since(now))
- log.Debug(requestID, " before plugin :", handler.Name, " end")
- if err != nil {
- log.Warn(requestID, " before plugin:", handler.Name, " error:", err.Error())
- }
- }
- log.Debug(requestID, " before plugin default: end")
- }(ctx)
- log.Debug(requestID, " before plugin : begin")
- for _, handler := range plugin_manager.GetBeforPlugins() {
-
- if handler.PluginObj.BeforeMatch == nil || reflect.ValueOf(handler.PluginObj.BeforeMatch).IsNil() {
- continue
- }
-
- ctx.SetPlugin(handler.Name)
- log.Debug(requestID, " before plugin :", handler.Name, " start")
- now := time.Now()
- flag, err := handler.PluginObj.BeforeMatch.BeforeMatch(ctx)
- log.Debug(requestID, " before plugin :", handler.Name, " Duration:", time.Since(now))
- log.Debug(requestID, " before plugin :", handler.Name, " end")
-
- if err != nil {
- log.Warn(requestID, " before plugin:", handler.Name, " error:", err.Error())
- }
- if flag == false {
- if handler.IsStop == true {
- return false
- }
- }
- }
- log.Debug(requestID, " before plugin : end")
- return true
-}
diff --git a/goku-node/plugin-flow/proxy.go b/goku-node/plugin-flow/proxy.go
deleted file mode 100644
index d975c2cb80a696ca3c7afbcd74163aa4aa512437..0000000000000000000000000000000000000000
--- a/goku-node/plugin-flow/proxy.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package pluginflow
-
-import (
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "github.com/eolinker/goku-api-gateway/goku-node/common"
- plugin_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/plugin-manager"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-
- "reflect"
- "time"
-)
-
-//ProxyFunc 执行插件的Proxy函数
-func ProxyFunc(ctx *common.Context, handleFunc []*entity.PluginHandlerExce) (bool, int) {
- requestID := ctx.RequestId()
- defer func(ctx *common.Context) {
- log.Debug(requestID, " Proxy plugin default: begin")
- for _, handler := range plugin_manager.GetDefaultPlugins() {
- if handler.PluginObj.Proxy == nil || reflect.ValueOf(handler.PluginObj.Proxy).IsNil() {
- continue
- }
- ctx.SetPlugin(handler.Name)
- log.Debug(requestID, " Proxy plugin :", handler.Name, " start")
- now := time.Now()
- _, err := handler.PluginObj.Proxy.Proxy(ctx)
- log.Debug(requestID, " Proxy plugin :", handler.Name, " Duration:", time.Since(now))
- log.Debug(requestID, " Proxy plugin :", handler.Name, " end")
-
- if err != nil {
- log.Warn(requestID, " Proxy plugin:", handler.Name, " error:", err.Error())
- }
- }
- log.Debug(requestID, " Proxy plugin default: begin")
- }(ctx)
- lastIndex := 0
- log.Debug(requestID, " Proxy plugin : begin")
- for index, handler := range handleFunc {
- lastIndex = index
- if handler.PluginObj.Proxy == nil || reflect.ValueOf(handler.PluginObj.Proxy).IsNil() {
- continue
- }
-
- ctx.SetPlugin(handler.Name)
- log.Debug(requestID, " Proxy plugin :", handler.Name, " start")
- now := time.Now()
- flag, err := handler.PluginObj.Proxy.Proxy(ctx)
- log.Debug(requestID, " Proxy plugin :", handler.Name, " Duration:", time.Since(now))
- log.Debug(requestID, " Proxy plugin :", handler.Name, " end")
-
- if err != nil {
- log.Warn(requestID, " Proxy plugin :", handler.Name, " error: ", err.Error())
- }
- if flag == false && handler.IsStop == true {
-
- return false, lastIndex
- }
- }
- log.Debug(requestID, " Proxy plugin : end")
- return true, lastIndex
-}
diff --git a/goku-node/redis-plugin-proxy/pipeline.go b/goku-node/redis-plugin-proxy/pipeline.go
index 21fa5ac8578fd47cd2e2618cb389fa23216f5640..0f72398fd9bfa4f903ae933a49af4309723b5888 100644
--- a/goku-node/redis-plugin-proxy/pipeline.go
+++ b/goku-node/redis-plugin-proxy/pipeline.go
@@ -1,11 +1,11 @@
-package redispluginproxy
+package redis_plugin_proxy
import (
- "github.com/eolinker/goku-plugin"
+ goku_plugin "github.com/eolinker/goku-plugin"
"github.com/go-redis/redis"
)
-//PipelineProxy pipelineProxy
+//PipelineProxy 转发管道
type PipelineProxy struct {
RedisProxy
pipeliner redis.Pipeliner
diff --git a/goku-node/redis-plugin-proxy/proxy.go b/goku-node/redis-plugin-proxy/proxy.go
index 9697f8ba8422fcd467283a1231c8d8d93db5d7c8..c399dbd86b99122aadc92320294980b2c80aebae 100644
--- a/goku-node/redis-plugin-proxy/proxy.go
+++ b/goku-node/redis-plugin-proxy/proxy.go
@@ -1,9 +1,10 @@
-package redispluginproxy
+package redis_plugin_proxy
import (
+ "time"
+
redis2 "github.com/eolinker/goku-plugin"
"github.com/go-redis/redis"
- "time"
)
//RedisProxy redisProxy
@@ -57,7 +58,7 @@ func (p *RedisProxy) Restore(key string, ttl time.Duration, value string) redis2
return p.redisClient.Restore(key, ttl, value)
}
-//RestoreReplace restore replace
+//RestoreReplace restoreReplace
func (p *RedisProxy) RestoreReplace(key string, ttl time.Duration, value string) redis2.StatusCmd {
return p.redisClient.RestoreReplace(key, ttl, value)
}
@@ -131,13 +132,13 @@ func (p *RedisProxy) IncrByFloat(key string, value float64) redis2.FloatCmd {
return p.redisClient.IncrByFloat(key, value)
}
-//MGet mget
+//MGet mGet
func (p *RedisProxy) MGet(keys ...string) redis2.SliceCmd { return p.redisClient.MGet(keys...) }
-//MSet mset
+//MSet mSet
func (p *RedisProxy) MSet(pairs ...interface{}) redis2.StatusCmd { return p.redisClient.MSet(pairs) }
-//MSetNX msetnx
+//MSetNX mSetNx
func (p *RedisProxy) MSetNX(pairs ...interface{}) redis2.BoolCmd { return p.redisClient.MSetNX(pairs) }
//Set set
@@ -145,17 +146,17 @@ func (p *RedisProxy) Set(key string, value interface{}, expiration time.Duration
return p.redisClient.Set(key, value, expiration)
}
-//SetBit setbit
+//SetBit setBit
func (p *RedisProxy) SetBit(key string, offset int64, value int) redis2.IntCmd {
return p.redisClient.SetBit(key, offset, value)
}
-//SetNX setnx
+//SetNX setNx
func (p *RedisProxy) SetNX(key string, value interface{}, expiration time.Duration) redis2.BoolCmd {
return p.redisClient.SetNX(key, value, expiration)
}
-//SetXX setxx
+//SetXX setXX
func (p *RedisProxy) SetXX(key string, value interface{}, expiration time.Duration) redis2.BoolCmd {
return p.redisClient.SetXX(key, value, expiration)
}
@@ -200,12 +201,12 @@ func (p *RedisProxy) HKeys(key string) redis2.StringSliceCmd { return p.redisCli
//HLen hLen
func (p *RedisProxy) HLen(key string) redis2.IntCmd { return p.redisClient.HLen(key) }
-//HMGet hMget
+//HMGet hMGet
func (p *RedisProxy) HMGet(key string, fields ...string) redis2.SliceCmd {
return p.redisClient.HMGet(key, fields...)
}
-//HMSet hMset
+//HMSet hMSet
func (p *RedisProxy) HMSet(key string, fields map[string]interface{}) redis2.StatusCmd {
return p.redisClient.HMSet(key, fields)
}
@@ -223,17 +224,17 @@ func (p *RedisProxy) HSetNX(key, field string, value interface{}) redis2.BoolCmd
//HVals hVals
func (p *RedisProxy) HVals(key string) redis2.StringSliceCmd { return p.redisClient.HVals(key) }
-//BLPop bLpop
+//BLPop bLPop
func (p *RedisProxy) BLPop(timeout time.Duration, keys ...string) redis2.StringSliceCmd {
return p.redisClient.BLPop(timeout, keys...)
}
-//BRPop brpop
+//BRPop bRPop
func (p *RedisProxy) BRPop(timeout time.Duration, keys ...string) redis2.StringSliceCmd {
return p.redisClient.BRPop(timeout, keys...)
}
-//BRPopLPush brPopLpush
+//BRPopLPush bRPopLPush
func (p *RedisProxy) BRPopLPush(source, destination string, timeout time.Duration) redis2.StringCmd {
return p.redisClient.BRPopLPush(source, destination, timeout)
}
@@ -261,7 +262,7 @@ func (p *RedisProxy) LInsertAfter(key string, pivot, value interface{}) redis2.I
//LLen llen
func (p *RedisProxy) LLen(key string) redis2.IntCmd { return p.redisClient.LLen(key) }
-//LPop lpop
+//LPop lPop
func (p *RedisProxy) LPop(key string) redis2.StringCmd { return p.redisClient.LPop(key) }
//LPush lPush
@@ -297,7 +298,7 @@ func (p *RedisProxy) LTrim(key string, start, stop int64) redis2.StatusCmd {
//RPop rPop
func (p *RedisProxy) RPop(key string) redis2.StringCmd { return p.redisClient.RPop(key) }
-//RPopLPush rPopLpush
+//RPopLPush rPopLPush
func (p *RedisProxy) RPopLPush(source, destination string) redis2.StringCmd {
return p.redisClient.RPopLPush(source, destination)
}
@@ -387,7 +388,7 @@ func (p *RedisProxy) SUnionStore(destination string, keys ...string) redis2.IntC
return p.redisClient.SUnionStore(destination, keys...)
}
-//Pipeline pipeLine
+//Pipeline pipeline
func (p *RedisProxy) Pipeline() redis2.Pipeliner {
pipe := p.redisClient.Pipeline()
return &PipelineProxy{
diff --git a/goku-node/redis-plugin-proxy/redis.go b/goku-node/redis-plugin-proxy/redis.go
index 597f0e18d8790a3ff45163e822afd0cd236c5f9f..04787964d522e65081c3e1fceb41e16ff7194a13 100644
--- a/goku-node/redis-plugin-proxy/redis.go
+++ b/goku-node/redis-plugin-proxy/redis.go
@@ -1,11 +1,11 @@
-package redispluginproxy
+package redis_plugin_proxy
import (
redis_manager "github.com/eolinker/goku-api-gateway/common/redis-manager"
- "github.com/eolinker/goku-plugin"
+ goku_plugin "github.com/eolinker/goku-plugin"
)
-//Create 创建redisManager
+//Create 创建RedisManager
func Create() goku_plugin.RedisManager {
return &RedisManager{
@@ -13,10 +13,9 @@ func Create() goku_plugin.RedisManager {
redisClient: redis_manager.GetConnection(),
},
}
-
}
-//RedisManager redisManager
+//RedisManager RedisManager
type RedisManager struct {
def goku_plugin.Redis
}
diff --git a/goku-node/request/request.go b/goku-node/request/request.go
deleted file mode 100644
index a33cf08a50686d2cc21d445218a63deae985cc68..0000000000000000000000000000000000000000
--- a/goku-node/request/request.go
+++ /dev/null
@@ -1,255 +0,0 @@
-package request
-
-import (
- "bytes"
- "errors"
- "io"
- "net/http"
- "net/url"
- // "fmt"
- "time"
-)
-
-const requestVersion = "2.0"
-
-//Request request
-type Request struct {
- client *http.Client
- method string
- URL string
- headers map[string][]string
- body []byte
-
- queryParams map[string][]string
-
- timeout int
-}
-
-//NewRequest 创建新请求
-func NewRequest(method string, URL *url.URL) (*Request, error) {
- if method != "GET" && method != "POST" && method != "PUT" && method != "DELETE" &&
- method != "HEAD" && method != "OPTIONS" && method != "PATCH" {
- return nil, errors.New("Unsupported Request Method")
- }
- return newRequest(method, URL)
-}
-
-//
-func newRequest(method string, URL *url.URL) (*Request, error) {
- var urlPath string
- queryParams := make(map[string][]string)
- for key, values := range URL.Query() {
- queryParams[key] = values
- }
- urlPath = URL.Scheme + "://" + URL.Host + URL.Path
- r := &Request{
- client: &http.Client{},
- method: method,
- URL: urlPath,
- headers: make(map[string][]string),
- queryParams: queryParams,
- }
- return r, nil
-}
-
-//SetHeader 设置请求头
-func (rq *Request) SetHeader(key string, values ...string) {
- if len(values) > 0 {
- rq.headers[key] = values[:]
- } else {
- delete(rq.headers, key)
- }
-}
-
-//Headers 获取请求头
-func (rq *Request) Headers() map[string][]string {
- headers := make(map[string][]string)
- for key, values := range rq.headers {
- headers[key] = values[:]
- }
- return headers
-}
-
-//SetQueryParam 设置Query参数
-func (rq *Request) SetQueryParam(key string, values ...string) {
- if len(values) > 0 {
- rq.queryParams[key] = values[:]
- } else {
- delete(rq.queryParams, key)
- }
-}
-
-//SetTimeout 设置请求超时时间
-func (rq *Request) SetTimeout(timeout int) {
- rq.timeout = timeout
-}
-
-//GetTimeout 获取请求超时时间
-func (rq *Request) GetTimeout() int {
- return rq.timeout
-}
-
-//Send 发送请求
-func (rq *Request) Send() (*http.Response, error) {
- // now := time.Now()
- req, err := rq.parseBody()
- // fmt.Println("Parse body",time.Since(now))
- if err != nil {
- return nil, err
- }
- req.Header.Set("Accept-Encoding", "gzip")
- // now = time.Now()
- req.Header = parseHeaders(rq.headers)
-
- rq.client.Timeout = time.Duration(rq.timeout) * time.Millisecond
-
- httpResponse, err := rq.client.Do(req)
-
- if err != nil {
- return nil, err
- }
- return httpResponse, nil
-
-}
-
-//QueryParams 获取query参数
-func (rq *Request) QueryParams() map[string][]string {
- params := make(map[string][]string)
- for key, values := range rq.queryParams {
- params[key] = values[:]
- }
- return params
-}
-
-//URLPath 获取完整的URL路径
-func (rq *Request) URLPath() string {
- if len(rq.queryParams) > 0 {
- return rq.URL + "?" + parseParams(rq.queryParams).Encode()
- }
- return rq.URL
-}
-
-//SetURL 设置URL
-func (rq *Request) SetURL(url string) {
- rq.URL = url
-}
-
-//SetRawBody 设置源数据
-func (rq *Request) SetRawBody(body []byte) {
- rq.body = body
-}
-
-// 解析请求头
-func parseHeaders(headers map[string][]string) http.Header {
- h := http.Header{}
- for key, values := range headers {
- for _, value := range values {
- h.Add(key, value)
- }
- }
-
- _, hasAccept := h["Accept"]
- if !hasAccept {
- h.Add("Accept", "*/*")
- }
- _, hasAgent := h["User-Agent"]
- if !hasAgent {
- h.Add("User-Agent", "goku-requests/"+requestVersion)
- }
- return h
-}
-
-// 解析请求体
-func (rq *Request) parseBody() (req *http.Request, err error) {
- var body io.Reader = nil
- if len(rq.body) > 0 {
- body = bytes.NewBuffer(rq.body)
-
- }
- req, err = http.NewRequest(rq.method, rq.URLPath(), body)
- return
- //if rq.method == "GET" || rq.method == "TRACE" {
- // req, err = http.NewRequest(rq.method, rq.URLPath(), nil)
- //}
- //
- //if len(rq.body) > 0 {
- //
- // if rq.isJSON {
- // if _, ok := rq.headers["Content-Type"]; !ok {
- // rq.headers["Content-Type"] = []string{"application/json"}
- // }
- // req, err = http.NewRequest(rq.method, rq.URLPath(),
- // strings.NewReader(string(rq.body)))
- // } else {
- // var body *bytes.Buffer
- // body = bytes.NewBuffer(rq.body)
- //
- // }
- //} else if len(rq.files) > 0 {
- // body := new(bytes.Buffer)
- // writer := multipart.NewWriter(body)
- // var part io.Writer
- // for fieldname, file := range rq.files {
- // part, err = writer.CreateFormFile(fieldname, file.filename)
- // if err != nil {
- // return
- // }
- // _, err = part.Write(file.data)
- // if err != nil {
- // return
- // }
- // }
- // for fieldname, values := range rq.formParams {
- // temp := make(map[string][]string)
- // temp[fieldname] = values
- // value := parseParams(temp).Encode()
- // err = writer.WriteField(fieldname, value)
- // if err != nil {
- // return
- // }
- // }
- // err = writer.Close()
- // if err != nil {
- // return
- // }
- // rq.headers["Content-Type"] = []string{writer.FormDataContentType()}
- // req, err = http.NewRequest(rq.method, rq.URLPath(), body)
- //} else {
- // rq.headers["Content-Type"] = []string{"application/x-www-form-urlencoded"}
- // req, err = http.NewRequest(rq.method, rq.URLPath(),
- // strings.NewReader(parseParams(rq.formParams).Encode()))
- //}
- //return
-}
-
-//parseParams 解析参数
-func parseParams(params map[string][]string) url.Values {
- v := url.Values{}
- for key, values := range params {
- for _, value := range values {
- v.Add(key, value)
- }
- }
- return v
-}
-
-//parseURL 解析URL
-func parseURL(urlPath string) (URL *url.URL, err error) {
- URL, err = url.Parse(urlPath)
- if err != nil {
- return nil, err
- }
-
- if URL.Scheme != "http" && URL.Scheme != "https" {
- urlPath = "http://" + urlPath
- URL, err = url.Parse(urlPath)
- if err != nil {
- return nil, err
- }
-
- if URL.Scheme != "http" && URL.Scheme != "https" {
- return nil, errors.New("[package requests] only HTTP and HTTPS are accepted")
- }
- }
- return
-}
diff --git a/goku-node/request_mapping.go b/goku-node/request_mapping.go
deleted file mode 100644
index 4580146dbad430eb307fdec8aa3513e69d6ad3e7..0000000000000000000000000000000000000000
--- a/goku-node/request_mapping.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package gokunode
-
-import (
- "fmt"
- "net/http"
- "time"
-
- "github.com/eolinker/goku-api-gateway/goku-node/common"
-
- balance_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/balance-manager"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-
- "strings"
-)
-
-// CreateRequest 创建转发请求
-func CreateRequest(ctx *common.Context, apiInfo *entity.APIExtend, timeout, retry int) (*http.Response, error) {
-
- app, has := balance_manager.Get(apiInfo.Target)
- if !has {
- err := fmt.Errorf("get balance error:%s", apiInfo.Target)
- return nil, err
- }
- rawbody, _ := ctx.ProxyRequest.RawBody()
-
- response, finalTargetServer, retryTargetServers, err := app.Send(apiInfo.Protocol, ctx.ProxyRequest.Method, ctx.ProxyRequest.TargetURL(), ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(), rawbody, time.Duration(timeout)*time.Millisecond, retry)
-
- ctx.SetRetryTargetServers(strings.Join(retryTargetServers, ","))
- ctx.SetFinalTargetServer(finalTargetServer)
-
- if err != nil {
- return nil, err
- }
- return response, nil
-
-}
diff --git a/goku-node/router.go b/goku-node/router.go
deleted file mode 100644
index 70bbd4fbf08222f2517d3b1e20fb12a442d5e281..0000000000000000000000000000000000000000
--- a/goku-node/router.go
+++ /dev/null
@@ -1,259 +0,0 @@
-package gokunode
-
-import (
- "fmt"
-
- log "github.com/eolinker/goku-api-gateway/goku-log"
- access_log "github.com/eolinker/goku-api-gateway/goku-node/access-log"
- "github.com/eolinker/goku-api-gateway/goku-node/handler"
- "github.com/eolinker/goku-api-gateway/goku-node/plugin-flow"
- access_field "github.com/eolinker/goku-api-gateway/server/access-field"
- "net/http"
- "strconv"
- "strings"
- "time"
-
- "github.com/eolinker/goku-api-gateway/goku-node/common"
- monitor_write "github.com/eolinker/goku-api-gateway/server/monitor/monitor-write"
-
- gateway_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/gateway-manager"
- strategy_api_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/strategy-api-manager"
- strategy_api_plugin_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/strategy-api-plugin-manager"
- strategy_plugin_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/strategy-plugin-manager"
- node_common "github.com/eolinker/goku-api-gateway/goku-node/node-common"
- "github.com/eolinker/goku-api-gateway/goku-node/visit"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
- // "time"
-)
-
-// Router 路由
-type Router struct {
- mu map[string]http.HandlerFunc
-}
-
-func (mux *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- if r.RequestURI == "*" {
- if r.ProtoAtLeast(1, 1) {
- w.Header().Set("Connection", "close")
- }
- w.WriteHeader(http.StatusBadRequest)
- return
- }
- path := r.URL.Path
- h, has := mux.mu[path]
- if has {
- h.ServeHTTP(w, r)
- return
- }
- ServeHTTP(w, r)
-
-}
-
-// NewRouter 创建新路由
-func NewRouter() http.Handler {
-
- r := &Router{
- mu: make(map[string]http.HandlerFunc),
- }
-
- hs := handler.Handler()
-
- for _, h := range hs {
- r.mu[h.Pattern] = h.HandlerFunc
- }
-
- return r
-}
-
-var systemRequestPath = []string{"/oauth2/token", "/oauth2/authorize", "/oauth2/verify"}
-
-//ServeHTTP httpHandle
-func ServeHTTP(w http.ResponseWriter, req *http.Request) {
- defer func() {
- if err := recover(); err != nil {
- log.Warn(err)
- }
- }()
-
- timeStart := time.Now()
-
- logFields := make(log.Fields)
-
- // 记录访问次数
- requestID := GetRandomString(16)
-
- ctx := common.NewContext(req, requestID, w)
- proxyStatusCode := 0
-
- log.Debug(requestID, " url: ", req.URL.String())
- log.Debug(requestID, " header: ", ctx.RequestOrg.Header.String())
- rawBody, err := ctx.RequestOrg.RawBody()
- if err == nil {
- log.Debug(requestID, " body: ", string(rawBody))
- }
-
- defer func() {
- n, status := ctx.Finish()
-
- if ctx.ProxyResponseHandler != nil {
- proxyStatusCode = ctx.ProxyResponseHandler.StatusCode()
- }
- logFields[access_field.RequestID] = requestID
- logFields[access_field.StatusCode] = status
- logFields[access_field.HTTPUserAgent] = fmt.Sprint("\"", req.UserAgent(), "\"")
- logFields[access_field.HTTPReferer] = req.Referer()
- logFields[access_field.RequestTime] = time.Since(timeStart)
- logFields[access_field.Request] = fmt.Sprint("\"", req.Method, " ", req.URL.Path, " ", req.Proto, "\"")
- logFields[access_field.BodyBytesSent] = n
- logFields[access_field.Host] = req.Host
- access_log.Log(logFields)
- log.WithFields(logFields).Info()
-
- for _, path := range systemRequestPath {
- if path == req.URL.Path {
- return
- }
- }
- apiID := strconv.Itoa(ctx.ApiID())
-
- monitor_write.AddMonitor(ctx.StrategyId(), apiID, proxyStatusCode, ctx.StatusCode())
- }()
-
- remoteAddr := Intercept(req.RemoteAddr, ":")
- logFields[access_field.RemoteAddr] = remoteAddr
-
- if realIP := ctx.GetHeader("X-Real-Ip"); realIP == "" {
- ctx.ProxyRequest.SetHeader("X-Real-Ip", remoteAddr)
- logFields[access_field.HTTPXForwardedFor] = remoteAddr
- } else {
- logFields[access_field.HTTPXForwardedFor] = realIP
- }
-
- // 匹配URI前执行函数
- var isBefor bool
- start := time.Now()
- isBefor = pluginflow.BeforeMatch(ctx)
- log.Info(requestID, " BeforeMatch plugin duration:", time.Since(start))
- if !isBefor {
- log.Info(requestID, " stop by BeforeMatch plugin")
- return
- }
-
- var timeout, retryCount int
-
- strategyID, ok := retrieveStrategyID(ctx)
- if !ok {
- return
- }
-
- logFields[access_field.Strategy] = fmt.Sprintf("\"%s %s\"", strategyID, ctx.StrategyName())
-
- requestPath := req.URL.Path
- requestMenthod := ctx.Request().Method()
-
- var handleFunc []*entity.PluginHandlerExce
- apiInfo, splitURL, param, ok := strategy_api_manager.CheckAPIFromStrategy(strategyID, requestPath, req.Method)
- if ok {
- ctx.SetAPIID(apiInfo.APIID)
- retryCount = apiInfo.RetryCount
- //ctx.IsMatch = true
- timeout = apiInfo.Timeout
-
- ctx.ProxyRequest.SetTargetServer(fmt.Sprintf("%s://%s", apiInfo.Protocol, apiInfo.Target))
-
- targetURL := apiInfo.TargetURL + requestPath
-
- if apiInfo.StripPrefix {
- targetURL = apiInfo.TargetURL + splitURL
- }
- if apiInfo.StripSlash {
- targetURL = node_common.FilterSlash(targetURL)
- }
- if !apiInfo.IsFollow {
- ctx.ProxyRequest.Method = strings.ToUpper(apiInfo.TargetMethod)
- }
- targetURL = node_common.MatchRestful(targetURL, param)
-
- ctx.ProxyRequest.SetTargetURL(targetURL)
-
- handleFunc, _ = strategy_api_plugin_manager.GetPluginsOfAPI(strategyID, apiInfo.APIID)
-
- } else {
- handleFunc, _ = strategy_plugin_manager.GetPluginsOfStrategy(strategyID)
- }
- start = time.Now()
- isAccess, _ := pluginflow.AccessFunc(ctx, handleFunc)
- log.Info(requestID, " Access plugin duration:", time.Since(start))
- if !isAccess {
-
- // todo
- return
- }
-
- if apiInfo == nil {
- log.Info(requestID, " URL dose not exist!")
- ctx.SetStatus(404, "404")
- ctx.SetBody([]byte("[ERROR]URL dose not exist!"))
-
- return
- }
- logFields[access_field.API] = fmt.Sprintf("\"%d %s\"", apiInfo.APIID, apiInfo.APIName)
- logFields[access_field.Proxy] = fmt.Sprintf("\"%s %s %s\"", ctx.ProxyRequest.Method, ctx.ProxyRequest.TargetURL(), apiInfo.Protocol)
- logFields[access_field.Balance] = apiInfo.Target
- start = time.Now()
- response, err := CreateRequest(ctx, apiInfo, timeout, retryCount)
- log.Info(requestID, " Proxy request duration:", time.Since(start))
- if err != nil {
- log.Warn(err.Error())
- }
- logFields[access_field.FinallyServer] = ctx.FinalTargetServer()
- logFields[access_field.Retry] = ctx.RetryTargetServers()
- ctx.SetProxyResponse(response)
- form, _ := ctx.RequestOrg.BodyForm()
- if response == nil {
- proxyStatusCode = -1
- // ctx.Proxy
- go visit.UpdateProxyFailureCount(apiInfo,
- requestMenthod, ctx.ProxyRequest.Method,
- ctx.RequestOrg.Headers(),
- ctx.RequestOrg.URL().Query(),
- form,
- 504,
- make(map[string][]string),
-
- ctx)
- } else {
- logFields[access_field.ProxyStatusCode] = response.StatusCode
- // w.WriteHeader(ctx.ProxyStatusCode)
- if !gateway_manager.IsSucess(ctx.StatusCode()) {
- go visit.UpdateProxyFailureCount(
- apiInfo,
- requestMenthod,
- ctx.ProxyRequest.Method,
- ctx.RequestOrg.Headers(),
- ctx.RequestOrg.URL().Query(),
- form,
- ctx.ProxyResponseHandler.StatusCode(),
- ctx.ProxyResponseHandler.Headers(),
- ctx)
- }
- }
-
- start = time.Now()
- isProxy, _ := pluginflow.ProxyFunc(ctx, handleFunc)
- log.Info(requestID, " Proxy plugin Duration:", time.Since(start))
- if !isProxy {
- return
- }
- // 默认返回插件未开启时,直接返回回复相关内容
- if response != nil {
-
- } else {
- ctx.SetStatus(504, "504")
- ctx.SetBody([]byte("[ERROR]Fail to get response after proxy!"))
- }
-
- //logFunc(ctx, handleFunc)
-
- return
-}
diff --git a/goku-node/server.go b/goku-node/server.go
deleted file mode 100644
index 442e9adbfab7b551877a6b193d52d4b9f89d2e1b..0000000000000000000000000000000000000000
--- a/goku-node/server.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package gokunode
-
-import (
- log "github.com/eolinker/goku-api-gateway/goku-log"
- config_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/config-manager"
- "github.com/eolinker/goku-api-gateway/goku-node/manager/updater"
- node_common "github.com/eolinker/goku-api-gateway/goku-node/node-common"
- monitor_write "github.com/eolinker/goku-api-gateway/server/monitor/monitor-write"
-
- goku_plugin "github.com/eolinker/goku-plugin"
- redis_plugin_proxy "github.com/eolinker/goku-api-gateway/goku-node/redis-plugin-proxy"
-
- "github.com/eolinker/goku-api-gateway/goku-service/discovery"
- "strings"
-)
-
-//InitPluginUtils 初始化插件工具
-func InitPluginUtils() {
- goku_plugin.SetRedisManager(redis_plugin_proxy.Create())
- goku_plugin.InitLog(log.GetLogger())
- //goku_plugin.SetLog(new(log_plugin_proxy.LoggerGeneral))
-}
-
-//InitDiscovery 初始化服务发现
-func InitDiscovery() {
-
- all := discovery.AllDrivers()
- log.Infof("install service discovery driver:[%s]\n", strings.Join(all, ","))
-}
-
-//InitLog 初始化日志模块
-func InitLog() {
- config_manager.InitLog()
-}
-
-//InitServer 初始化Server
-func InitServer() {
- log.Debug("init InitServer start")
-
- InitPluginUtils()
-
- log.Debug("init InitPluginUtils done")
- InitDiscovery()
- log.Debug("init InitDiscovery done")
- // 注册自动更新,并保证第一次全量拉取完数据
- updater.InitUpdate()
-
- //// 执行插件初始化函数
- // 插件初始化放在 plugin-manager中
- log.Debug("init updater.InitUpdate done")
-
- monitor_write.InitMonitorWrite(node_common.ClusterName())
- log.Debug("init server done")
-}
diff --git a/goku-node/strategy.go b/goku-node/strategy.go
deleted file mode 100644
index 1fea636966c9dcaa08af10b6e932e5a99e96511b..0000000000000000000000000000000000000000
--- a/goku-node/strategy.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package gokunode
-
-import (
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "github.com/eolinker/goku-api-gateway/goku-node/common"
- strategy_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/strategy-manager"
-)
-
-func getStrateyID(ctx *common.Context) string {
- if value := ctx.Request().GetHeader("Strategy-Id"); value != "" {
- return value
- }
- if value := ctx.Request().URL().Query().Get("Strategy-Id"); value != "" {
- return value
- }
- if value := ctx.Request().GetForm("Strategy-Id"); value != "" {
- return value
- }
-
- return ""
-}
-
-func retrieveStrategyID(ctx *common.Context) (string, bool) {
- strategyID := getStrateyID(ctx)
-
- if strategyID == "" {
- if v, ok := strategy_manager.GetAnonymous(); ok {
- strategyID = v.StrategyID
- ctx.SetStrategyName(v.StrategyName)
- ctx.SetStrategyId(strategyID)
-
- } else {
- go log.Info("[ERROR]Missing Strategy ID!")
- ctx.SetStatus(500, "500")
-
- ctx.SetBody([]byte("[ERROR]Missing Strategy ID!"))
- return strategyID, false
- }
- } else {
-
- // 快速查找策略ID
- if v, ok := strategy_manager.Get(strategyID); ok {
-
- if v.EnableStatus != 1 {
-
- go log.Info("[ERROR]StrategyID is out of service!")
-
- ctx.SetStatus(500, "500")
-
- ctx.SetBody([]byte("[ERROR]StrategyID is out of service!"))
- return strategyID, false
- }
-
- ctx.SetStrategyName(v.StrategyName)
- ctx.SetStrategyId(strategyID)
- } else {
- go log.Info("[ERROR]StrategyID dose not exist!")
-
- ctx.SetStatus(500, "500")
-
- ctx.SetBody([]byte("[ERROR]StrategyID dose not exist!"))
- return strategyID, false
- }
- }
- return strategyID, true
-}
diff --git a/goku-node/visit/visit.go b/goku-node/visit/visit.go
deleted file mode 100644
index 3d3e4db344cfbf2ce8369e02efd6613dcbf7410c..0000000000000000000000000000000000000000
--- a/goku-node/visit/visit.go
+++ /dev/null
@@ -1,247 +0,0 @@
-package visit
-
-import (
- "encoding/json"
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "github.com/eolinker/goku-api-gateway/goku-node/common"
- "strconv"
- "time"
-
- node_common "github.com/eolinker/goku-api-gateway/goku-node/node-common"
-
- redis_manager "github.com/eolinker/goku-api-gateway/common/redis-manager"
- cmd2 "github.com/eolinker/goku-api-gateway/goku-node/cmd"
- gateway_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/gateway-manager"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
- jsoniter "github.com/json-iterator/go"
-)
-
-type alertInfo struct {
- AlertAddr string `json:"alertAddr"`
- AlertPeriodType int `json:"alertPeriodType"`
- ReceiveList string `json:"receiveList"`
-}
-
-//UpdateProxyFailureCount 更新网关转发失败次数
-func UpdateProxyFailureCount(apiInfo *entity.APIExtend,
- requestMethod string,
- proxyMethod string,
- headers map[string][]string,
- queryParams map[string][]string,
- formParams map[string][]string,
- responseStatus int,
- responseHeader map[string][]string,
-
- ctx *common.Context) (bool, string, error) {
- redisConn := redis_manager.GetConnection()
- var (
- alertAddress string
- alertStatus int
- alertPeriodType int
- )
- alertStatus = gateway_manager.GetAlertStatus()
-
- if alertStatus == 0 || apiInfo.AlertValve == 0 {
- return true, "", nil
- } else {
- info := gateway_manager.GetAlertInfo()
- alertJson := alertInfo{}
- err := json.Unmarshal([]byte(info), &alertJson)
- if err != nil {
- return false, err.Error(), err
- }
-
- clusterName := node_common.ClusterName()
- alertPeriodType = alertJson.AlertPeriodType
- alertAddress = alertJson.AlertAddr
- for {
- rep, err := redisConn.SetNX(clusterName+":lock", 1, 3*time.Second).Result()
- if err != nil {
- log.Info(err)
- return false, "", err
- }
- if rep {
- break
- }
- }
-
- // 获取当前告警时间信息
- redisKey := clusterName + ":gokuFailureCount:" + strconv.Itoa(apiInfo.APIID)
- // 获取key信息
- result, err := redisConn.Get(redisKey).Result()
- if err != nil {
- if err.Error() != "redis: nil" {
- log.Info(err)
- return false, "", err
- }
- }
- var expire int = 60
- if alertPeriodType == 1 {
- expire = 5 * 60
- } else if alertPeriodType == 2 {
- expire = 15 * 60
- } else if alertPeriodType == 3 {
- expire = 30 * 60
- } else if alertPeriodType == 4 {
- expire = 60 * 60
- }
-
- var json = jsoniter.ConfigCompatibleWithStandardLibrary
- headerList, err := json.Marshal(headers)
- if err != nil {
- log.Info(err)
- return false, "", err
- }
- queryParamList, err := json.Marshal(queryParams)
- if err != nil {
- log.Info(err)
- return false, "", err
- }
- formParamsList, err := json.Marshal(formParams)
- if err != nil {
- log.Info(err)
- return false, "", err
- }
- responseHeaderList, err := json.Marshal(responseHeader)
- if err != nil {
- log.Info(err)
- return false, "", err
- }
-
- var count int = 0
-
- if result == "" {
- _, err = redisConn.SetNX(redisKey, 1, time.Duration(expire)*time.Second).Result()
- if err != nil {
- log.Info(err)
-
- return false, "", err
- }
- count = 1
- } else {
- count, err = strconv.Atoi(result)
- if err != nil {
- log.Info(err)
-
- return false, "", err
- }
- }
-
- if count >= apiInfo.AlertValve {
-
- _, _, _ = cmd2.AddAlertMessage(apiInfo.APIID,
- apiInfo.APIName,
- apiInfo.RequestURL,
- ctx.FinalTargetServer(),
- apiInfo.TargetURL,
- requestMethod,
- proxyMethod,
- string(headerList),
- string(queryParamList),
- string(formParamsList),
- string(responseHeaderList),
- alertPeriodType,
- apiInfo.AlertValve,
- responseStatus,
- "true",
- ctx.StrategyId(),
- ctx.StrategyName(),
- ctx.RequestId())
- AlertLog(
- apiInfo.RequestURL,
- ctx.FinalTargetServer(),
- apiInfo.TargetURL,
- requestMethod,
- proxyMethod,
- string(headerList),
- string(queryParamList),
- string(formParamsList),
- string(responseHeaderList),
- responseStatus,
- ctx.StrategyId(),
- ctx.StrategyName(),
- ctx.RequestId())
-
- period := "1"
- if alertPeriodType == 1 {
- period = "5"
- } else if alertPeriodType == 2 {
- period = "15"
- } else if alertPeriodType == 3 {
- period = "30"
- } else if alertPeriodType == 4 {
- period = "60"
- }
- msg := "[Alert] GoKu Gateway failed to proxy requests for " + period + " minute " + strconv.Itoa(apiInfo.AlertValve) + " times"
- cmd2.SendRequestToAlertAddress(alertAddress, apiInfo.RequestURL, ctx.FinalTargetServer(), apiInfo.TargetURL, msg, apiInfo.APIName, apiInfo.APIID)
-
- _, err = redisConn.Set(redisKey, 1, time.Duration(expire)*time.Second).Result()
- if err != nil {
- log.Info(err)
- }
- } else {
- _, _, _ = cmd2.AddAlertMessage(
- apiInfo.APIID,
- apiInfo.APIName,
- apiInfo.RequestURL,
- ctx.FinalTargetServer(),
- apiInfo.TargetURL,
- requestMethod,
- proxyMethod,
- string(headerList),
- string(queryParamList),
- string(formParamsList),
- string(responseHeaderList),
- alertPeriodType,
- apiInfo.AlertValve,
- responseStatus,
- "false",
- ctx.StrategyId(),
- ctx.StrategyName(),
- ctx.RequestId())
- AlertLog(
- apiInfo.RequestURL,
- ctx.FinalTargetServer(),
- apiInfo.TargetURL,
- apiInfo.RequestMethod,
- apiInfo.TargetMethod,
- string(headerList),
- string(queryParamList),
- string(formParamsList),
- string(responseHeaderList),
- responseStatus,
- ctx.StrategyId(),
- ctx.StrategyName(),
- ctx.RequestId())
- if _, err := redisConn.Incr(redisKey).Result(); err != nil {
-
- return false, err.Error(), err
- }
- }
- redisConn.Del("lock")
- return true, "", nil
- }
-}
-
-//AlertLog 记录告警日志
-func AlertLog(requestURL, targetServer, targetURL, requestMethod, proxyMethod, headerList, queryParamList, formParamList, responseHeaderList string, responseStatus int, strategyID string, strategyName, requestID string) {
- log.WithFields(log.Fields{
- "request_id": requestID,
- "strategy_name": strategyName,
- "strategy_id": strategyID,
- "request_method": requestMethod,
- "request_url": requestURL,
- "target_method": proxyMethod,
- "target_server": targetServer,
- "target_url": targetURL,
- "request_query": queryParamList,
- "request_header": headerList,
- "request_form_param": formParamList,
- "response_statusCode": strconv.Itoa(responseStatus),
- "response_header": responseHeaderList,
- }).Warning("alert")
-
- //_= logutils.Log("log/alertLog", "alert", log.PeriodDay, logInfo)
-
- return
-}
diff --git a/goku-service/application/application.go b/goku-service/application/application.go
index d169a52b426ac2df968b79d63aa29ed10b9a7f46..2f0567a68a218b0e5a6b0e471dda19862a6af434 100644
--- a/goku-service/application/application.go
+++ b/goku-service/application/application.go
@@ -6,6 +6,7 @@ import (
"time"
)
+//IHttpApplication iHttpApplication
type IHttpApplication interface {
Send(Proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error)
}
diff --git a/goku-service/application/org.go b/goku-service/application/org.go
index c149e05f1c008b86c39cfc872cbf0bc624e8aa6a..469eca1318997bd2aaa17d084451167ab98afc2a 100644
--- a/goku-service/application/org.go
+++ b/goku-service/application/org.go
@@ -2,21 +2,23 @@ package application
import (
"fmt"
- "github.com/eolinker/goku-api-gateway/utils"
"net/http"
"net/url"
"time"
+
+ "github.com/eolinker/goku-api-gateway/utils"
)
+//Org org
type Org struct {
server string
}
-// 忽略重试
+//Send 请求发送,忽略重试
func (app *Org) Send(proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) {
- var response *http.Response = nil
- var err error = nil
+ var response *http.Response
+ var err error
FinalTargetServer := ""
RetryTargetServers := make([]string, 0, retry+1)
@@ -39,6 +41,7 @@ func (app *Org) Send(proto string, method string, path string, querys url.Values
return response, FinalTargetServer, RetryTargetServers, err
}
+//NewOrg 创建新的IHttpApplication
func NewOrg(server string) IHttpApplication {
return &Org{
server: server,
diff --git a/goku-service/application/r.go b/goku-service/application/r.go
index 902ca73c6f65f581f674ef4401b1430d41282aec..3e58a60215e58a6dbed8ffa1151fd428aed15f81 100644
--- a/goku-service/application/r.go
+++ b/goku-service/application/r.go
@@ -18,15 +18,24 @@ func request(method string, backendDomain string, query url.Values, header http.
return nil, err
}
+ u.Query()
req, err := NewRequest(method, u)
if err != nil {
return nil, err
}
+ queryDest:= u.Query()
+ if query!= nil{
+ for k,vs:=range query{
+ for _,v:=range vs{
+ queryDest.Add(k,v)
+ }
+ }
+ }
req.headers = header
- req.queryParams = query
+ req.queryParams = queryDest
req.SetRawBody(body)
if timeout != 0 {
diff --git a/goku-service/application/request.go b/goku-service/application/request.go
index 21ba0ea23eb3e536fab7515656b6e3aa73a2583b..c2f9d605f8af32a10a0b80c1306a0d22104321e3 100644
--- a/goku-service/application/request.go
+++ b/goku-service/application/request.go
@@ -6,12 +6,15 @@ import (
"io"
"net/http"
"net/url"
+
// "fmt"
"time"
)
-var Version string = "2.0"
+//Version 版本号
+var Version = "2.0"
+//Request request
type Request struct {
client *http.Client
method string
@@ -24,7 +27,7 @@ type Request struct {
timeout time.Duration
}
-// 创建新请求
+//NewRequest 创建新请求
func NewRequest(method string, URL *url.URL) (*Request, error) {
if method != "GET" && method != "POST" && method != "PUT" && method != "DELETE" &&
method != "HEAD" && method != "OPTIONS" && method != "PATCH" {
@@ -33,7 +36,6 @@ func NewRequest(method string, URL *url.URL) (*Request, error) {
return newRequest(method, URL)
}
-//
func newRequest(method string, URL *url.URL) (*Request, error) {
var urlPath string
queryParams := make(map[string][]string)
@@ -51,58 +53,56 @@ func newRequest(method string, URL *url.URL) (*Request, error) {
return r, nil
}
-// 设置请求头
-func (this *Request) SetHeader(key string, values ...string) {
+//SetHeader 设置请求头
+func (r *Request) SetHeader(key string, values ...string) {
if len(values) > 0 {
- this.headers[key] = values[:]
+ r.headers[key] = values[:]
} else {
- delete(this.headers, key)
+ delete(r.headers, key)
}
}
-// 获取请求头
-func (this *Request) Headers() map[string][]string {
+//Headers 获取请求头
+func (r *Request) Headers() map[string][]string {
headers := make(map[string][]string)
- for key, values := range this.headers {
+ for key, values := range r.headers {
headers[key] = values[:]
}
return headers
}
-// 设置Query参数
-func (this *Request) SetQueryParam(key string, values ...string) {
+//SetQueryParam 设置Query参数
+func (r *Request) SetQueryParam(key string, values ...string) {
if len(values) > 0 {
- this.queryParams[key] = values[:]
+ r.queryParams[key] = values[:]
} else {
- delete(this.queryParams, key)
+ delete(r.queryParams, key)
}
}
-// 设置请求超时时间
-func (this *Request) SetTimeout(timeout time.Duration) {
- this.timeout = timeout
+//SetTimeout 设置请求超时时间
+func (r *Request) SetTimeout(timeout time.Duration) {
+ r.timeout = timeout
}
//// 获取请求超时时间
-//func (this *Request) GetTimeout() time.Duration {
-// return this.timeout
+//func (r *Request) GetTimeout() time.Duration {
+// return r.timeout
//}
-// 发送请求
-func (this *Request) Send() (*http.Response, error) {
+//Send 发送请求
+func (r *Request) Send() (*http.Response, error) {
// now := time.Now()
- req, err := this.parseBody()
- // fmt.Println("Parse body",time.Since(now))
+ req, err := r.parseBody()
if err != nil {
return nil, err
}
req.Header.Set("Accept-Encoding", "gzip")
- // now = time.Now()
- req.Header = parseHeaders(this.headers)
+ req.Header = parseHeaders(r.headers)
- this.client.Timeout = this.timeout
+ r.client.Timeout = r.timeout
- httpResponse, err := this.client.Do(req)
+ httpResponse, err := r.client.Do(req)
if err != nil {
return nil, err
@@ -111,32 +111,31 @@ func (this *Request) Send() (*http.Response, error) {
}
-// 获取query参数
-func (this *Request) QueryParams() map[string][]string {
+//QueryParams 获取query参数
+func (r *Request) QueryParams() map[string][]string {
params := make(map[string][]string)
- for key, values := range this.queryParams {
+ for key, values := range r.queryParams {
params[key] = values[:]
}
return params
}
-// 获取完整的URL路径
-func (this *Request) URLPath() string {
- if len(this.queryParams) > 0 {
- return this.URL + "?" + parseParams(this.queryParams).Encode()
- } else {
- return this.URL
+//URLPath 获取完整的URL路径
+func (r *Request) URLPath() string {
+ if len(r.queryParams) > 0 {
+ return r.URL + "?" + parseParams(r.queryParams).Encode()
}
+ return r.URL
}
-// 设置URL
-func (this *Request) SetURL(url string) {
- this.URL = url
+//SetURL 设置URL
+func (r *Request) SetURL(url string) {
+ r.URL = url
}
-// 设置源数据
-func (this *Request) SetRawBody(body []byte) {
- this.body = body
+//SetRawBody 设置源数据
+func (r *Request) SetRawBody(body []byte) {
+ r.body = body
}
// 解析请求头
@@ -160,66 +159,15 @@ func parseHeaders(headers map[string][]string) http.Header {
}
// 解析请求体
-func (this *Request) parseBody() (req *http.Request, err error) {
- var body io.Reader = nil
- if len(this.body) > 0 {
- body = bytes.NewBuffer(this.body)
+func (r *Request) parseBody() (req *http.Request, err error) {
+ var body io.Reader
+ if len(r.body) > 0 {
+ body = bytes.NewBuffer(r.body)
}
- req, err = http.NewRequest(this.method, this.URLPath(), body)
+ req, err = http.NewRequest(r.method, r.URLPath(), body)
return
- //if this.method == "GET" || this.method == "TRACE" {
- // req, err = http.NewRequest(this.method, this.URLPath(), nil)
- //}
- //
- //if len(this.body) > 0 {
- //
- // if this.isJSON {
- // if _, ok := this.headers["Content-Type"]; !ok {
- // this.headers["Content-Type"] = []string{"application/json"}
- // }
- // req, err = http.NewRequest(this.method, this.URLPath(),
- // strings.NewReader(string(this.body)))
- // } else {
- // var body *bytes.Buffer
- // body = bytes.NewBuffer(this.body)
- //
- // }
- //} else if len(this.files) > 0 {
- // body := new(bytes.Buffer)
- // writer := multipart.NewWriter(body)
- // var part io.Writer
- // for fieldname, file := range this.files {
- // part, err = writer.CreateFormFile(fieldname, file.filename)
- // if err != nil {
- // return
- // }
- // _, err = part.Write(file.data)
- // if err != nil {
- // return
- // }
- // }
- // for fieldname, values := range this.formParams {
- // temp := make(map[string][]string)
- // temp[fieldname] = values
- // value := parseParams(temp).Encode()
- // err = writer.WriteField(fieldname, value)
- // if err != nil {
- // return
- // }
- // }
- // err = writer.Close()
- // if err != nil {
- // return
- // }
- // this.headers["Content-Type"] = []string{writer.FormDataContentType()}
- // req, err = http.NewRequest(this.method, this.URLPath(), body)
- //} else {
- // this.headers["Content-Type"] = []string{"application/x-www-form-urlencoded"}
- // req, err = http.NewRequest(this.method, this.URLPath(),
- // strings.NewReader(parseParams(this.formParams).Encode()))
- //}
- //return
+
}
// 解析参数
diff --git a/goku-service/application/service.go b/goku-service/application/service.go
index 6db0865e02c184571a07a46713e364e3868159fd..80d69145863d0f946d544d553dd87a9aaf6b537d 100644
--- a/goku-service/application/service.go
+++ b/goku-service/application/service.go
@@ -2,19 +2,22 @@ package application
import (
"fmt"
- "github.com/eolinker/goku-api-gateway/goku-service/common"
- "github.com/eolinker/goku-api-gateway/goku-service/health"
- "github.com/eolinker/goku-api-gateway/utils"
"net/http"
"net/url"
"time"
+
+ "github.com/eolinker/goku-api-gateway/goku-service/common"
+ "github.com/eolinker/goku-api-gateway/goku-service/health"
+ "github.com/eolinker/goku-api-gateway/utils"
)
+//Application 应用
type Application struct {
service *common.Service
healthCheckHandler health.CheckHandler
}
+//NewApplication 创建Application
func NewApplication(service *common.Service, healthCheckHandler health.CheckHandler) *Application {
return &Application{
service: service,
@@ -22,10 +25,12 @@ func NewApplication(service *common.Service, healthCheckHandler health.CheckHand
}
}
+
+//Send send
func (app *Application) Send(proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) {
- var response *http.Response = nil
- var err error = nil
+ var response *http.Response
+ var err error
FinalTargetServer := ""
RetryTargetServers := make([]string, 0, retry+1)
@@ -39,9 +44,13 @@ func (app *Application) Send(proto string, method string, path string, querys ur
return nil, FinalTargetServer, RetryTargetServers, fmt.Errorf("not found instance for app:%s", app.service.Name)
}
- FinalTargetServer = fmt.Sprintf("%s:%d", instance.IP, instance.Port)
+ FinalTargetServer = instance.IP
+ if instance.Port != 0 {
+ FinalTargetServer = fmt.Sprintf("%s:%d", instance.IP, instance.Port)
+ }
+
RetryTargetServers = append(RetryTargetServers, FinalTargetServer)
- u := fmt.Sprintf("%s://%s:%d/%s", proto, instance.IP, instance.Port, path)
+ u := fmt.Sprintf("%s://%s/%s", proto, FinalTargetServer, path)
response, err = request(method, u, querys, header, body, timeout)
if err != nil {
diff --git a/goku-service/balance/balance.go b/goku-service/balance/balance.go
index 15fcfd68f4fad8ebf2378bf00d5a1fb17ffb82c8..c8c95da0a1792d595715fc6c1cefb07b2c2a56ec 100644
--- a/goku-service/balance/balance.go
+++ b/goku-service/balance/balance.go
@@ -1,7 +1,7 @@
package balance
-type Balance struct {
- Name string
- Discovery string
- AppConfig string
-}
+//type Balance struct {
+// Name string
+// Discovery string
+// AppConfig string
+//}
diff --git a/goku-service/balance/discovery.go b/goku-service/balance/discovery.go
index 6fcda4596a7b184439d1df155fe51ae8115ded3d..0af67504fe6bf81b711ee4c86abbfab99185dc78 100644
--- a/goku-service/balance/discovery.go
+++ b/goku-service/balance/discovery.go
@@ -1,33 +1,27 @@
package balance
import (
+ "github.com/eolinker/goku-api-gateway/config"
"github.com/eolinker/goku-api-gateway/goku-service/application"
"github.com/eolinker/goku-api-gateway/goku-service/discovery"
)
-func ResetBalances(balances []*Balance) {
-
- bmap := make(map[string]*Balance)
-
- for _, b := range balances {
- bmap[b.Name] = b
-
- }
-
- manager.set(bmap)
-
+//ResetBalances 重置负载列表
+func ResetBalances(balances map[string]*config.BalanceConfig) {
+ manager.set(balances)
}
+//GetByName 通过名称获取负载
func GetByName(name string) (application.IHttpApplication, bool) {
b, has := manager.get(name)
if !has {
return application.NewOrg(name), true
}
- sources, has := discovery.GetDiscoverer(b.Discovery)
+ sources, has := discovery.GetDiscoverer(b.DiscoverName)
if has {
- service, handler, yes := sources.GetApp(b.AppConfig)
+ service, handler, yes := sources.GetApp(b.Config)
if yes {
return application.NewApplication(service, handler), true
}
diff --git a/goku-service/balance/manager.go b/goku-service/balance/manager.go
index 48d003d273a2b91b65595ea5e9c8a1d8e6d40604..683164d9beebe2d13d482644fbc10f622002a443 100644
--- a/goku-service/balance/manager.go
+++ b/goku-service/balance/manager.go
@@ -2,25 +2,28 @@ package balance
import (
"sync"
+
+ "github.com/eolinker/goku-api-gateway/config"
)
var manager = &Manager{
locker: sync.RWMutex{},
- balances: make(map[string]*Balance),
+ balances: make(map[string]*config.BalanceConfig),
}
+//Manager manager
type Manager struct {
locker sync.RWMutex
- balances map[string]*Balance
+ balances map[string]*config.BalanceConfig
}
-func (m *Manager) set(balances map[string]*Balance) {
+func (m *Manager) set(balances map[string]*config.BalanceConfig) {
m.locker.Lock()
m.balances = balances
m.locker.Unlock()
}
-func (m *Manager) get(name string) (*Balance, bool) {
+func (m *Manager) get(name string) (*config.BalanceConfig, bool) {
m.locker.RLock()
b, has := m.balances[name]
diff --git a/goku-service/common/factory.go b/goku-service/common/factory.go
index 01c92dc346e98bc7d2ba472067299c3e67be9a2d..feee0c0fa991987e307601141f3750c785c71505 100644
--- a/goku-service/common/factory.go
+++ b/goku-service/common/factory.go
@@ -5,11 +5,13 @@ import (
"sync"
)
+//InstanceFactory instanceFactory
type InstanceFactory struct {
locker sync.RWMutex
instances map[string]*Instance
}
+//NewInstanceFactory 创建InstanceFactory
func NewInstanceFactory() *InstanceFactory {
return &InstanceFactory{
locker: sync.RWMutex{},
@@ -17,6 +19,7 @@ func NewInstanceFactory() *InstanceFactory {
}
}
+//General general
func (m *InstanceFactory) General(ip string, port int, weight int) *Instance {
if weight < 1 {
weight = 1
@@ -38,7 +41,7 @@ func (m *InstanceFactory) General(ip string, port int, weight int) *Instance {
return i
}
i = &Instance{
- InstanceId: fmt.Sprintf("%s:%d", ip, port),
+ InstanceID: fmt.Sprintf("%s:%d", ip, port),
IP: ip,
Port: port,
Weight: weight,
diff --git a/goku-service/common/instance.go b/goku-service/common/instance.go
index 9abbbf382f03bd85109dbb24c858694823d106af..e312870bf88de7579e49ada66a8fba16002aa360 100644
--- a/goku-service/common/instance.go
+++ b/goku-service/common/instance.go
@@ -2,14 +2,17 @@ package common
import "sync"
+//Instance instance
type Instance struct {
- InstanceId string
+ InstanceID string
IP string
Port int
Weight int
Status InstanceStatus
locker sync.RWMutex
}
+
+//PInstances PInstances
type PInstances []*Instance
func (p PInstances) Len() int {
@@ -24,6 +27,7 @@ func (p PInstances) Swap(i, j int) {
p[i], p[j] = p[j], p[i]
}
+//CheckStatus checkStatus
func (i *Instance) CheckStatus(status InstanceStatus) bool {
i.locker.RLock()
b := i.Status == status
diff --git a/goku-service/common/service.go b/goku-service/common/service.go
index 6789f3881eaeda656509c4fe3122386b205620a9..c3b65459f764e2e48312466070a0cd141ead355b 100644
--- a/goku-service/common/service.go
+++ b/goku-service/common/service.go
@@ -6,6 +6,7 @@ import (
"sync"
)
+//Service service
type Service struct {
Name string
instances []*Instance
@@ -13,6 +14,7 @@ type Service struct {
locker sync.RWMutex
}
+//NewService 创建Service
func NewService(name string, Instances []*Instance) *Service {
return &Service{
Name: name,
@@ -22,6 +24,7 @@ func NewService(name string, Instances []*Instance) *Service {
}
}
+//SetInstances setInstances
func (s *Service) SetInstances(instances []*Instance) {
sort.Sort(sort.Reverse(PInstances(instances)))
@@ -36,6 +39,7 @@ func (s *Service) SetInstances(instances []*Instance) {
//}
}
+//Weighting weighting
func (s *Service) Weighting() (*Instance, int, bool) {
s.locker.RLock()
instances := s.instances
@@ -66,6 +70,7 @@ func (s *Service) Weighting() (*Instance, int, bool) {
return nil, 0, false
}
+//Next next
func (s *Service) Next(lastIndex int) (*Instance, int, bool) {
if lastIndex == -1 {
return s.Weighting()
diff --git a/goku-service/common/status.go b/goku-service/common/status.go
index a6567c22b9826efade81892ef7b7088e15fdb69e..b6fdfde1421b03670c518ac849391ba200a67f07 100644
--- a/goku-service/common/status.go
+++ b/goku-service/common/status.go
@@ -2,11 +2,15 @@ package common
import "strings"
+//InstanceStatus instanceStanceStatus
type InstanceStatus int
const (
+ //InstanceRun run
InstanceRun = iota
+ //InstanceDown down
InstanceDown
+ //InstanceChecking check
InstanceChecking
)
@@ -22,6 +26,7 @@ func (status InstanceStatus) String() string {
return "unkown"
}
+//ParseStatus parseStatus
func ParseStatus(status string) InstanceStatus {
s := strings.ToLower(status)
diff --git a/goku-service/discovery/config.go b/goku-service/discovery/config.go
index 3a0243921bd8f5e2f9b4654ed699e8f64c3d8e1c..acf42edc50a39c9dad245b77a717290583833c73 100644
--- a/goku-service/discovery/config.go
+++ b/goku-service/discovery/config.go
@@ -1,15 +1,2 @@
package discovery
-type HealthCheckConfig struct {
- IsHealthCheck bool
- Url string
- Second int
- TimeOutMill int
- StatusCode string
-}
-type Config struct {
- Name string
- Driver string
- Config string
- HealthCheckConfig
-}
diff --git a/goku-service/discovery/discovery.go b/goku-service/discovery/discovery.go
index 3334e384df328bc38b650f4c322d2f58eb1c9f5b..d43301b218163adfdece6d859250e90cd28ca766 100644
--- a/goku-service/discovery/discovery.go
+++ b/goku-service/discovery/discovery.go
@@ -4,6 +4,7 @@ import (
"github.com/eolinker/goku-api-gateway/goku-service/common"
)
+//Discovery discovery
type Discovery interface {
SetConfig(config string) error
Driver() string
diff --git a/goku-service/discovery/driver-manager.go b/goku-service/discovery/driver-manager.go
index babc47ac6591f7e9b5174c5c9ad369e08a231e16..2115f692e5910bb6d8458ba892c5a7597085e7e1 100644
--- a/goku-service/discovery/driver-manager.go
+++ b/goku-service/discovery/driver-manager.go
@@ -1,8 +1,9 @@
package discovery
import (
- log "github.com/eolinker/goku-api-gateway/goku-log"
"strings"
+
+ log "github.com/eolinker/goku-api-gateway/goku-log"
)
var (
@@ -11,6 +12,7 @@ var (
driverNames = make([]string, 0)
)
+//AllDrivers allDrivers
func AllDrivers() []string {
return driverNames
}
@@ -23,6 +25,7 @@ func AllDrivers() []string {
// isLock=true
//}
+//RegisteredDiscovery registerdDiscovery
func RegisteredDiscovery(name string, driver Driver) {
//if isLock{
diff --git a/goku-service/discovery/drivers.go b/goku-service/discovery/drivers.go
index 1f1724b977af96aeae68f367ca5f6fd4d1e0eff4..9ff5c90585a45226590d44c32c133644b899dcb3 100644
--- a/goku-service/discovery/drivers.go
+++ b/goku-service/discovery/drivers.go
@@ -2,18 +2,22 @@ package discovery
import "sync"
+//Driver driver
type Driver interface {
Open(name string, config string) (ISource, error)
}
+//CreateHandler createHandler
type CreateHandler func(config string) Discovery
+//DriverBase driverBase
type DriverBase struct {
createFunc CreateHandler
locker sync.RWMutex
sources map[string]*SourceDiscovery
}
+//NewDriver newDriver
func NewDriver(createFunc CreateHandler) *DriverBase {
return &DriverBase{
createFunc: createFunc,
@@ -22,6 +26,7 @@ func NewDriver(createFunc CreateHandler) *DriverBase {
}
}
+//Open open
func (d *DriverBase) Open(name string, config string) (ISource, error) {
d.locker.RLock()
diff --git a/goku-service/discovery/manager.go b/goku-service/discovery/manager.go
index ad060f680774fce137c10b0543beb8f6de8d3e93..3a01ca91f66ddc620ccab497f5cf0ed43245145d 100644
--- a/goku-service/discovery/manager.go
+++ b/goku-service/discovery/manager.go
@@ -1,8 +1,10 @@
package discovery
import (
- log "github.com/eolinker/goku-api-gateway/goku-log"
"sync"
+
+ "github.com/eolinker/goku-api-gateway/config"
+ log "github.com/eolinker/goku-api-gateway/goku-log"
)
var manager = &Manager{
@@ -10,13 +12,15 @@ var manager = &Manager{
sources: make(map[string]ISource),
}
+//Manager manager
type Manager struct {
locker sync.RWMutex
sources map[string]ISource
}
-func ResetAllServiceConfig(confs []*Config) {
+//ResetAllServiceConfig resetAllServiceConfig
+func ResetAllServiceConfig(confs map[string]*config.DiscoverConfig) {
sources := make(map[string]ISource)
manager.locker.RLock()
@@ -48,7 +52,7 @@ func ResetAllServiceConfig(confs []*Config) {
}
sources[name] = s
- s.SetHealthConfig(&conf.HealthCheckConfig)
+ s.SetHealthConfig(conf.HealthCheck)
err := s.SetDriverConfig(conf.Config)
@@ -68,6 +72,7 @@ func ResetAllServiceConfig(confs []*Config) {
manager.locker.Unlock()
}
+//GetDiscoverer getDiscoverer
func GetDiscoverer(discoveryName string) (ISource, bool) {
manager.locker.RLock()
s, has := manager.sources[discoveryName]
diff --git a/goku-service/discovery/sources.go b/goku-service/discovery/sources.go
index 83db013cddaf4d717ea08a0fdc7ad1a5e8a0e405..bad54d8b19b19b3f3e8c935d5d46bc4069fc6796 100644
--- a/goku-service/discovery/sources.go
+++ b/goku-service/discovery/sources.go
@@ -2,21 +2,25 @@ package discovery
import (
"errors"
- "github.com/eolinker/goku-api-gateway/goku-service/common"
- "github.com/eolinker/goku-api-gateway/goku-service/health"
"reflect"
"sync"
"time"
+
+ "github.com/eolinker/goku-api-gateway/config"
+ "github.com/eolinker/goku-api-gateway/goku-service/common"
+ "github.com/eolinker/goku-api-gateway/goku-service/health"
)
+//ISource iSource
type ISource interface {
GetApp(app string) (*common.Service, health.CheckHandler, bool)
- SetHealthConfig(conf *HealthCheckConfig)
+ SetHealthConfig(conf *config.HealthCheckConfig)
SetDriverConfig(config string) error
Close()
CheckDriver(driverName string) bool
}
+//SourceDiscovery sourceDiscovery
type SourceDiscovery struct {
name string
discovery Discovery
@@ -26,10 +30,12 @@ type SourceDiscovery struct {
services map[string]*common.Service
}
+//SetDriverConfig 设置服务发现配置
func (s *SourceDiscovery) SetDriverConfig(config string) error {
return s.discovery.SetConfig(config)
}
+//Close close
func (s *SourceDiscovery) Close() {
instances := s.healthCheckHandler.Close()
for _, instance := range instances {
@@ -37,6 +43,8 @@ func (s *SourceDiscovery) Close() {
}
}
+
+//CheckDriver checkDriver
func (s *SourceDiscovery) CheckDriver(driverName string) bool {
if s.discovery == nil {
return false
@@ -47,19 +55,21 @@ func (s *SourceDiscovery) CheckDriver(driverName string) bool {
return false
}
-func (s *SourceDiscovery) SetHealthConfig(conf *HealthCheckConfig) {
+//SetHealthConfig 设置健康检查配置
+func (s *SourceDiscovery) SetHealthConfig(conf *config.HealthCheckConfig) {
if conf == nil || !conf.IsHealthCheck {
s.Close()
return
}
s.healthCheckHandler.Open(
- conf.Url,
+ conf.URL,
conf.StatusCode,
conf.Second,
time.Duration(conf.TimeOutMill)*time.Millisecond)
}
+//GetApp getApp
func (s *SourceDiscovery) GetApp(name string) (*common.Service, health.CheckHandler, bool) {
s.locker.RLock()
service, has := s.services[name]
@@ -70,6 +80,7 @@ func (s *SourceDiscovery) GetApp(name string) (*common.Service, health.CheckHand
return nil, nil, false
}
+//SetServices setServices
func (s *SourceDiscovery) SetServices(services []*common.Service) {
serviceMap := make(map[string]*common.Service)
@@ -84,8 +95,10 @@ func (s *SourceDiscovery) SetServices(services []*common.Service) {
}
+//ErrorEmptyDiscovery errorEmptyDiscovery
var ErrorEmptyDiscovery = errors.New("discovery is nil")
+//NewSource newSource
func NewSource(name string, d Discovery) (*SourceDiscovery, error) {
if d == nil || reflect.ValueOf(d).IsNil() {
@@ -100,13 +113,6 @@ func NewSource(name string, d Discovery) (*SourceDiscovery, error) {
locker: sync.RWMutex{},
}
- //services, e := d.GetServers()
- //if e!=nil{
- // return nil,e
- //}
-
- //s.SetServices(services)
-
d.SetCallback(s.SetServices)
return s, d.Open()
diff --git a/goku-service/driver/consul-kv/consul-kv.go b/goku-service/driver/consul-kv/consul-kv.go
index ca7c19c14091b31f08d50b3f8ced646fcc84bde4..1a77be7b1bf0fb88ea06fe10c649031a2ce757f1 100644
--- a/goku-service/driver/consul-kv/consul-kv.go
+++ b/goku-service/driver/consul-kv/consul-kv.go
@@ -4,12 +4,15 @@ import (
"github.com/eolinker/goku-api-gateway/goku-service/discovery"
)
+//Driver driver
type Driver struct {
}
+//Open open
func (d *Driver) Open(name string, config string) (discovery.ISource, error) {
panic("implement me")
}
+//ConsulKeyValueDiscovery consulKeyValueDiscovery
type ConsulKeyValueDiscovery struct {
}
diff --git a/goku-service/driver/consul-kv/init.go b/goku-service/driver/consul-kv/init.go
index 04200727995daf50413f2dd88f3e5e532458ed9e..1001bfbd1f8ad8ab822cf540c59d4bcbcf432079 100644
--- a/goku-service/driver/consul-kv/init.go
+++ b/goku-service/driver/consul-kv/init.go
@@ -1,11 +1,4 @@
package consul_kv
-import (
- "github.com/eolinker/goku-api-gateway/goku-service/discovery"
-)
-
+//DriverName 驱动名称
const DriverName = "consulKv"
-
-func init() {
- discovery.RegisteredDiscovery(DriverName, new(Driver))
-}
diff --git a/goku-service/driver/consul/consul_catalog.go b/goku-service/driver/consul/consul_catalog.go
index 89ee3167e7d1030914509cdd1a523ca5fda823c1..0e14599afa07bad53e4a0bad7cbd1c21bd0b41bf 100644
--- a/goku-service/driver/consul/consul_catalog.go
+++ b/goku-service/driver/consul/consul_catalog.go
@@ -2,13 +2,15 @@ package consul
import (
"context"
+ "time"
+
log "github.com/eolinker/goku-api-gateway/goku-log"
"github.com/eolinker/goku-api-gateway/goku-service/common"
"github.com/hashicorp/consul/api"
- "time"
)
-type ConsulDiscovery struct {
+//Discovery discovery
+type Discovery struct {
//Config *api.Config
orgConfig string
@@ -21,7 +23,8 @@ type ConsulDiscovery struct {
cancel context.CancelFunc
}
-func (d *ConsulDiscovery) SetConfig(config string) error {
+//SetConfig setConfig
+func (d *Discovery) SetConfig(config string) error {
if d.orgConfig == config {
return nil
}
@@ -39,33 +42,38 @@ func (d *ConsulDiscovery) SetConfig(config string) error {
}
-func (d *ConsulDiscovery) Driver() string {
+//Driver driver
+func (d *Discovery) Driver() string {
return DriverName
}
-func (d *ConsulDiscovery) SetCallback(callback func(services []*common.Service)) {
+//SetCallback setCallback
+func (d *Discovery) SetCallback(callback func(services []*common.Service)) {
d.callback = callback
}
-func (d *ConsulDiscovery) GetServers() ([]*common.Service, error) {
+//GetServers getServers
+func (d *Discovery) GetServers() ([]*common.Service, error) {
return d.services, nil
}
-func (d *ConsulDiscovery) Close() error {
+//Close close
+func (d *Discovery) Close() error {
if d.cancel != nil {
d.cancel()
}
return nil
}
-func (d *ConsulDiscovery) Open() error {
+//Open open
+func (d *Discovery) Open() error {
d.ScheduleAtFixedRate(time.Second * 5)
return nil
}
-//address: [hostName:port]
-func NewConsulDiscovery(address string) *ConsulDiscovery {
+//NewConsulDiscovery address: [hostName:port]
+func NewConsulDiscovery(address string) *Discovery {
config := api.DefaultConfig()
config.Address = address
@@ -75,7 +83,7 @@ func NewConsulDiscovery(address string) *ConsulDiscovery {
return nil
}
- cd := &ConsulDiscovery{
+ cd := &Discovery{
callback: nil,
client: client,
services: nil,
@@ -86,7 +94,8 @@ func NewConsulDiscovery(address string) *ConsulDiscovery {
return cd
}
-func (d *ConsulDiscovery) GetServicesInTime() (map[string][]string, map[string][]*api.ServiceEntry, error) {
+//GetServicesInTime getServicesInTime
+func (d *Discovery) GetServicesInTime() (map[string][]string, map[string][]*api.ServiceEntry, error) {
q := &api.QueryOptions{}
services, _, err := d.client.Catalog().Services(q)
@@ -110,7 +119,8 @@ func (d *ConsulDiscovery) GetServicesInTime() (map[string][]string, map[string][
}
-func (d *ConsulDiscovery) ScheduleAtFixedRate(second time.Duration) {
+//ScheduleAtFixedRate scheduleAtFixedRate
+func (d *Discovery) ScheduleAtFixedRate(second time.Duration) {
if d.cancel != nil {
d.cancel()
d.cancel = nil
@@ -118,10 +128,10 @@ func (d *ConsulDiscovery) ScheduleAtFixedRate(second time.Duration) {
d.run()
ctx, cancel := context.WithCancel(context.Background())
d.cancel = cancel
- go d.runTask(second, ctx)
+ go d.runTask(ctx, second)
}
-func (d *ConsulDiscovery) runTask(second time.Duration, ctx context.Context) {
+func (d *Discovery) runTask(ctx context.Context, second time.Duration) {
timer := time.NewTicker(second)
defer timer.Stop()
for {
@@ -135,7 +145,7 @@ func (d *ConsulDiscovery) runTask(second time.Duration, ctx context.Context) {
}
}
}
-func (d *ConsulDiscovery) run() {
+func (d *Discovery) run() {
services, catalogServices, err := d.GetServicesInTime()
if err == nil || services != nil || catalogServices != nil {
d.execCallbacks(services, catalogServices)
@@ -144,7 +154,7 @@ func (d *ConsulDiscovery) run() {
}
}
-func (d *ConsulDiscovery) execCallbacks(services map[string][]string, catalogServices map[string][]*api.ServiceEntry) {
+func (d *Discovery) execCallbacks(services map[string][]string, catalogServices map[string][]*api.ServiceEntry) {
if services == nil {
log.Info("consul services is empty")
return
@@ -175,7 +185,8 @@ func (d *ConsulDiscovery) execCallbacks(services map[string][]string, catalogSer
}
-func (d *ConsulDiscovery) Health() (bool, string) {
+//Health health
+func (d *Discovery) Health() (bool, string) {
leader, err := d.client.Status().Leader()
if err != nil || leader == "" {
return false, err.Error()
diff --git a/goku-service/driver/consul/init.go b/goku-service/driver/consul/init.go
index 0a9e5a1938f0d1a8431988f1a63c512acfde4ebe..70cb39b1d6e00dcc1dca3a3672f9ad0de6daccc5 100644
--- a/goku-service/driver/consul/init.go
+++ b/goku-service/driver/consul/init.go
@@ -4,14 +4,15 @@ import (
"github.com/eolinker/goku-api-gateway/goku-service/discovery"
)
+//DriverName 驱动名称
const DriverName = "consul"
-func init() {
-
+//Register register
+func Register() {
discovery.RegisteredDiscovery(DriverName, discovery.NewDriver(Create))
-
}
+//Create 创建
func Create(config string) discovery.Discovery {
return NewConsulDiscovery(config)
}
diff --git a/goku-service/driver/eureka/error.go b/goku-service/driver/eureka/error.go
index 1b2062a353ccc47663f441d9ed040c443a8dc1b7..45c89c335d29f8a58951cc2e66f94c0385a09b1b 100644
--- a/goku-service/driver/eureka/error.go
+++ b/goku-service/driver/eureka/error.go
@@ -6,6 +6,7 @@ const (
nilPointCode = 20001
)
+//Error error
type Error struct {
Message string
Code int
@@ -15,10 +16,12 @@ func _error(innerCode int, innerMessage string, message string) *Error {
return &Error{Message: innerMessage + ",cause by: " + message, Code: innerCode}
}
+//NewError 创建Error
func NewError(message string, code int) *Error {
return &Error{Message: message, Code: code}
}
+//NilPointError 空指针错误
func NilPointError(message string) *Error {
return _error(nilPointCode, "nil point error", message)
}
diff --git a/goku-service/driver/eureka/eureka.go b/goku-service/driver/eureka/eureka.go
index e46a8c48204dc286f21e349f29cb213517b8b584..b63e796d547473eb1d49de19fb9996324ba529b9 100644
--- a/goku-service/driver/eureka/eureka.go
+++ b/goku-service/driver/eureka/eureka.go
@@ -4,8 +4,6 @@ import (
"context"
"encoding/xml"
"fmt"
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "github.com/eolinker/goku-api-gateway/goku-service/common"
"io/ioutil"
"net/http"
"net/url"
@@ -13,12 +11,16 @@ import (
"strings"
"sync/atomic"
"time"
+
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+ "github.com/eolinker/goku-api-gateway/goku-service/common"
)
+//Eureka eureka
type Eureka struct {
services []*common.Service
//AppNames map[string]string
- eurekaUrl []string
+ eurekaURL []string
weightKey string
callback func(services []*common.Service)
ct uint64
@@ -26,6 +28,7 @@ type Eureka struct {
instanceFactory *common.InstanceFactory
}
+//SetConfig setConfig
func (d *Eureka) SetConfig(config string) error {
tags := strings.Split(config, ";")
weightKey := ""
@@ -39,22 +42,27 @@ func (d *Eureka) SetConfig(config string) error {
return nil
}
-func (d *Eureka) setConfig(eurekaUrl []string, weightKey string) {
- d.eurekaUrl = eurekaUrl
+func (d *Eureka) setConfig(eurekaURL []string, weightKey string) {
+ d.eurekaURL = eurekaURL
d.weightKey = weightKey
}
+
+//Driver driver
func (d *Eureka) Driver() string {
return DriverName
}
+//SetCallback setCallBack
func (d *Eureka) SetCallback(callback func(services []*common.Service)) {
d.callback = callback
}
+//GetServers getServers
func (d *Eureka) GetServers() ([]*common.Service, error) {
return d.services, nil
}
+//Close close
func (d *Eureka) Close() error {
if d.cancelFunc != nil {
d.cancelFunc()
@@ -63,11 +71,13 @@ func (d *Eureka) Close() error {
return nil
}
+//Open open
func (d *Eureka) Open() error {
d.ScheduleAtFixedRate(time.Second * 5)
return nil
}
+//NewEurekaDiscovery 创建Eureka
func NewEurekaDiscovery(config string) *Eureka {
e := &Eureka{
services: nil,
@@ -114,7 +124,7 @@ func (d *Eureka) execCallbacks(apps *Applications) {
} else if ins.SecurePort.Enabled {
port = ins.SecurePort.Port
}
- inses = append(inses, d.instanceFactory.General(ins.IpAddr, port, weight))
+ inses = append(inses, d.instanceFactory.General(ins.IPAddr, port, weight))
}
server := common.NewService(app.Name, inses)
services = append(services, server)
@@ -124,6 +134,7 @@ func (d *Eureka) execCallbacks(apps *Applications) {
}
+//ScheduleAtFixedRate scheduleAtFixedRate
func (d *Eureka) ScheduleAtFixedRate(second time.Duration) {
d.run()
if d.cancelFunc != nil {
@@ -133,10 +144,10 @@ func (d *Eureka) ScheduleAtFixedRate(second time.Duration) {
ctx, cancel := context.WithCancel(context.Background())
d.cancelFunc = cancel
- go d.runTask(second, ctx)
+ go d.runTask(ctx, second)
}
-func (d *Eureka) runTask(second time.Duration, ctx context.Context) {
+func (d *Eureka) runTask(ctx context.Context, second time.Duration) {
timer := time.NewTicker(second)
for {
select {
@@ -159,9 +170,9 @@ func (d *Eureka) run() {
}
}
+//GetApplications 获取应用
func (d *Eureka) GetApplications() (*Applications, error) {
- //url := c.eurekaUrl + "/apps"
- url, err := d.getEurekaServerUrl()
+ url, err := d.getEurekaServerURL()
if err != nil {
return nil, err
}
@@ -179,7 +190,7 @@ func (d *Eureka) GetApplications() (*Applications, error) {
if res.StatusCode != http.StatusOK {
return nil, err
}
- var applications *Applications = new(Applications)
+ var applications = new(Applications)
err = xml.Unmarshal(respBody, applications)
// log.Info(string(respBody))
@@ -187,26 +198,27 @@ func (d *Eureka) GetApplications() (*Applications, error) {
return applications, err
}
-func (d *Eureka) getEurekaServerUrl() (string, error) {
+func (d *Eureka) getEurekaServerURL() (string, error) {
ct := atomic.AddUint64(&d.ct, 1)
- size := len(d.eurekaUrl)
+ size := len(d.eurekaURL)
if size == 0 {
e := NilPointError("eureka url is empty")
return "", e
}
index := int(ct) % size
- url := d.eurekaUrl[index]
+ url := d.eurekaURL[index]
//if strings.LastIndex(url,"/")>-1{
url = strings.TrimSuffix(url, "/")
//}
return url, nil
}
+//Health health
func (d *Eureka) Health() (bool, string) {
ok, desc := true, "ok"
i := 0
- for _, u := range d.eurekaUrl {
+ for _, u := range d.eurekaURL {
url, err := url.Parse(u)
if err != nil {
@@ -214,8 +226,8 @@ func (d *Eureka) Health() (bool, string) {
ok, desc = false, err.Error()
continue
}
- healthUrl := url.Scheme + "://" + url.Host + "/health"
- res, err := http.Get(healthUrl)
+ healthURL := url.Scheme + "://" + url.Host + "/health"
+ res, err := http.Get(healthURL)
if err != nil {
i++
ok, desc = false, err.Error()
diff --git a/goku-service/driver/eureka/init.go b/goku-service/driver/eureka/init.go
index b99676c1099350824bdef6a57d51d772d6e6609a..b73ae8544ecc17e4ba15e892fa28580e5828b83e 100644
--- a/goku-service/driver/eureka/init.go
+++ b/goku-service/driver/eureka/init.go
@@ -4,14 +4,18 @@ import (
"github.com/eolinker/goku-api-gateway/goku-service/discovery"
)
+//DriverName 驱动名称
const DriverName = "eureka"
-const EurekaStatusUp = "UP"
-func init() {
+//EurekaStatusUp eureka状态
+const EurekaStatusUp = "UP"
+//Register 注册
+func Register() {
discovery.RegisteredDiscovery(DriverName, discovery.NewDriver(Create))
-
}
+
+//Create 创建
func Create(config string) discovery.Discovery {
return NewEurekaDiscovery(config)
}
diff --git a/goku-service/driver/eureka/metadata_marshaller.go b/goku-service/driver/eureka/metadata_marshaller.go
index acb3dad7e1484fe88ef3206eae58bf2490b44ce1..b7807cb53e3a6bcf61d47cb9fd9b847f01308b47 100644
--- a/goku-service/driver/eureka/metadata_marshaller.go
+++ b/goku-service/driver/eureka/metadata_marshaller.go
@@ -6,18 +6,21 @@ import (
"regexp"
)
+//MetaData metaData
type MetaData struct {
Map map[string]string
Class string
}
+//Vraw vraw
type Vraw struct {
Content []byte `xml:",innerxml"`
Class string `xml:"class,attr" json:"@class"`
}
+//MarshalXML marshalXML
func (s *MetaData) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
- var attributes []xml.Attr = make([]xml.Attr, 0)
+ var attributes = make([]xml.Attr, 0)
if s.Class != "" {
attributes = append(attributes, xml.Attr{
Name: xml.Name{
@@ -30,8 +33,8 @@ func (s *MetaData) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
tokens := []xml.Token{start}
for key, value := range s.Map {
- t := xml.StartElement{Name: xml.Name{"", key}}
- tokens = append(tokens, t, xml.CharData(value), xml.EndElement{t.Name})
+ t := xml.StartElement{Name: xml.Name{Space: "", Local: key}}
+ tokens = append(tokens, t, xml.CharData(value), xml.EndElement{Name: t.Name})
}
tokens = append(tokens, xml.EndElement{
@@ -54,6 +57,7 @@ func (s *MetaData) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
return nil
}
+//UnmarshalXML unMarshalXML
func (s *MetaData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
s.Map = make(map[string]string)
vraw := &Vraw{}
@@ -71,6 +75,7 @@ func (s *MetaData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
return nil
}
+//MarshalJSON marshalJSON
func (s *MetaData) MarshalJSON() ([]byte, error) {
mapIt := make(map[string]string)
for key, value := range s.Map {
@@ -81,9 +86,11 @@ func (s *MetaData) MarshalJSON() ([]byte, error) {
}
return json.Marshal(mapIt)
}
+
+//UnmarshalJSON unMarshalJSON
func (s *MetaData) UnmarshalJSON(data []byte) error {
dataUnmarshal := make(map[string]string)
- err := json.Unmarshal(data, dataUnmarshal)
+ err := json.Unmarshal(data, &dataUnmarshal)
s.Map = dataUnmarshal
if val, ok := s.Map["@class"]; ok {
s.Class = val
diff --git a/goku-service/driver/eureka/requests.go b/goku-service/driver/eureka/requests.go
index 54c01b4a9fe27bfd2f296464ba83deb2408fcf0f..217846ebe38a63f251c9af6398ce9aa8f64d8e86 100644
--- a/goku-service/driver/eureka/requests.go
+++ b/goku-service/driver/eureka/requests.go
@@ -9,44 +9,58 @@ var (
ErrRequestCancelled = errors.New("sending request is cancelled")
)
+//HealthStatus 健康状态
type HealthStatus struct {
Status string `json:"status,omitempty"`
Description string `json:"description,omitempty"`
}
+
+//Health health
type Health struct {
HealthStatus
Details map[string]interface{} `json:"details,omitempty"`
}
+//RawRequest raw请求
type RawRequest struct {
method string
relativePath string
body []byte
cancel <-chan bool
}
+
+//Applications applications
type Applications struct {
VersionsDelta int `xml:"versions__delta"`
AppsHashcode string `xml:"apps__hashcode"`
Applications []Application `xml:"application,omitempty"`
}
+
+//Application application
type Application struct {
Name string `xml:"name"`
Instances []InstanceInfo `xml:"instance"`
}
+
+//Instance instance
type Instance struct {
Instance *InstanceInfo `xml:"instance" json:"instance"`
}
+
+//Port port
type Port struct {
Port int `xml:",chardata" json:"$"`
Enabled bool `xml:"enabled,attr" json:"@enabled"`
}
+
+//InstanceInfo instanceInfo
type InstanceInfo struct {
HostName string `xml:"hostName" json:"hostName"`
- HomePageUrl string `xml:"homePageUrl,omitempty" json:"homePageUrl,omitempty"`
- StatusPageUrl string `xml:"statusPageUrl" json:"statusPageUrl"`
- HealthCheckUrl string `xml:"healthCheckUrl,omitempty" json:"healthCheckUrl,omitempty"`
+ HomePageURL string `xml:"homePageUrl,omitempty" json:"homePageUrl,omitempty"`
+ StatusPageURL string `xml:"statusPageUrl" json:"statusPageUrl"`
+ HealthCheckURL string `xml:"healthCheckUrl,omitempty" json:"healthCheckUrl,omitempty"`
App string `xml:"app" json:"app"`
- IpAddr string `xml:"ipAddr" json:"ipAddr"`
+ IPAddr string `xml:"ipAddr" json:"ipAddr"`
VipAddress string `xml:"vipAddress" json:"vipAddress"`
SecureVipAddress string `xml:"secureVipAddress,omitempty" json:"secureVipAddress,omitempty"`
Status string `xml:"status" json:"status"`
@@ -60,32 +74,36 @@ type InstanceInfo struct {
LastDirtyTimestamp int `xml:"lastDirtyTimestamp,omitempty" json:"lastDirtyTimestamp,omitempty"`
ActionType string `xml:"actionType,omitempty" json:"actionType,omitempty"`
Overriddenstatus string `xml:"overriddenstatus,omitempty" json:"overriddenstatus,omitempty"`
- CountryId int `xml:"countryId,omitempty" json:"countryId,omitempty"`
+ CountryID int `xml:"countryId,omitempty" json:"countryId,omitempty"`
//
- InstanceId string `xml:"instanceId" json:"instanceId"`
+ InstanceID string `xml:"instanceId" json:"instanceId"`
AppName string `xml:"appName,omitempty" json:"appName,omitempty"`
AppGroupName string `xml:"appGroupName,omitempty" json:"appGroupName,omitempty"`
}
+
+//DataCenterInfo dataCenterInfo
type DataCenterInfo struct {
Name string `xml:"name" json:"name"`
Class string `xml:"class,attr" json:"@class"`
Metadata *DataCenterMetadata `xml:"metadata,omitempty" json:"metadata,omitempty"`
}
+//DataCenterMetadata dataCenterMetaData
type DataCenterMetadata struct {
AmiLaunchIndex string `xml:"ami-launch-index,omitempty" json:"ami-launch-index,omitempty"`
LocalHostname string `xml:"local-hostname,omitempty" json:"local-hostname,omitempty"`
AvailabilityZone string `xml:"availability-zone,omitempty" json:"availability-zone,omitempty"`
- InstanceId string `xml:"instance-id,omitempty" json:"instance-id,omitempty"`
+ InstanceID string `xml:"instance-id,omitempty" json:"instance-id,omitempty"`
PublicIpv4 string `xml:"public-ipv4,omitempty" json:"public-ipv4,omitempty"`
PublicHostname string `xml:"public-hostname,omitempty" json:"public-hostname,omitempty"`
AmiManifestPath string `xml:"ami-manifest-path,omitempty" json:"ami-manifest-path,omitempty"`
LocalIpv4 string `xml:"local-ipv4,omitempty" json:"local-ipv4,omitempty"`
Hostname string `xml:"hostname,omitempty" json:"hostname,omitempty"`
- AmiId string `xml:"ami-id,omitempty" json:"ami-id,omitempty"`
+ AmiID string `xml:"ami-id,omitempty" json:"ami-id,omitempty"`
InstanceType string `xml:"instance-type,omitempty" json:"instance-type,omitempty"`
}
+//LeaseInfo leaseInfo
type LeaseInfo struct {
EvictionDurationInSecs uint `xml:"evictionDurationInSecs,omitempty" json:"evictionDurationInSecs,omitempty"`
RenewalIntervalInSecs int `xml:"renewalIntervalInSecs,omitempty" json:"renewalIntervalInSecs,omitempty"`
diff --git a/goku-service/driver/kubernetes/init.go b/goku-service/driver/kubernetes/init.go
index ed2461e6ecd0febba62eca2e8e7ad72e09e31cd5..07a3b5068a9fff5bfed7d88f7735d99e4f5768be 100644
--- a/goku-service/driver/kubernetes/init.go
+++ b/goku-service/driver/kubernetes/init.go
@@ -4,6 +4,7 @@ import (
discoveryManager "github.com/eolinker/goku-api-gateway/goku-service/discovery"
)
+//DriverName 驱动名称
const DriverName = "kubernetes"
func init() {
diff --git a/goku-service/driver/kubernetes/k8s.go b/goku-service/driver/kubernetes/k8s.go
index fa073f410bfb95d819f2ec675f2132a8a934aa8d..c15c1c3323d6b7aaa986fa16f841055ed2a9adb0 100644
--- a/goku-service/driver/kubernetes/k8s.go
+++ b/goku-service/driver/kubernetes/k8s.go
@@ -4,12 +4,15 @@ import (
"github.com/eolinker/goku-api-gateway/goku-service/discovery"
)
+//Driver driver
type Driver struct {
}
+//Open open
func (d *Driver) Open(name string, config string) (discovery.ISource, error) {
panic("implement me")
}
-type KubernetesDiscovery struct {
+//Discovery discovery
+type Discovery struct {
}
diff --git a/goku-service/driver/static/init.go b/goku-service/driver/static/init.go
index 54ce11b2166f6cc08a3a3621527b325013f8cb4d..f81d56f4d1a2e27ac18057235e9224e25f056f3a 100644
--- a/goku-service/driver/static/init.go
+++ b/goku-service/driver/static/init.go
@@ -4,8 +4,10 @@ import (
"github.com/eolinker/goku-api-gateway/goku-service/discovery"
)
+//DriverName 驱动名称
const DriverName = "static"
-func init() {
+//Register 注册
+func Register() {
discovery.RegisteredDiscovery(DriverName, new(Driver))
}
diff --git a/goku-service/driver/static/node.go b/goku-service/driver/static/node.go
index c95b78cf3a1cbe83213f1dacb702235748dcc29c..6af6508b8d5c28316b7cb9f71135fa35b36e4705 100644
--- a/goku-service/driver/static/node.go
+++ b/goku-service/driver/static/node.go
@@ -1,5 +1,6 @@
package static
+//Node node
type Node struct {
IP string
Port int
diff --git a/goku-service/driver/static/static-node.go b/goku-service/driver/static/static-node.go
index 70ad5ba9a29db7af876653f849b44b3ea3267775..5856d0ae0e7efe3cd80659b077d628e18e02de1e 100644
--- a/goku-service/driver/static/static-node.go
+++ b/goku-service/driver/static/static-node.go
@@ -5,37 +5,46 @@ import (
"github.com/eolinker/goku-api-gateway/goku-service/discovery"
)
+//Driver driver
type Driver struct {
}
+//Open open
func (d *Driver) Open(name string, config string) (discovery.ISource, error) {
return NewStaticSources(name), nil
}
+//StaticDiscovery staticDiscovery
type StaticDiscovery struct {
}
+//SetConfig setConfig
func (d *StaticDiscovery) SetConfig(config string) error {
return nil
}
+//Driver driver
func (d *StaticDiscovery) Driver() string {
return DriverName
}
+//SetCallback setCallBack
func (d *StaticDiscovery) SetCallback(callback func(services []*common.Service)) {
return
}
+//GetServers getServers
func (d *StaticDiscovery) GetServers() ([]*common.Service, error) {
return nil, nil
}
+//Close close
func (d *StaticDiscovery) Close() error {
return nil
}
+//Open open
func (d *StaticDiscovery) Open() error {
return nil
}
diff --git a/goku-service/driver/static/staticSources.go b/goku-service/driver/static/staticSources.go
index d054ad7219193028c87af052e7e53beb27057a5c..7df29b8d2c2e1c3a0a864eba839507dbf462b4e6 100644
--- a/goku-service/driver/static/staticSources.go
+++ b/goku-service/driver/static/staticSources.go
@@ -3,18 +3,22 @@ package static
import (
"errors"
"fmt"
- "github.com/eolinker/goku-api-gateway/goku-service/discovery"
- "github.com/eolinker/goku-api-gateway/goku-service/health"
"time"
- "github.com/eolinker/goku-api-gateway/goku-service/common"
+ "github.com/eolinker/goku-api-gateway/config"
+ "github.com/eolinker/goku-api-gateway/goku-service/health"
+
"strconv"
"strings"
"unicode"
+
+ "github.com/eolinker/goku-api-gateway/goku-service/common"
)
+//ErrorNoInstance errorNoInstance
var ErrorNoInstance = errors.New("no instance")
+//Sources source
type Sources struct {
name string
@@ -23,19 +27,21 @@ type Sources struct {
instanceFactory *common.InstanceFactory
}
-func (s *Sources) SetHealthConfig(conf *discovery.HealthCheckConfig) {
+//SetHealthConfig setHealthConfig
+func (s *Sources) SetHealthConfig(conf *config.HealthCheckConfig) {
if conf == nil || !conf.IsHealthCheck {
s.Close()
return
}
s.healthCheckHandler.Open(
- conf.Url,
+ conf.URL,
conf.StatusCode,
conf.Second,
time.Duration(conf.TimeOutMill)*time.Millisecond)
}
+//Close close
func (s *Sources) Close() {
instances := s.healthCheckHandler.Close()
for _, instance := range instances {
@@ -43,15 +49,18 @@ func (s *Sources) Close() {
}
}
+//CheckDriver checkDriver
func (s *Sources) CheckDriver(driverName string) bool {
return driverName == DriverName
}
+//SetDriverConfig setDriverConfig
func (s *Sources) SetDriverConfig(config string) error {
return nil
}
+//GetApp getApp
func (s *Sources) GetApp(app string) (*common.Service, health.CheckHandler, bool) {
service, e := s.decode(app)
if e != nil {
@@ -60,6 +69,7 @@ func (s *Sources) GetApp(app string) (*common.Service, health.CheckHandler, bool
return service, s.healthCheckHandler, true
}
+//NewStaticSources 创建Sources
func NewStaticSources(name string) *Sources {
return &Sources{
@@ -88,7 +98,7 @@ func (s *Sources) decode(config string) (*common.Service, error) {
instances := make([]*common.Instance, 0, 5)
nodes := make([]*Node, 0, 5)
- var node *Node = nil
+ var node *Node
index := 0
for _, word := range words {
if word == ";" {
@@ -113,10 +123,6 @@ func (s *Sources) decode(config string) (*common.Service, error) {
if len(vs) == 2 {
node.Port, _ = strconv.Atoi(vs[1])
}
- if node.Port == 0 {
- node.Port = 80
- }
- //node.InstanceId = fmt.Sprintf("%s:%d",node.IP,node.Port)
nodes = append(nodes, node)
}
diff --git a/goku-service/health/checker.go b/goku-service/health/checker.go
index 104293b5ac59f02874ea4f7cd185d8c396a3b78b..6b31ae19ac878018cf3c6aee0c0eb088f30dfa9c 100644
--- a/goku-service/health/checker.go
+++ b/goku-service/health/checker.go
@@ -3,11 +3,13 @@ package health
import (
"context"
"fmt"
- "github.com/eolinker/goku-api-gateway/goku-service/common"
"net/http"
"time"
+
+ "github.com/eolinker/goku-api-gateway/goku-service/common"
)
+//Checker checker
type Checker struct {
path string
second int
@@ -22,6 +24,7 @@ type Checker struct {
checkChan chan *common.Instance
}
+//Open open
func (c *Checker) Open() {
if c.cancelFunc != nil {
return
@@ -37,13 +40,23 @@ func (c *Checker) Open() {
go c.doloop(ctx, c.closeDone)
}
func (c *Checker) check(instance *common.Instance) bool {
- url := fmt.Sprintf("http://%s:%d/%s", instance.IP, instance.Port, c.path)
- respone, err := http.Get(url)
+ // todo 这里有个问题,没有指定协议,只能通过端口进行简单判定,如果没有设置端口或者设置自定义的https的端口,会导致无法识别到https
+ server := instance.IP
+ if instance.Port != 0 {
+ server = fmt.Sprintf("%s:%d", instance.IP, instance.Port)
+ }
+ protocol := "http"
+ if instance.Port == 443 {
+ protocol = "https"
+ }
+
+ url := fmt.Sprintf("%s://%s/%s", protocol, server, c.path)
+ response, err := http.Get(url)
if err != nil {
return false
}
- if c.statusCodes[ respone.StatusCode] {
+ if c.statusCodes[response.StatusCode] {
return true
}
return false
@@ -69,11 +82,11 @@ func (c *Checker) doloop(ctx context.Context, closeDone chan int) {
case <-t.C:
{
count := 0
- for instanceId, ins := range instances {
+ for instanceID, ins := range instances {
// 处理空列表
if len(ins) == 0 {
- delete(instances, instanceId)
+ delete(instances, instanceID)
continue
}
@@ -87,37 +100,39 @@ func (c *Checker) doloop(ctx context.Context, closeDone chan int) {
// 移除没有需要待检查的实例id
if len(insNew) == 0 {
- delete(instances, instanceId)
+ delete(instances, instanceID)
continue
}
instance := insNew[0]
if c.check(instance) {
- delete(instances, instanceId)
+ delete(instances, instanceID)
for _, in := range insNew {
in.ChangeStatus(common.InstanceChecking, common.InstanceRun)
}
} else {
count += len(insNew)
- instances[instanceId] = insNew
+ instances[instanceID] = insNew
}
}
c.sum = count
}
case instance := <-c.checkChan:
if instance != nil {
- instances[instance.InstanceId] = append(instances[instance.InstanceId], instance)
+ instances[instance.InstanceID] = append(instances[instance.InstanceID], instance)
c.sum++
}
}
}
}
+//Check check
func (c *Checker) Check(instance *common.Instance) {
instance.ChangeStatus(common.InstanceRun, common.InstanceChecking)
c.checkChan <- instance
}
+//Close close
func (c *Checker) Close() (map[string][]*common.Instance, int) {
if c.cancelFunc != nil {
c.cancelFunc()
diff --git a/goku-service/health/health.go b/goku-service/health/health.go
index 18c7d3286aac2299589db40bd4ef4abac0628460..137c8c3c00092cc42c93b689d6261049889c3252 100644
--- a/goku-service/health/health.go
+++ b/goku-service/health/health.go
@@ -1,24 +1,29 @@
package health
import (
- "github.com/eolinker/goku-api-gateway/goku-service/common"
"strconv"
"strings"
"time"
+
+ "github.com/eolinker/goku-api-gateway/goku-service/common"
)
+//CheckHandler checkHandler
type CheckHandler interface {
Open(path string, statusCodes string, second int, timeout time.Duration)
Check(instance *common.Instance)
IsNeedCheck() bool
Close() []*common.Instance
}
+
+//CheckBox checkBox
type CheckBox struct {
isNeedCheck bool
statusCodes map[string]bool
checker *Checker
}
+//Open open
func (c *CheckBox) Open(path string, statusCodes string, second int, timeout time.Duration) {
old := c.checker
@@ -58,6 +63,7 @@ func (c *CheckBox) Open(path string, statusCodes string, second int, timeout tim
c.isNeedCheck = true
}
+//Check check
func (c *CheckBox) Check(instance *common.Instance) {
if !c.isNeedCheck {
return
@@ -67,11 +73,13 @@ func (c *CheckBox) Check(instance *common.Instance) {
}
}
+//IsNeedCheck isNeedCheck
func (c *CheckBox) IsNeedCheck() bool {
return c.isNeedCheck && c.checker != nil
}
+//Close close
func (c *CheckBox) Close() []*common.Instance {
if c.checker == nil {
return nil
diff --git a/node/console/config.go b/node/console/config.go
new file mode 100644
index 0000000000000000000000000000000000000000..01d199b0e1abc960519d7e45a8f42d28a7959572
--- /dev/null
+++ b/node/console/config.go
@@ -0,0 +1,138 @@
+package console
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ listener2 "github.com/eolinker/goku-api-gateway/common/listener"
+ "github.com/eolinker/goku-api-gateway/config"
+)
+
+//ConfigCallbackFunc configCallbackFunc
+type ConfigCallbackFunc func(gokuConfig *config.GokuConfig)
+
+var (
+ lastConfig *config.GokuConfig
+ once sync.Once
+
+ listener = listener2.New()
+)
+
+//GetConfig 获取节点配置
+func (c *Console) GetConfig() (*config.GokuConfig, error) {
+ if lastConfig != nil {
+ return lastConfig, nil
+ }
+
+ once.Do(func() {
+ listenConfig(c.ctx, c.port, c.adminHost)
+ })
+
+ cn := make(chan *config.GokuConfig, 1)
+ listener.ListenOnce(func(event interface{}) {
+ conf := event.(*config.GokuConfig)
+ cn <- conf
+ })
+ deadline, _ := context.WithTimeout(context.Background(), time.Second*30)
+
+ select {
+ case <-deadline.Done():
+ return nil, errors.New("get config timeout")
+ case conf := <-cn:
+ return conf, nil
+ }
+}
+
+//AddListen 新增监听配置
+func (c *Console) AddListen(callback ConfigCallbackFunc) {
+
+ listener.Listen(func(event interface{}) {
+ conf := event.(*config.GokuConfig)
+ callback(conf)
+ })
+
+}
+
+func listenConfig(ctx context.Context, port int, adminHost string) {
+
+ admin := adminHost
+ admin = strings.TrimPrefix(admin, "http://")
+ admin = strings.TrimSuffix(admin, "/")
+
+ url := fmt.Sprintf("http://%s/version/config/get", admin)
+
+ go func() {
+
+ errNum := 0
+ lastVersion := ""
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ default:
+ {
+
+ gokuConfig, err := getConfig(url, port, lastVersion)
+ if err != nil {
+ errNum++
+ time.After(time.Second * time.Duration(errNum))
+ continue
+ }
+ if gokuConfig != nil {
+ if lastVersion != gokuConfig.Version {
+ lastVersion = gokuConfig.Version
+ lastConfig = gokuConfig
+ listener.Call(gokuConfig)
+ }
+
+ }
+ }
+ }
+
+ }
+
+ }()
+
+}
+func getConfig(url string, port int, lastVersion string) (*config.GokuConfig, error) {
+ req, e := http.NewRequest(http.MethodGet, url, nil)
+
+ if e != nil {
+
+ return nil, e
+ }
+
+ q := req.URL.Query()
+ q.Add("port", strconv.Itoa(port))
+ q.Add("version", lastVersion)
+ req.URL.RawQuery = q.Encode()
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return nil, err
+ }
+
+ defer resp.Body.Close()
+
+ data, err := ioutil.ReadAll(resp.Body)
+
+ if err != nil {
+ return nil, err
+ }
+
+ gConfig := new(config.GokuConfig)
+
+ err = json.Unmarshal(data, gConfig)
+ if err != nil {
+ return nil, err
+ }
+
+ return gConfig, nil
+}
diff --git a/node/console/console.go b/node/console/console.go
new file mode 100644
index 0000000000000000000000000000000000000000..1cd031de23466a17e4d8cce83499887d4a32adf2
--- /dev/null
+++ b/node/console/console.go
@@ -0,0 +1,32 @@
+package console
+
+import (
+ "context"
+ "sync"
+)
+
+//Console console
+type Console struct {
+ adminHost string
+ port int
+ ctx context.Context
+ cancel context.CancelFunc
+ lastVersion int
+ once sync.Once
+}
+
+//Close close
+func (c *Console) Close() {
+ c.once.Do(c.cancel)
+}
+
+//NewConsole newConsole
+func NewConsole(port int, adminHost string) *Console {
+ ctx, cancel := context.WithCancel(context.Background())
+ return &Console{
+ port: port,
+ adminHost: adminHost,
+ ctx: ctx,
+ cancel: cancel,
+ }
+}
diff --git a/node/gateway/README.md b/node/gateway/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..554fe1ed938676e83623c7d90ed58f4b39c4c41c
--- /dev/null
+++ b/node/gateway/README.md
@@ -0,0 +1,4 @@
+## router
+
+注:
+因为兼容旧版本的原因,这里显得比较复杂,待重构后,这里会抽象出来
\ No newline at end of file
diff --git a/node/gateway/api.go b/node/gateway/api.go
new file mode 100644
index 0000000000000000000000000000000000000000..91740dc1b9dd1a7820fc3d944031f1c65760d817
--- /dev/null
+++ b/node/gateway/api.go
@@ -0,0 +1,90 @@
+package gateway
+
+import (
+ "fmt"
+
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+ "github.com/eolinker/goku-api-gateway/node/gateway/application"
+ plugin_executor "github.com/eolinker/goku-api-gateway/node/gateway/plugin-executor"
+ access_field "github.com/eolinker/goku-api-gateway/server/access-field"
+)
+
+//API 接口
+type API struct {
+ strategyID string
+ //api *config.APIContent
+ app application.Application
+ pluginAccess []plugin_executor.Executor
+ pluginAccessGlobal []plugin_executor.Executor
+
+ pluginProxies []plugin_executor.Executor
+ pluginProxiesGlobal []plugin_executor.Executor
+
+ apiID int
+ apiName string
+}
+
+//Router router
+func (h *API) Router(ctx *common.Context) {
+
+ ctx.SetAPIID(h.apiID)
+ ctx.LogFields[access_field.API] = fmt.Sprintf("\"%d %s\"", h.apiID, h.apiName)
+
+ isAccess := h.accessFlow(ctx)
+ h.accessGlobalFlow(ctx)
+ if !isAccess {
+ return
+ }
+
+ h.app.Execute(ctx)
+
+ isproxy := h.proxyFlow(ctx)
+ h.proxyGlobalFlow(ctx)
+
+ if !isproxy {
+ return
+ }
+
+ return
+}
+
+func (h *API) accessFlow(ctx *common.Context) bool {
+ for _, handler := range h.pluginAccess {
+
+ flag, _ := handler.Execute(ctx)
+
+ if flag == false && handler.IsStop() {
+
+ return false
+ }
+ }
+ return true
+}
+
+func (h *API) accessGlobalFlow(ctx *common.Context) {
+ // 全局插件不中断
+ for _, handler := range h.pluginAccessGlobal {
+ _, _ = handler.Execute(ctx)
+ }
+}
+
+func (h *API) proxyFlow(ctx *common.Context) bool {
+ for _, handler := range h.pluginProxies {
+
+ flag, _ := handler.Execute(ctx)
+
+ if flag == false && handler.IsStop() {
+
+ return false
+ }
+ }
+ return true
+}
+
+func (h *API) proxyGlobalFlow(ctx *common.Context) {
+ // 全局插件不中断
+ for _, handler := range h.pluginProxiesGlobal {
+ _, _ = handler.Execute(ctx)
+
+ }
+}
diff --git a/node/gateway/application/action/action.go b/node/gateway/application/action/action.go
new file mode 100644
index 0000000000000000000000000000000000000000..5b68dce23416e5d8eaf0684a4f8937d5ecd00a37
--- /dev/null
+++ b/node/gateway/application/action/action.go
@@ -0,0 +1,48 @@
+package action
+
+import (
+ "github.com/eolinker/goku-api-gateway/config"
+ "github.com/eolinker/goku-api-gateway/node/gateway/response"
+ "strings"
+)
+
+const (
+ Delete ="delete"
+ Rename = "rename"
+ Move = "move"
+ Black = "black"
+ White = "white"
+
+
+)
+type Filter interface {
+ Do(value *response.Response)
+}
+
+type Filters []Filter
+
+func (f Filters) Do(value *response.Response) {
+ target := value
+ for _,item:=range f{
+ item.Do(target)
+ }
+
+}
+
+func GenByconfig( ac * config.ActionConfig) Filter {
+ switch strings.ToLower(ac.ActionType) {
+ case Delete:
+ return DeleteFilter(ac.Original)
+ case Rename:
+ return &RenameFilter{
+ pattern:ac.Original,
+ name:ac.Target,
+ }
+ case Move:
+ return &MoveFilter{
+ target:ac.Target,
+ source:ac.Original,
+ }
+ }
+ return nil
+}
\ No newline at end of file
diff --git a/node/gateway/application/action/blacklist.go b/node/gateway/application/action/blacklist.go
new file mode 100644
index 0000000000000000000000000000000000000000..d5785a79bc5900963635ac7c0bedbfabdd2a3d50
--- /dev/null
+++ b/node/gateway/application/action/blacklist.go
@@ -0,0 +1,12 @@
+package action
+
+import "github.com/eolinker/goku-api-gateway/node/gateway/response"
+
+type Blacklist string
+
+func (f Blacklist) Do(value *response.Response) {
+ value.Delete(string(f))
+}
+
+
+
diff --git a/node/gateway/application/action/delete.go b/node/gateway/application/action/delete.go
new file mode 100644
index 0000000000000000000000000000000000000000..be1050fd795248c519873bd50b70c671e6d1f4ce
--- /dev/null
+++ b/node/gateway/application/action/delete.go
@@ -0,0 +1,12 @@
+package action
+
+import "github.com/eolinker/goku-api-gateway/node/gateway/response"
+
+type DeleteFilter string
+
+func (f DeleteFilter) Do(value *response.Response) {
+ value.Delete(string(f))
+}
+
+
+
diff --git a/node/gateway/application/action/move.go b/node/gateway/application/action/move.go
new file mode 100644
index 0000000000000000000000000000000000000000..fa8a4c2118e072a1b22d40f9c71657850b5e120c
--- /dev/null
+++ b/node/gateway/application/action/move.go
@@ -0,0 +1,13 @@
+package action
+
+import "github.com/eolinker/goku-api-gateway/node/gateway/response"
+
+type MoveFilter struct {
+ source string
+ target string
+}
+
+func (f *MoveFilter) Do(value *response.Response) {
+ value.Move(f.source,f.target)
+}
+
diff --git a/node/gateway/application/action/rename.go b/node/gateway/application/action/rename.go
new file mode 100644
index 0000000000000000000000000000000000000000..2528e995c55e62486ec845f20e5a4ca647c01dd9
--- /dev/null
+++ b/node/gateway/application/action/rename.go
@@ -0,0 +1,14 @@
+package action
+
+import "github.com/eolinker/goku-api-gateway/node/gateway/response"
+
+type RenameFilter struct {
+ pattern string
+ name string
+}
+
+func (f *RenameFilter) Do(value *response.Response) {
+
+ value.ReName(f.pattern,f.name)
+}
+
diff --git a/node/gateway/application/action/white.go b/node/gateway/application/action/white.go
new file mode 100644
index 0000000000000000000000000000000000000000..2bfdcc7716cc18931fbbf521b96a4a208619c2cc
--- /dev/null
+++ b/node/gateway/application/action/white.go
@@ -0,0 +1,144 @@
+package action
+
+import (
+ "encoding/json"
+ "github.com/eolinker/goku-api-gateway/node/gateway/response"
+ "strconv"
+ "strings"
+)
+
+type _WhiteNode map[string]_WhiteNode
+
+
+func (n _WhiteNode) String() string {
+
+ data, e := json.Marshal(n)
+ if e!= nil{
+ return e.Error()
+ }
+ return string(data)
+}
+type _WhiteRoot struct {
+ root _WhiteNode
+}
+
+func (w *_WhiteRoot) Do(value *response.Response) {
+
+ value.Data = w.root.Do(value.Data)
+}
+
+func newWhiteNode() _WhiteNode {
+ return make(_WhiteNode)
+}
+func GenWhite(paths []string)Filter {
+ root:= genWhite(paths)
+ return &_WhiteRoot{
+ root:root,
+ }
+}
+
+func genWhite(paths []string)_WhiteNode{
+ root:=newWhiteNode()
+
+ for _,path:=range paths{
+ root.add(strings.Split(path,"."))
+ }
+ return root
+}
+func (n _WhiteNode) add(path []string) {
+
+ if len(path) ==0{
+ return
+ }
+ key:= path[0]
+ next:=path[1:]
+
+
+ node,has:=n[key]
+ if !has{
+ node = newWhiteNode()
+ n[key] =node
+ }
+
+ node.add(next)
+
+}
+func (n _WhiteNode) Do(value interface{}) interface{} {
+
+
+ if value==nil{
+ return nil
+ }
+
+ if len(n)== 0{
+ return value
+ }
+
+ switch value.(type) {
+ case []interface{}:
+ {
+ list:= value.([]interface{})
+ l:=len(list)
+ vs:=make([]interface{},0,len(n))
+ for key,child:=range n{
+ if key == "*"{
+ vsALl :=make([]interface{},0,len(list))
+ for _,item:=range list{
+ vsALl = append(vsALl,child.Do(item))
+ }
+ return vsALl
+ }
+ if i,err:= strconv.Atoi(key);err == nil{
+ if i0{
+ filters = append(filters,action.GenWhite(whiteList))
+ }
+
+ for _,ac:=range acs{
+
+ f:=action.GenByconfig(ac)
+ if f!= nil{
+ filters = append(filters,f)
+ }
+ }
+ return filters
+}
\ No newline at end of file
diff --git a/node/gateway/application/backend/layer.go b/node/gateway/application/backend/layer.go
new file mode 100644
index 0000000000000000000000000000000000000000..46034045582714e3be49f7b9d86b53ca6611e743
--- /dev/null
+++ b/node/gateway/application/backend/layer.go
@@ -0,0 +1,111 @@
+package backend
+
+import (
+ "context"
+ "github.com/eolinker/goku-api-gateway/config"
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+ "github.com/eolinker/goku-api-gateway/goku-service/application"
+ "github.com/eolinker/goku-api-gateway/goku-service/balance"
+ "github.com/eolinker/goku-api-gateway/node/gateway/application/action"
+ "github.com/eolinker/goku-api-gateway/node/gateway/application/interpreter"
+ "github.com/eolinker/goku-api-gateway/node/gateway/response"
+ "io/ioutil"
+ "strings"
+ "time"
+)
+
+type Layer struct {
+ BalanceName string
+ Balance application.IHttpApplication
+ HasBalance bool
+ Protocol string
+
+
+ Filter action.Filter
+ Method string
+ Path interpreter.Interpreter
+ Decode response.DecodeHandle
+
+ Body interpreter.Interpreter
+ Encode string
+ Target string
+ Group[] string
+ Retry int
+ TimeOut time.Duration
+
+}
+
+func (b *Layer) Send(ctx *common.Context,variables *interpreter.Variables,deadline context.Context) (*BackendResponse, error) {
+ path:= b.Path.Execution(variables)
+ body:= b.Body.Execution(variables)
+ method:= b.Method
+
+ r, finalTargetServer, retryTargetServers, err := b.Balance.Send(b.Protocol,method, path, ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(),[]byte(body), b.TimeOut, b.Retry)
+
+ if err!=nil{
+ return nil,err
+ }
+ backendResponse := &BackendResponse{
+ Method: strings.ToUpper(method),
+ Protocol: b.Protocol,
+ //Response: r,
+ TargetUrl: path,
+ FinalTargetServer: finalTargetServer,
+ RetryTargetServers: retryTargetServers,
+ Header:r.Header,
+ }
+
+ defer r.Body.Close()
+ backendResponse.BodyOrg, err = ioutil.ReadAll(r.Body)
+ if err!= nil{
+ return backendResponse,nil
+ }
+
+
+ rp,e:=response.Decode(backendResponse.BodyOrg,b.Decode)
+ if e!= nil{
+ backendResponse.Body = nil
+ return nil,e
+ }
+
+
+
+ b.Filter.Do(rp)
+
+ if b.Target!= ""{
+ rp.ReTarget(b.Target)
+ }
+ if len(b.Group)>0{
+ rp.Group(b.Group)
+ }
+ backendResponse.Body = rp.Data
+ return backendResponse,nil
+}
+
+
+
+func NewLayer(step *config.APIStepConfig) *Layer {
+ var b = &Layer{
+ BalanceName: step.Balance,
+ Balance: nil,
+ HasBalance: false,
+ Protocol: step.Proto,
+ Filter: genFilter(step.BlackList,step.WhiteList,step.Actions),
+ Method: strings.ToUpper(step.Method),
+ Path: interpreter.GenPath( step.Path),
+ Decode: response.GetDecoder(step.Decode),
+ Encode: step.Encode,
+ Target: step.Target,
+ Group: nil,
+ TimeOut:time.Duration(step.TimeOut)*time.Millisecond,
+ Body:interpreter.Gen(step.Body),
+ Retry: step.Retry,
+ }
+ if step.Group != ""{
+ b.Group = strings.Split(step.Group,".")
+ }
+
+ b.Balance, b.HasBalance = balance.GetByName(b.BalanceName)
+
+ return b
+}
diff --git a/node/gateway/application/backend/proxy.go b/node/gateway/application/backend/proxy.go
new file mode 100644
index 0000000000000000000000000000000000000000..5fc09b6e5699e93f912989a29d3fe9a88ca8d83a
--- /dev/null
+++ b/node/gateway/application/backend/proxy.go
@@ -0,0 +1,122 @@
+package backend
+
+import (
+ "fmt"
+ "github.com/eolinker/goku-api-gateway/config"
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+ "github.com/eolinker/goku-api-gateway/goku-service/application"
+ "github.com/eolinker/goku-api-gateway/goku-service/balance"
+ "io/ioutil"
+ "strings"
+
+ "github.com/eolinker/goku-api-gateway/node/gateway/application/interpreter"
+ "github.com/eolinker/goku-api-gateway/node/gateway/response"
+ "time"
+)
+
+type Proxy struct {
+ //step * config.APIStepConfig
+ BalanceName string
+ Balance application.IHttpApplication
+ HasBalance bool
+ Protocol string
+
+
+ Method string
+ Path interpreter.Interpreter
+ OrgPath string
+ Decode response.DecodeHandle
+
+ RequestPath string
+
+ Retry int
+ TimeOut time.Duration
+
+}
+func NewProxyBackendTarget(step *config.APIStepConfig,requestPath string,balanceTarget string) *Proxy {
+ b:= &Proxy{
+ BalanceName:balanceTarget,
+ Protocol:step.Proto,
+ Method: strings.ToUpper(step.Method),
+ Path: interpreter.GenPath( step.Path),
+
+ RequestPath: requestPath,
+ Decode: response.GetDecoder(step.Decode),
+
+
+ TimeOut:time.Duration(step.TimeOut)*time.Millisecond,
+ Retry: step.Retry,
+
+ }
+
+
+ b.Balance, b.HasBalance = balance.GetByName(balanceTarget)
+
+ return b
+}
+
+
+func (b *Proxy) Send(ctx *common.Context,variables *interpreter.Variables)( *BackendResponse,error) {
+
+
+ if !b.HasBalance{
+ err := fmt.Errorf("get balance error:%s", b.BalanceName)
+ return nil, err
+ }
+
+
+
+
+
+ path:= b.Path.Execution(variables)
+
+ // 不是restful时,将匹配路由之后对url拼接到path之后
+ if len(variables.Restful)==0{
+ orgRequestUrl := ctx.RequestOrg.URL().RawPath
+ lessPath := strings.TrimPrefix(orgRequestUrl,b.RequestPath)
+ lessPath = strings.TrimPrefix(lessPath,"/")
+ path = strings.TrimSuffix(path,"/")
+ path = fmt.Sprint(path,"/",lessPath)
+ }
+
+ method:= b.Method
+ if method == "FOLLOW"{
+ method = ctx.ProxyRequest.Method
+ }
+ r, finalTargetServer, retryTargetServers, err := b.Balance.Send(b.Protocol,method , path, ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(),variables.Org, b.TimeOut, b.Retry)
+
+
+ backendResponse := &BackendResponse{
+ Method: method,
+ Protocol: b.Protocol,
+ StatusCode:200,
+ Status:"200" ,
+ //Response: r,
+ TargetUrl: path,
+ FinalTargetServer: finalTargetServer,
+ RetryTargetServers: retryTargetServers,
+ Header:r.Header,
+ //Cookies:r.Cookies(),
+ }
+ if err!=nil{
+ backendResponse.StatusCode,backendResponse.Status = 503,"503"
+ return backendResponse,err
+ }
+ defer r.Body.Close()
+ backendResponse.BodyOrg, err = ioutil.ReadAll(r.Body)
+ if err!= nil{
+ return backendResponse,nil
+ }
+
+ if b.Decode!= nil{
+ rp,e:=response.Decode(backendResponse.BodyOrg,b.Decode)
+ if e!= nil{
+ backendResponse.Body = nil
+ }else {
+ backendResponse.Body = rp.Data
+ }
+ }
+
+ return backendResponse,nil
+
+}
diff --git a/node/gateway/application/backend/response.go b/node/gateway/application/backend/response.go
new file mode 100644
index 0000000000000000000000000000000000000000..7548489cd7eb8f23d9ad6486c26aed566956636d
--- /dev/null
+++ b/node/gateway/application/backend/response.go
@@ -0,0 +1,17 @@
+package backend
+
+import "net/http"
+
+type BackendResponse struct {
+ Method string
+ Protocol string
+ TargetUrl string
+ FinalTargetServer string
+ RetryTargetServers []string
+ BodyOrg []byte
+ Header http.Header
+ Body interface{}
+ StatusCode int
+ Status string
+}
+
diff --git a/node/gateway/application/empty.go b/node/gateway/application/empty.go
new file mode 100644
index 0000000000000000000000000000000000000000..ef18e653715400e167d9875f9990fbbb877c560a
--- /dev/null
+++ b/node/gateway/application/empty.go
@@ -0,0 +1,17 @@
+package application
+
+import "github.com/eolinker/goku-api-gateway/goku-node/common"
+
+type EmptyApplication struct {
+ response string
+}
+
+func (app *EmptyApplication) Execute(ctx *common.Context) {
+ panic("implement me")
+}
+
+func NewEmptyApplication(response string) *EmptyApplication {
+ return &EmptyApplication{
+ response: response,
+ }
+}
diff --git a/node/gateway/application/factory.go b/node/gateway/application/factory.go
new file mode 100644
index 0000000000000000000000000000000000000000..6c89b52c424a70fc62d8f8aaa18a83cf049ef62f
--- /dev/null
+++ b/node/gateway/application/factory.go
@@ -0,0 +1,79 @@
+package application
+
+import (
+ "errors"
+ "fmt"
+ "net/url"
+
+ "github.com/eolinker/goku-api-gateway/config"
+)
+
+var (
+ ErrorInvalidAPI = errors.New("invalid api")
+)
+
+type Factory struct {
+ apiContents map[int]*config.APIContent
+
+ cache map[string]Application
+}
+
+func NewFactory(apis map[int]*config.APIContent) *Factory {
+ return &Factory{
+ apiContents: apis,
+ cache: make(map[string]Application),
+ }
+}
+
+func (f *Factory) GenApplication(cfg *config.APIOfStrategy) (Application, error) {
+
+ apiContent, has := f.apiContents[cfg.ID]
+ if !has {
+ return nil, ErrorInvalidAPI
+ }
+ switch len(apiContent.Steps) {
+ case 0:
+ {
+ key := fmt.Sprintf("Empty:%d", cfg.ID)
+ app, has := f.cache[key]
+ if !has {
+ app = NewEmptyApplication(apiContent.StaticResponse)
+ f.cache[key] = app
+ }
+
+ return app, nil
+ }
+ case 1:
+ {
+ if apiContent.OutPutEncoder == "" || apiContent.OutPutEncoder == "origin" {
+ step := apiContent.Steps[0]
+ balance := step.Balance
+ if cfg.Balance != "" {
+ balance = cfg.Balance
+ }
+ balanceK, _ := url.QueryUnescape(balance)
+ key := fmt.Sprintf("StaticApp:%d:%s", cfg.ID, balanceK)
+ app, has := f.cache[key]
+ if !has {
+ app = NewDefaultApplication(apiContent, balance)
+ f.cache[key] = app
+ }
+
+ return app, nil
+ }
+ }
+ fallthrough
+ default:
+ {
+ key := fmt.Sprintf("LayerApp:%d", cfg.ID)
+ app, has := f.cache[key]
+ if !has {
+ app = NewLayerApplication(apiContent)
+ f.cache[key] = app
+ }
+ return app, nil
+ }
+ }
+
+ return nil, nil
+}
diff --git a/node/gateway/application/interpreter/analysis.go b/node/gateway/application/interpreter/analysis.go
new file mode 100644
index 0000000000000000000000000000000000000000..fbf1d78d852c91b829fb565012e1df7810ec2bff
--- /dev/null
+++ b/node/gateway/application/interpreter/analysis.go
@@ -0,0 +1,218 @@
+package interpreter
+
+import (
+ "bytes"
+ "strings"
+)
+
+var (
+ start = []byte( "{{")
+ end = []byte( "}}")
+
+ restfulStart = []byte("{")
+ restfulEnd = []byte("}")
+ restfulHead = []byte(Restful)
+ restfulSp = []byte("/:")
+ restfulSpE = "/?"
+)
+
+func Gen(tpl string) Interpreter {
+ tpl=strings.TrimSpace(tpl)
+ i,err:=Parse(tpl)
+ if err!= nil{
+ exe := make(_Executor, 1, 1)
+ exe[0] = new(_OrgReader)
+ return exe
+ }
+ return i
+}
+//Parse 编译
+func Parse(tpl string) (Interpreter, error) {
+
+ exe := make(_Executor, 0, 10)
+
+ data := []byte(tpl)
+ for {
+ pre, key, sub := parse(data)
+
+ if pre != nil {
+ exe = append(exe, _NotReader(string(pre)))
+ }
+
+ if key != nil {
+ r, e := genReader(key)
+ if e != nil {
+ return nil, e
+ }
+ exe = append(exe, r)
+ }
+ if sub == nil {
+ break
+ }
+ data = sub
+
+ }
+ return exe, nil
+}
+
+func parse(data []byte) (pre, key, sub []byte) {
+
+ firstStart := bytes.Index(data, start)
+ if firstStart == -1 {
+ return data, nil, nil
+ }
+ firstEnd := bytes.Index(data[firstStart:], end)
+ if firstEnd == -1 {
+ return data, nil, nil
+ }
+ firstEnd += firstStart
+ pre = data[:firstStart]
+ key = data[firstStart+2 : firstEnd]
+ if firstEnd+2 < len(data) {
+ sub = data[firstEnd+2:]
+ }
+ return
+}
+
+func GenPath(path string) Interpreter {
+ interpreter, e := ParsePath(path)
+ if e != nil{
+ exe := make(_Executor, 1, 1)
+ exe[0] = _NotReader(path)
+ return exe
+ }
+ return interpreter
+}
+func ParsePath(path string) (Interpreter, error) {
+
+ exe := make(_Executor, 0, 10)
+
+ data := []byte(path)
+ for {
+ pre, key, sub := parse(data)
+
+ //fmt.Println("pre:", string(pre), "\tkey:", string(key), "\tsub:", string(sub))
+ if pre != nil {
+ restfulReader, err := parsePath(pre)
+ if err != nil {
+ return nil, err
+ }
+ exe = append(exe, restfulReader...)
+ }
+
+ if key != nil {
+ r, e := genReader(key)
+ if e != nil {
+ return nil, e
+ }
+ exe = append(exe, r)
+ }
+ if sub == nil {
+ break
+ }
+ data = sub
+
+ }
+ return exe, nil
+
+}
+
+func parsePath(line []byte) ([]Reader, error) {
+ readers := make([]Reader, 0, 10)
+ data := line
+ for {
+ pre, key, sub := parsePathDo(data)
+
+ //fmt.Println("path:\tpre:", string(pre), "\tkey:", string(key), "\tsub:", string(sub))
+ if pre != nil {
+
+ restfulReader, err := parseRestful(pre)
+ if err != nil {
+ return nil, err
+ }
+ readers = append(readers, restfulReader...)
+ }
+
+ if key != nil {
+ r, e := genResfult(restfulHead, key)
+ if e != nil {
+ return nil, e
+ }
+ readers = append(readers, r)
+ }
+ if sub == nil {
+ break
+ }
+ data = sub
+
+ }
+ return readers, nil
+}
+
+func parsePathDo(line []byte) (pre, key, sub []byte) {
+
+ firstStart := bytes.Index(line, restfulStart)
+ if firstStart == -1 {
+ return line, nil, nil
+ }
+ firstEnd := bytes.Index(line[firstStart:], restfulEnd)
+ if firstEnd == -1 {
+ return line, nil, nil
+ }
+ firstEnd += firstStart
+ pre = line[:firstStart]
+ key = line[firstStart+1 : firstEnd]
+ if firstEnd+1 < len(line) {
+ sub = line[firstEnd+1:]
+ }
+ return
+}
+func parseRestful(line []byte) ([]Reader, error) {
+ readers := make([]Reader, 0, 10)
+ data := line
+ for {
+ pre, key, sub := parseRestfulDo(data)
+
+ //fmt.Println("restful:\tpre:", string(pre), "\tkey:", string(key), "\tsub:", string(sub))
+ if pre != nil {
+ readers = append(readers, _NotReader(pre))
+ }
+
+ if key != nil {
+ r, e := genResfult(restfulHead, key)
+ if e != nil {
+ return nil, e
+ }
+ readers = append(readers, r)
+ }
+ if sub == nil {
+ break
+ }
+ data = sub
+
+ }
+ return readers, nil
+}
+func parseRestfulDo(line []byte) (pre, key, sub []byte) {
+
+ firstStart := bytes.Index(line, restfulSp)
+ if firstStart == -1 {
+ return line, nil, nil
+ }
+ firstEnd := bytes.IndexAny(line[firstStart+2:], restfulSpE)
+ if firstEnd == -1 {
+ pre = line[:firstStart+1]
+ key = line[firstStart+2:]
+ sub = nil
+ return
+ }
+
+ firstEnd += firstStart+2
+ pre = line[:firstStart+1]
+ key = line[firstStart+2 : firstEnd]
+
+ if firstEnd+1 < len(line) {
+ sub = line[firstEnd:]
+ }
+ return
+}
diff --git a/node/gateway/application/interpreter/anlysis_test.go b/node/gateway/application/interpreter/anlysis_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..ebb6ce96b35f0e41b1718746c0d4b7343618bbf1
--- /dev/null
+++ b/node/gateway/application/interpreter/anlysis_test.go
@@ -0,0 +1,55 @@
+package interpreter
+
+import (
+ "fmt"
+ "net/http"
+ "testing"
+)
+
+func TestParse(t *testing.T) {
+
+ tpl := "header:{{header.va}},cookie:{cookie.name},restful:id={{restful.name}},body:{{body.name}}"
+
+ body := map[string]interface{}{
+ "name": "bodyName",
+ }
+ header := http.Header{}
+ header.Set("va", "headVA")
+ cookie := []*http.Cookie{{Name: "name", Value: "kingsword"}}
+ resfult := map[string]string{
+ "id": "1",
+ "name": "app",
+ }
+ variables := NewVariables("{xxxx}", body, header, cookie, resfult, 1)
+
+ interpreter, e := Parse(tpl)
+ if e != nil {
+
+ t.Fatal(e)
+ return
+ }
+
+ path := "/xxx/{name}/:id/:name?a=1"
+
+ interpreterpath, e := ParsePath(path)
+ if e != nil {
+
+ t.Fatal(e)
+ return
+ }
+ fmt.Println("path:\n\t", path)
+ fmt.Println("target:\n\t", interpreterpath.Execution(variables))
+
+ //variables.AppendResponse(header,body,cookie)
+ //
+ //
+ //tpl2:="header:{{header1.va}},cookie:{{cookie1.name}},restful:id={{restful.id}}"
+ //interpreter2, e := Parse(tpl2)
+ //if e!= nil{
+ //
+ // t.Fatal(e)
+ // return
+ //}
+ //fmt.Println("tpl2:\n\t",tpl2)
+ //fmt.Println("target:\n\t",interpreter2.Execution(variables))
+}
diff --git a/node/gateway/application/interpreter/error.go b/node/gateway/application/interpreter/error.go
new file mode 100644
index 0000000000000000000000000000000000000000..8d8965e2cf03d25eddba0de330a60671e49a1040
--- /dev/null
+++ b/node/gateway/application/interpreter/error.go
@@ -0,0 +1,12 @@
+package interpreter
+
+import "fmt"
+
+type GrammarError string
+
+func (e GrammarError)Error()string {
+ return fmt.Sprint("Invalid:",string(e))
+}
+func (e GrammarError)String()string {
+ return e.Error()
+}
diff --git a/node/gateway/application/interpreter/interpreter.go b/node/gateway/application/interpreter/interpreter.go
new file mode 100644
index 0000000000000000000000000000000000000000..9f6b80321ba445397e78a5af6936af38a4fa2f86
--- /dev/null
+++ b/node/gateway/application/interpreter/interpreter.go
@@ -0,0 +1,86 @@
+package interpreter
+
+import (
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+type _Cookies []*http.Cookie
+type Variables struct {
+ Org []byte
+ Bodes []interface{}
+ Headers []http.Header
+ Cookies []_Cookies
+ Restful map[string]string
+ Query url.Values
+
+}
+
+func (v *Variables) MergeResponse() (interface{} ,http.Header) {
+
+ body:= MergeBodys(v.Bodes[1:])
+
+ header := MergeHeaders(v.Headers[1:])
+
+ cookies := MergeCookies(v.Cookies[1:])
+
+ // 把cookie加回header中
+ rt:= &http.Request{Header:header}
+ for _,c:=range cookies{
+ rt.AddCookie(c)
+ }
+
+ return body, header
+}
+func NewVariables(org []byte,body interface{},header http.Header,cookie []*http.Cookie,restful map[string]string,query url.Values, size int) *Variables {
+ max:=size+1
+ bodes :=make([]interface{},0,max)
+ headers:=make([]http.Header,0,max)
+ cookies:=make([]_Cookies,0,max)
+
+ v:= &Variables{
+ Org: org,
+ Bodes: append(bodes,body),
+ Headers: append(headers,header),
+ Restful: restful,
+ Query:query,
+ }
+ v.Cookies = append(cookies,cookie)
+ // 暂时先删除掉cookie
+ header.Del("Cookie")
+
+ return v
+}
+func (v *Variables) AppendResponse(header http.Header,body interface{}) {
+ v.Headers = append(v.Headers,header)
+ v.Bodes = append(v.Bodes,body)
+ req:= http.Request{Header:header}
+ v.Cookies = append(v.Cookies, _Cookies(req.Cookies()))
+ // 暂时先删除掉cookie
+ header.Del("Cookie")
+}
+
+type Interpreter interface {
+ Execution(value *Variables)string
+}
+
+
+type _Executor []Reader
+
+func (exe _Executor) Execution(value *Variables) string {
+
+ switch len(exe) {
+ case 0:
+ return ""
+ case 1:
+ return exe[0].Read(value)
+ }
+ builder:=strings.Builder{}
+
+ for _,r:=range exe{
+ builder.WriteString(r.Read(value))
+ }
+ return builder.String()
+
+}
diff --git a/node/gateway/application/interpreter/merge.go b/node/gateway/application/interpreter/merge.go
new file mode 100644
index 0000000000000000000000000000000000000000..b13e1e8f7f6f06e7997b29fde0ea9ba4df4d36ca
--- /dev/null
+++ b/node/gateway/application/interpreter/merge.go
@@ -0,0 +1,89 @@
+package interpreter
+
+import "net/http"
+
+func MergeBodys( bodys []interface{})interface{} {
+
+ if isAllMap(bodys){
+
+ b1:=bodys[0]
+ mall:=b1.(map[string]interface{})
+
+ for _,b:=range bodys{
+
+ m:=b.(map[string]interface{})
+
+ for k,v:=range m{
+ mall[k]=v
+ }
+
+ }
+ return mall
+ }
+ if isAllSlice(bodys){
+
+ return bodys
+ }
+ return make(map[string]interface{},0)
+}
+
+
+func isAllSlice(bodys []interface{}) bool {
+
+ for _,b:=range bodys{
+
+ switch b.(type) {
+ case []map[string]interface{},[]interface{}:
+ continue
+ default:
+ return false
+ }
+ }
+ return true
+}
+func isAllMap(bodys []interface{}) bool {
+
+ for _,b:=range bodys{
+
+ switch b.(type) {
+ case map[string]interface{}:
+ continue
+ default:
+ return false
+ }
+ }
+ return true
+}
+
+func MergeHeaders(Headers []http.Header) http.Header{
+
+ header := Headers[0]
+
+ for _,h:=range Headers[1:]{
+
+ for k,v:=range h{
+
+ header[k] = v
+ }
+ }
+
+ return header
+}
+
+func MergeCookies( cookies []_Cookies) []*http.Cookie {
+
+ allCookies:=make(map[string]*http.Cookie)
+
+ for _,cs:=range cookies{
+ for _,c:=range cs{
+ allCookies[c.Name] = c
+ }
+ }
+ newCookies:= make([]*http.Cookie,0,len(allCookies))
+ for _,c:=range allCookies{
+
+ newCookies = append(newCookies,c)
+
+ }
+ return newCookies
+}
\ No newline at end of file
diff --git a/node/gateway/application/interpreter/reader-create.go b/node/gateway/application/interpreter/reader-create.go
new file mode 100644
index 0000000000000000000000000000000000000000..0ffe61231e661d2f256b1859003b03e50c026c26
--- /dev/null
+++ b/node/gateway/application/interpreter/reader-create.go
@@ -0,0 +1,137 @@
+package interpreter
+
+import (
+ "bytes"
+ "strconv"
+ "strings"
+)
+type ReaderCreateFunc func(head []byte,body[]byte)(Reader,error)
+
+const (
+ Body="body"
+ Header="header"
+ Restful="restful"
+ Query = "query"
+ Cookie="cookie"
+)
+
+var(
+ creators map[string]ReaderCreateFunc
+ readers map[string][]byte
+ pathSplitSeq = []byte(".")
+)
+func init() {
+ creators = make(map[string]ReaderCreateFunc)
+ readers = make(map[string][]byte)
+
+ readers[Body[:4]]=[]byte(Body)
+ readers[Header[:4]]=[]byte(Header)
+ readers[Restful[:4]]=[]byte(Restful)
+ readers[Cookie[:4]]=[]byte(Cookie)
+ readers[Query[:4]]=[]byte(Query)
+
+ creators[Body] = ReaderCreateFunc(func(head []byte,body[]byte)(Reader,error) {
+
+ index := 0
+ if len(head)>len(Body){
+ indexData := head[len(Body):]
+ i,err:= strconv.Atoi(string(indexData))
+ if err!= nil{
+ return nil,err
+ }
+ index = i
+ }
+
+ pathData:= bytes.Split(body,pathSplitSeq)
+
+ path:=make([]string,0,len(pathData))
+ for _,p:=range pathData{
+ path= append(path,string(p))
+ }
+
+
+ return &_BodyReader{
+ Index: index,
+ Path: path,
+ Name:string(body),
+ }, nil
+ })
+ creators[Header] = ReaderCreateFunc(func(head []byte,body[]byte)(Reader,error) {
+ index := 0
+ if len(head)>len(Header){
+ indexData := head[len(Header):]
+ i,err:= strconv.Atoi(string(indexData))
+ if err!= nil{
+ return nil,err
+ }
+ index = i
+ }
+
+ return &_HeaderReader{
+ Index: index,
+ Key: string(body),
+ }, nil
+ })
+ creators[Query] = ReaderCreateFunc(func(head []byte,body[]byte)(Reader,error) {
+ if !bytes.Equal(head,[]byte(Query)){
+ return nil,GrammarError(string(head))
+ }
+ return &_QueryReader{
+ Key: string(body),
+ },nil
+ })
+ creators[Restful] = ReaderCreateFunc(genResfult)
+ creators[Cookie] = ReaderCreateFunc(func(head []byte,body[]byte)(Reader,error) {
+ index := 0
+ if len(head)>len(Cookie){
+ indexData := head[len(Cookie):]
+ i,err:= strconv.Atoi(string(indexData))
+ if err!= nil{
+ return nil,err
+ }
+ index = i
+ }
+
+ return &_CookieReader{
+ Index: index,
+ Name: string(body),
+ }, nil
+ })
+}
+
+func genResfult(head[]byte,body[]byte)(Reader,error) {
+
+ if !bytes.Equal(head,[]byte(Restful)){
+ return nil,GrammarError(string(head))
+ }
+ return &_RestFulReader{
+ Key: string(body),
+ },nil
+}
+
+func genReader(line []byte)(Reader ,error) {
+
+ kindex:=bytes.IndexAny(line,".")
+
+ if kindex == -1{
+ return nil, GrammarError(line)
+ }
+
+ key:= line[:kindex]
+ keyPre:=strings.ToLower(string(key[:4]))
+
+ cmd,has:=readers[keyPre]
+ if !has{
+ return nil,GrammarError(string(line))
+ }
+ if !bytes.HasPrefix(key,cmd){
+ return nil,GrammarError(string(line))
+ }
+
+ create:= creators[string(cmd)]
+
+ return create(bytes.ToLower(key),line[kindex+1:])
+
+}
+
+
diff --git a/node/gateway/application/interpreter/reader.go b/node/gateway/application/interpreter/reader.go
new file mode 100644
index 0000000000000000000000000000000000000000..4ff0a78c863921fa8b746ab55e5569cbf08efd47
--- /dev/null
+++ b/node/gateway/application/interpreter/reader.go
@@ -0,0 +1,122 @@
+package interpreter
+
+import (
+ "fmt"
+ "net/url"
+ "reflect"
+)
+
+type Reader interface {
+ Read(variables *Variables)string
+}
+
+
+
+type _NotReader string
+
+func (r _NotReader) Read(variables *Variables) string {
+ return string(r)
+}
+
+type _OrgReader struct {
+
+}
+
+func (r *_OrgReader) Read(variables *Variables) string {
+ return string(variables.Org)
+}
+
+type _BodyReader struct {
+ Index int
+ Path []string
+ Name string
+}
+
+func (r*_BodyReader) Read(variables *Variables) string {
+
+ if len(variables.Bodes) <= r.Index{
+ return ""
+ }
+ if r.Index == 0{
+ body:= variables.Bodes[r.Index]
+ form,ok:= body.(url.Values)
+ if ok{
+ return form.Get(r.Name)
+ }
+ }
+
+ root:= reflect.ValueOf(variables.Bodes[r.Index])
+ return find(&root,r.Path)
+}
+func find(node *reflect.Value,path[]string) string {
+
+ if len(path) == 0{
+ return fmt.Sprint(node.Interface())
+ }
+
+ k:= node.Kind()
+
+ switch k {
+
+ case reflect.Interface:
+
+ next:=node.Elem()
+ return find(&next,path)
+ case reflect.Map:
+ {
+ key:=reflect.ValueOf( path[0])
+ next:=node.MapIndex(key)
+ return find(&next,path[1:])
+ }
+ default:
+ return ""
+ }
+
+ return ""
+}
+
+
+type _HeaderReader struct {
+ Index int
+ Key string
+}
+
+func (r *_HeaderReader) Read(variables *Variables) string {
+ if len(variables.Headers) <= r.Index{
+ return ""
+ }
+
+ return variables.Headers[r.Index].Get(r.Key)
+}
+
+type _RestFulReader struct {
+ Key string
+}
+
+func (r *_RestFulReader) Read(variables *Variables) string {
+ return variables.Restful[r.Key]
+}
+type _QueryReader struct {
+ Key string
+}
+
+func (r *_QueryReader) Read(variables *Variables) string {
+ return variables.Query.Get(r.Key)
+}
+
+type _CookieReader struct {
+ Index int
+ Name string
+}
+
+func (r *_CookieReader) Read(variables *Variables) string {
+ if len(variables.Cookies) <= r.Index{
+ return ""
+ }
+ for _,c:=range variables.Cookies[r.Index]{
+ if c.Name == r.Name{
+ return c.Value
+ }
+ }
+ return ""
+}
diff --git a/node/gateway/application/layer.go b/node/gateway/application/layer.go
new file mode 100644
index 0000000000000000000000000000000000000000..79b6ba51df86ff04a93b0c7b0374bc066304a353
--- /dev/null
+++ b/node/gateway/application/layer.go
@@ -0,0 +1,134 @@
+package application
+
+import (
+ "context"
+ "time"
+
+ "github.com/eolinker/goku-api-gateway/config"
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+ "github.com/eolinker/goku-api-gateway/node/gateway/application/backend"
+ "github.com/eolinker/goku-api-gateway/node/gateway/application/interpreter"
+ "github.com/eolinker/goku-api-gateway/node/gateway/response"
+)
+
+type LayerApplication struct {
+ output response.Encoder
+ backsides []*backend.Layer
+ static *staticeResponse
+
+ timeOut time.Duration
+}
+
+func (app *LayerApplication) Execute(ctx *common.Context) {
+
+ orgBody, _ := ctx.ProxyRequest.RawBody()
+
+ bodyObj, _ := ctx.ProxyRequest.BodyInterface()
+
+ variables := interpreter.NewVariables(orgBody, bodyObj, ctx.ProxyRequest.Headers(), ctx.ProxyRequest.Cookies(), ctx.RestfulParam, ctx.ProxyRequest.Querys(), len(app.backsides))
+
+ deadline := context.Background()
+ cancelFunc := context.CancelFunc(nil)
+ app.timeOut = 0
+ if app.timeOut > 0 {
+ deadline, cancelFunc = context.WithDeadline(deadline, time.Now().Add(app.timeOut))
+ } else {
+ deadline, cancelFunc = context.WithCancel(deadline)
+ }
+
+ resC := make(chan int, 1)
+ errC := make(chan error, 1)
+ go app.do(deadline, variables, ctx, resC, errC)
+
+ defer func() {
+ close(resC)
+ close(errC)
+ }()
+
+ select {
+ case <-deadline.Done():
+ ctx.SetStatus(503, "503")
+ ctx.SetBody([]byte("[ERROR]timeout!"))
+ // 超时
+ return
+ case <-errC:
+
+ cancelFunc()
+ ctx.SetStatus(504, "504")
+ ctx.SetBody([]byte("[ERROR]Fail to get response after proxy!"))
+ //error
+ return
+ case <-resC:
+ //response
+ cancelFunc()
+ break
+ }
+
+ mergeResponse, headers := variables.MergeResponse()
+
+ body, e := app.output.Encode(mergeResponse, nil)
+ if e != nil {
+ log.Warn("encode response error:", e)
+ return
+ }
+
+ ctx.SetProxyResponseHandler(common.NewResponseReader(headers, 200, "200", body))
+
+}
+func (app *LayerApplication) do(ctxDeadline context.Context, variables *interpreter.Variables, ctx *common.Context, resC chan<- int, errC chan<- error) {
+
+ l := len(app.backsides)
+ for i, b := range app.backsides {
+
+ if deadline, ok := ctxDeadline.Deadline(); ok {
+ if time.Now().After(deadline) {
+ // 超时
+ log.Warn("time out before send step:", i, "/", l)
+ return
+ }
+ }
+ r, err := b.Send(ctx, variables, ctxDeadline)
+
+ if deadline, ok := ctxDeadline.Deadline(); ok {
+ if time.Now().After(deadline) {
+ // 超时
+ log.Warn("time out before send step:", i+1, "/", l)
+ return
+ }
+ }
+ if err != nil {
+ errC <- err
+ log.Warn("error by send step:", i+1, "/", l, "\t:", err)
+ return
+ }
+ variables.AppendResponse(r.Header, r.Body)
+ }
+ if deadline, ok := ctxDeadline.Deadline(); ok {
+ if time.Now().After(deadline) {
+ // 超时
+ log.Warn("time out before send step:", l, "/", l)
+ return
+ }
+ }
+ resC <- 1
+
+}
+func NewLayerApplication(apiContent *config.APIContent) *LayerApplication {
+ app := &LayerApplication{
+ output: response.GetEncoder(apiContent.OutPutEncoder),
+ backsides: make([]*backend.Layer, 0, len(apiContent.Steps)),
+ static: nil,
+ timeOut: time.Duration(apiContent.TimeOutTotal) * time.Millisecond,
+ }
+
+ for _, step := range apiContent.Steps {
+ app.backsides = append(app.backsides, backend.NewLayer(step))
+ }
+
+ if apiContent.StaticResponse != "" {
+ staticResponseStrategy := config.Parse(apiContent.StaticResponseStrategy)
+ app.static = newStaticeResponse(apiContent.StaticResponse, staticResponseStrategy)
+ }
+ return app
+}
diff --git a/node/gateway/application/proxy.go b/node/gateway/application/proxy.go
new file mode 100644
index 0000000000000000000000000000000000000000..d3273f7f80b88a06c2f46e44c086e4c24939033c
--- /dev/null
+++ b/node/gateway/application/proxy.go
@@ -0,0 +1,92 @@
+package application
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/eolinker/goku-api-gateway/config"
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+ "github.com/eolinker/goku-api-gateway/node/gateway/application/backend"
+ "github.com/eolinker/goku-api-gateway/node/gateway/application/interpreter"
+
+ "github.com/eolinker/goku-api-gateway/node/gateway/response"
+ access_field "github.com/eolinker/goku-api-gateway/server/access-field"
+)
+
+type DefaultApplication struct {
+ output response.Encoder
+ backend *backend.Proxy
+ static *staticeResponse
+ balanceTarget string
+}
+
+func NewDefaultApplication(apiContent *config.APIContent, target string) *DefaultApplication {
+
+ app := &DefaultApplication{
+ backend: nil,
+ static: nil,
+ balanceTarget: target,
+ output: response.GetEncoder(apiContent.OutPutEncoder),
+ }
+ if len(apiContent.Steps) == 1 {
+ step := apiContent.Steps[0]
+ app.backend = backend.NewProxyBackendTarget(step, apiContent.RequestURL, target)
+ }
+ if apiContent.StaticResponse != "" {
+ staticResponseStrategy := config.Parse(apiContent.StaticResponseStrategy)
+ app.static = newStaticeResponse(apiContent.StaticResponse, staticResponseStrategy)
+ }
+
+ return app
+}
+
+func (app *DefaultApplication) Execute(ctx *common.Context) {
+
+ ctx.LogFields[access_field.Balance] = app.balanceTarget
+
+ if app.backend != nil {
+ orgBody, _ := ctx.ProxyRequest.RawBody()
+
+ variables := interpreter.NewVariables(orgBody, nil, ctx.ProxyRequest.Headers(), ctx.ProxyRequest.Cookies(), ctx.RestfulParam, ctx.ProxyRequest.Querys(), 1)
+
+ r, err := app.backend.Send(ctx, variables)
+ if r != nil {
+
+ ctx.ProxyRequest.Method = r.Method
+ ctx.ProxyRequest.SetTargetURL(r.TargetUrl)
+
+ ctx.SetRetryTargetServers(strings.Join(r.RetryTargetServers, ","))
+ ctx.SetFinalTargetServer(r.FinalTargetServer)
+
+ ctx.LogFields[access_field.FinallyServer] = ctx.FinalTargetServer()
+ ctx.LogFields[access_field.Retry] = ctx.RetryTargetServers()
+ ctx.LogFields[access_field.Proxy] = fmt.Sprintf("\"%s %s %s\"", r.Method, r.TargetUrl, r.Protocol)
+
+ }
+ if err != nil {
+
+ log.Warn(err)
+ return
+ }
+
+ ctx.LogFields[access_field.ProxyStatusCode] = r.StatusCode
+
+ body, err := app.output.Encode(r.Body, r.BodyOrg)
+ if err != nil {
+ body = r.BodyOrg
+ }
+ ctx.SetProxyResponseHandler(common.NewResponseReader(r.Header, r.StatusCode, r.Status, body))
+
+ return
+
+ }
+ if app.static != nil {
+ app.static.Do(ctx)
+ return
+ }
+
+ ctx.SetStatus(504, "504")
+ ctx.SetBody([]byte("[ERROR]Fail to get response after proxy!"))
+
+}
diff --git a/node/gateway/application/static-response.go b/node/gateway/application/static-response.go
new file mode 100644
index 0000000000000000000000000000000000000000..a5b7d04e740ab0787751cbcfec2abed47fea3732
--- /dev/null
+++ b/node/gateway/application/static-response.go
@@ -0,0 +1,20 @@
+package application
+
+import (
+ "github.com/eolinker/goku-api-gateway/config"
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+)
+
+type staticeResponse struct {
+ body []byte
+ strategy config.StaticResponseStrategy
+}
+
+func newStaticeResponse(body string, strategy config.StaticResponseStrategy) *staticeResponse {
+ return &staticeResponse{body: []byte(body), strategy: strategy}
+}
+
+func (sp *staticeResponse) Do(ctx *common.Context) {
+ ctx.SetBody(sp.body)
+ ctx.SetStatus(200,"200")
+}
\ No newline at end of file
diff --git a/node/gateway/befor.go b/node/gateway/befor.go
new file mode 100644
index 0000000000000000000000000000000000000000..69d255add127e2754ca91f848eedb22c3d26fe80
--- /dev/null
+++ b/node/gateway/befor.go
@@ -0,0 +1,90 @@
+package gateway
+
+import (
+ "net/http"
+ "time"
+
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+ plugin_executor "github.com/eolinker/goku-api-gateway/node/gateway/plugin-executor"
+ "github.com/eolinker/goku-api-gateway/node/utils"
+)
+
+//Before before
+type Before struct {
+ pluginBefor []plugin_executor.Executor
+ pluginGlobalBefor []plugin_executor.Executor
+
+ strategies map[string]*Strategy
+ anonymousStrategy string
+}
+
+//Router 路由
+func (r *Before) Router(w http.ResponseWriter, req *http.Request, ctx *common.Context) {
+ start := time.Now()
+ isBefore := r.BeforeMatch(ctx)
+ log.Info(ctx.RequestId(), " BeforeMatch plugin duration:", time.Since(start))
+ if !isBefore {
+ log.Info(ctx.RequestId(), " stop by BeforeMatch plugin")
+ return
+ }
+ r.rout(w, req, ctx)
+}
+
+//BeforeMatch 插件流程,匹配URI及策略前执行
+func (r *Before) BeforeMatch(ctx *common.Context) bool {
+ requestID := ctx.RequestId()
+ defer func(ctx *common.Context) {
+ log.Debug(requestID, " before plugin default: begin")
+ for _, handler := range r.pluginGlobalBefor {
+
+ _, _ = handler.Execute(ctx)
+
+ }
+ log.Debug(requestID, " before plugin default: end")
+ }(ctx)
+ log.Debug(requestID, " before plugin : begin")
+ for _, handler := range r.pluginBefor {
+
+ flag, _ := handler.Execute(ctx)
+
+ if flag == false {
+ if handler.IsStop() == true {
+ return false
+ }
+ }
+ }
+ log.Debug(requestID, " before plugin : end")
+ return true
+
+}
+
+func (r *Before) rout(w http.ResponseWriter, req *http.Request, ctx *common.Context) {
+ strategyID := utils.GetStrateyID(ctx)
+ if strategyID == "" {
+ // 没有策略id
+ if r.anonymousStrategy == "" {
+ // 没有开放策略
+ go log.Info("[ERROR]Missing Strategy ID!")
+ ctx.SetStatus(500, "500")
+
+ ctx.SetBody([]byte("[ERROR]Missing Strategy ID!"))
+ return
+ }
+
+ strategyID = r.anonymousStrategy
+ }
+
+ v, has := r.strategies[strategyID]
+
+ if !has {
+ go log.Info("[ERROR]StrategyID dose not exist!")
+
+ ctx.SetStatus(500, "500")
+
+ ctx.SetBody([]byte("[ERROR]StrategyID dose not exist!"))
+ return
+ }
+ v.Router(w, req, ctx)
+
+}
diff --git a/node/gateway/const.go b/node/gateway/const.go
new file mode 100644
index 0000000000000000000000000000000000000000..6c6a23466e269fd1b35235f09a76a4f51594c047
--- /dev/null
+++ b/node/gateway/const.go
@@ -0,0 +1,10 @@
+package gateway
+
+var(
+ authNames = map[string]string{
+ "Oauth2": "goku-oauth2_auth",
+ "Apikey": "goku-apikey_auth",
+ "Basic": "goku-basic_auth",
+ "Jwt": "goku-jwt_auth",
+ }
+)
\ No newline at end of file
diff --git a/node/gateway/http.go b/node/gateway/http.go
new file mode 100644
index 0000000000000000000000000000000000000000..fc3115bc704904a16837f3798a247bef1cf74e2d
--- /dev/null
+++ b/node/gateway/http.go
@@ -0,0 +1,74 @@
+package gateway
+
+import (
+ "fmt"
+ "net/http"
+ "time"
+
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+ access_log "github.com/eolinker/goku-api-gateway/goku-node/access-log"
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+ "github.com/eolinker/goku-api-gateway/node/utils"
+ fields "github.com/eolinker/goku-api-gateway/server/access-field"
+)
+
+var systemRequestPath = []string{"/oauth2/token", "/oauth2/authorize", "/oauth2/verify"}
+
+//HTTPHandler httpHandler
+type HTTPHandler struct {
+ router *Before
+}
+
+func (h *HTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ timeStart := time.Now()
+ // 记录访问次数
+ requestID := utils.GetRandomString(16)
+
+ ctx := common.NewContext(req, requestID, w)
+
+ log.Debug(requestID, " url: ", ctx.Request().URL().String())
+ log.Debug(requestID, " header: ", ctx.RequestOrg.Header.String())
+
+ if log.GetLogger().Level == log.DebugLevel {
+ rawBody, err := ctx.RequestOrg.RawBody()
+ if err == nil {
+ log.Debug(requestID, " body: ", string(rawBody))
+ }
+ }
+ remoteAddr := utils.Intercept(req.RemoteAddr, ":")
+ ctx.LogFields[fields.RemoteAddr] = remoteAddr
+
+ if realIP := ctx.GetHeader("X-Real-Ip"); realIP == "" {
+ ctx.ProxyRequest.SetHeader("X-Real-Ip", remoteAddr)
+ ctx.LogFields[fields.HTTPXForwardedFor] = remoteAddr
+ } else {
+ ctx.LogFields[fields.HTTPXForwardedFor] = realIP
+ }
+
+ h.router.Router(w, req, ctx)
+
+ n, status := ctx.Finish()
+
+ //proxyStatusCode := 0
+ //if ctx.ProxyResponseHandler != nil {
+ // proxyStatusCode = ctx.ProxyResponseHandler.StatusCode()
+ //}
+
+ ctx.LogFields[fields.RequestID] = requestID
+ ctx.LogFields[fields.StatusCode] = status
+ ctx.LogFields[fields.HTTPUserAgent] = fmt.Sprint("\"", req.UserAgent(), "\"")
+ ctx.LogFields[fields.HTTPReferer] = req.Referer()
+ ctx.LogFields[fields.RequestTime] = time.Since(timeStart)
+ ctx.LogFields[fields.Request] = fmt.Sprint("\"", req.Method, " ", req.URL.Path, " ", req.Proto, "\"")
+ ctx.LogFields[fields.BodyBytesSent] = n
+ ctx.LogFields[fields.Host] = req.Host
+ access_log.Log(ctx.LogFields)
+ log.WithFields(ctx.LogFields).Info()
+
+ //for _, path := range systemRequestPath {
+ // if path == req.URL.Path {
+ // return
+ // }
+ //}
+
+}
diff --git a/node/gateway/plugin-executor/executor.go b/node/gateway/plugin-executor/executor.go
new file mode 100644
index 0000000000000000000000000000000000000000..bb75ca1399dca80390741fb0b6e4c2a20bf49e2d
--- /dev/null
+++ b/node/gateway/plugin-executor/executor.go
@@ -0,0 +1,111 @@
+package plugin_executor
+
+import (
+ goku_plugin "github.com/eolinker/goku-plugin"
+ "github.com/eolinker/goku-api-gateway/config"
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+ "time"
+)
+
+type Executor interface {
+ Execute(ctx *common.Context)(isContinue bool, e error)
+ IsStop()bool
+}
+type executorInfo struct {
+ Name string
+ isStop bool
+}
+
+
+
+func (ex*executorInfo) IsStop() bool {
+ return ex.isStop
+}
+
+func genExecutor(cfg *config.PluginConfig) executorInfo {
+ return executorInfo{
+ Name:cfg.Name,
+ isStop:cfg.IsStop,
+ }
+}
+type beforeExecutor struct {
+ executorInfo
+ plugin goku_plugin.PluginBeforeMatch
+
+}
+
+func (ex*beforeExecutor) Execute(ctx *common.Context) (isContinue bool, e error) {
+ requestId:=ctx.RequestId()
+ ctx.SetPlugin(ex.Name)
+ log.Debug(requestId, " before plugin :", ex.Name, " start")
+ now := time.Now()
+ isContinue, err := ex.plugin.BeforeMatch(ctx)
+ log.Debug(requestId, " before plugin :", ex.Name, " Duration:", time.Since(now))
+ log.Debug(requestId, " before plugin :", ex.Name, " end")
+ if err != nil {
+ log.Warn(requestId, " before plugin:", ex.Name, " error:", err)
+ }
+ return isContinue,err
+}
+
+func NewBeforeExecutor(cfg *config.PluginConfig,p goku_plugin.PluginBeforeMatch ) *beforeExecutor {
+ return &beforeExecutor{
+ executorInfo: genExecutor(cfg),
+ plugin: p,
+ }
+
+}
+type accessExecutor struct {
+ executorInfo
+ plugin goku_plugin.PluginAccess
+}
+
+func (ex *accessExecutor) Execute(ctx *common.Context) (isContinue bool, e error) {
+ requestId:=ctx.RequestId()
+ ctx.SetPlugin(ex.Name)
+
+ log.Debug(requestId, " access plugin :", ex.Name, " start")
+ now := time.Now()
+ isContinue, err := ex.plugin.Access(ctx)
+ log.Debug(requestId, " access plugin :", ex.Name, " Duration:", time.Since(now))
+ log.Debug(requestId, " access plugin :", ex.Name, " end")
+ if err != nil {
+ log.Warn(requestId, " access plugin:", ex.Name, " error:", err)
+ }
+ return isContinue,err
+}
+
+func NewAccessExecutor(cfg *config.PluginConfig,p goku_plugin.PluginAccess ) *accessExecutor {
+ return &accessExecutor{
+ executorInfo: genExecutor(cfg),
+ plugin: p,
+ }
+}
+
+type proxyExecutor struct {
+ executorInfo
+ plugin goku_plugin.PluginProxy
+}
+
+func (ex*proxyExecutor) Execute(ctx *common.Context) (isContinue bool, e error) {
+ requestId:=ctx.RequestId()
+ ctx.SetPlugin(ex.Name)
+
+ log.Debug(requestId, " proxy plugin :", ex.Name, " start")
+ now := time.Now()
+ isContinue, err := ex.plugin.Proxy(ctx)
+ log.Debug(requestId, " proxy plugin :", ex.Name, " Duration:", time.Since(now))
+ log.Debug(requestId, " proxy plugin :", ex.Name, " end")
+ if err != nil {
+ log.Warn(requestId, " proxy plugin:", ex.Name, " error:", err)
+ }
+ return isContinue,err
+}
+
+func NewProxyExecutor(cfg *config.PluginConfig,p goku_plugin.PluginProxy ) *proxyExecutor {
+ return &proxyExecutor{
+ executorInfo: genExecutor(cfg),
+ plugin: p,
+ }
+}
\ No newline at end of file
diff --git a/node/gateway/plugin.go b/node/gateway/plugin.go
new file mode 100644
index 0000000000000000000000000000000000000000..4427e80279c7772dab517c1e102e51023202dec4
--- /dev/null
+++ b/node/gateway/plugin.go
@@ -0,0 +1,59 @@
+package gateway
+
+import (
+ "reflect"
+
+ "github.com/eolinker/goku-api-gateway/config"
+ plugin_executor "github.com/eolinker/goku-api-gateway/node/gateway/plugin-executor"
+ plugin "github.com/eolinker/goku-api-gateway/node/plugin-loader"
+)
+
+func genBeforPlugin(cfgs []*config.PluginConfig, cluster string) []plugin_executor.Executor {
+ ps := make([]plugin_executor.Executor, 0, len(cfgs))
+ for _, cfg := range cfgs {
+
+ factory, e := plugin.LoadPlugin(cfg.Name)
+ if e != nil {
+ continue
+ }
+ obj, err := factory.Create(cfg.Config, cluster, cfg.UpdateTag, "", 0)
+ if err != nil {
+ continue
+ }
+
+ if obj.BeforeMatch != nil && !reflect.ValueOf(obj.BeforeMatch).IsNil() {
+ ps = append(ps, plugin_executor.NewBeforeExecutor(cfg, obj.BeforeMatch))
+ }
+ }
+ return ps
+}
+
+func genPlugins(cfgs []*config.PluginConfig, cluster string, strategyID string, apiID int) ([]plugin_executor.Executor, []plugin_executor.Executor, []plugin_executor.Executor) {
+ psBefor := make([]plugin_executor.Executor, 0, len(cfgs))
+ psAccess := make([]plugin_executor.Executor, 0, len(cfgs))
+ psProxy := make([]plugin_executor.Executor, 0, len(cfgs))
+
+ for _, cfg := range cfgs {
+
+ factory, e := plugin.LoadPlugin(cfg.Name)
+ if e != nil {
+ continue
+ }
+ obj, err := factory.Create(cfg.Config, cluster, cfg.UpdateTag, strategyID, apiID)
+ if err != nil {
+ continue
+ }
+
+ if obj.BeforeMatch != nil && !reflect.ValueOf(obj.BeforeMatch).IsNil() {
+ psBefor = append(psBefor, plugin_executor.NewBeforeExecutor(cfg, obj.BeforeMatch))
+ }
+ if obj.Access != nil && !reflect.ValueOf(obj.Access).IsNil() {
+ psAccess = append(psAccess, plugin_executor.NewAccessExecutor(cfg, obj.Access))
+ }
+ if obj.Proxy != nil && !reflect.ValueOf(obj.Proxy).IsNil() {
+ psProxy = append(psProxy, plugin_executor.NewProxyExecutor(cfg, obj.Proxy))
+ }
+ }
+ return psBefor, psAccess, psProxy
+
+}
diff --git a/node/gateway/response/decode.go b/node/gateway/response/decode.go
new file mode 100644
index 0000000000000000000000000000000000000000..b96844fd4e452f58e8662de24c62f22316ccb37d
--- /dev/null
+++ b/node/gateway/response/decode.go
@@ -0,0 +1,28 @@
+package response
+
+import (
+ "encoding/json"
+ "strings"
+)
+const(
+ JSON ="json"
+ XML = "xml"
+ String = "string"
+)
+var (
+ jsonDecoder = func(data []byte, v interface{}) error {
+ err:=json.Unmarshal(data,v)
+ return err
+ }
+
+)
+func GetDecoder(decoder string) DecodeHandle {
+
+ switch strings.ToLower(decoder) {
+ case JSON:
+ return jsonDecoder
+ }
+
+ return nil
+}
+
diff --git a/node/gateway/response/decoder.go b/node/gateway/response/decoder.go
new file mode 100644
index 0000000000000000000000000000000000000000..f4e1ef4de881c00c882fb5a8d63baa7806d8ec8d
--- /dev/null
+++ b/node/gateway/response/decoder.go
@@ -0,0 +1,31 @@
+package response
+
+import "errors"
+
+var (
+ ErrorInvalidDecoder = errors.New("invalid decoder")
+)
+type DecodeHandle func(data []byte, v interface{}) error
+
+type EncodeHandle func (v interface{},org []byte)([]byte,error)
+type Encoder interface {
+ Encode(v interface{},org []byte)([]byte,error)
+ ContentType()string
+}
+
+func Decode(data []byte,handle DecodeHandle) (*Response,error) {
+
+ if handle == nil{
+ return nil,ErrorInvalidDecoder
+ }
+
+ var v interface{}
+ err:=handle(data,&v)
+ if err!=nil{
+ return nil,err
+ }
+ return &Response{
+ Data: v,
+ },nil
+
+}
diff --git a/node/gateway/response/encode.go b/node/gateway/response/encode.go
new file mode 100644
index 0000000000000000000000000000000000000000..b452fadf2fda8e37dbd76a2b65becea62a2b8101
--- /dev/null
+++ b/node/gateway/response/encode.go
@@ -0,0 +1,63 @@
+package response
+
+import (
+ "encoding/json"
+ "encoding/xml"
+
+ "strings"
+)
+
+var (
+
+ jsonEncoder =& EncoderH{
+ contentType:"application/json",
+ handleFunc:func(v interface{},org []byte)([]byte,error){
+ return json.Marshal(v)
+ },
+ }
+ xmlEncoder =&EncoderH{
+ contentType:"text/xml; charset=utf-8",
+ handleFunc:func(v interface{},org []byte) ([]byte,error){
+ return xml.Marshal(v)
+ },
+ }
+ stringEncoder =&EncoderH{
+ contentType:"text/plain",
+ handleFunc: func(v interface{},org []byte)([]byte,error) {
+
+ return org,nil
+ },
+ }
+ notEncoder = &EncoderH{
+ contentType: "",
+ handleFunc: func(v interface{}, org []byte) (bytes []byte, e error) {
+ return org,nil
+ },
+ }
+)
+
+type EncoderH struct {
+ contentType string
+ handleFunc EncodeHandle
+}
+
+func (e *EncoderH) Encode(v interface{},org []byte) ([]byte, error) {
+ return e.handleFunc(v,org)
+}
+
+func (e *EncoderH) ContentType() string {
+ return e.contentType
+}
+
+func GetEncoder(encoder string) Encoder {
+
+ switch strings.ToLower(encoder) {
+ case JSON:
+ return jsonEncoder
+ case XML:
+ return xmlEncoder
+ case String:
+ return stringEncoder
+ }
+ return notEncoder
+}
\ No newline at end of file
diff --git a/node/gateway/response/node.go b/node/gateway/response/node.go
new file mode 100644
index 0000000000000000000000000000000000000000..1b412345ed9b4d1ce8917e9cffa2cc1efee06b1a
--- /dev/null
+++ b/node/gateway/response/node.go
@@ -0,0 +1,213 @@
+package response
+
+import (
+ "strconv"
+ "strings"
+)
+
+type _Node struct {
+ data interface{}
+ parent *_Node
+ index int
+ key string
+}
+
+func (node *_Node)Set(v interface{}) {
+ if node.parent == nil{
+ return
+ }
+}
+
+
+
+func (node*_Node)child(key string,callback func(*_Node))bool {
+
+ return false
+}
+func (node *_Node)get(key string)*_Node{
+
+ if key == ""{
+ return nil
+ }
+
+ if key == "*"{
+ return node
+ }
+ switch node.data.(type) {
+ case []interface{}:
+ {
+
+ sl:=node.data.([]interface{})
+ if i,e:= strconv.Atoi(key);e==nil{
+ if i< len(sl){
+ n:=&_Node{
+ data:sl[i],
+ parent:node,
+ index:i,
+ }
+ return n
+ }
+
+ }
+ }
+ case map[string]interface{}:
+ {
+ sm :=node.data.(map[string]interface{})
+ if v,has:=sm[key];has{
+ n:=&_Node{
+ data: v,
+ parent: node,
+ key: key,
+ }
+
+ return n
+ }
+ }
+ }
+
+ return nil
+
+}
+func (node*_Node)Make(path []string) {
+
+ if node.data == nil{
+ node.data = make(map[string]interface{})
+ }
+ makePath(node.data,path)
+
+}
+func makePath(data interface{},path[]string) {
+ if len(path) == 0{
+ return
+ }
+ k:=path[0]
+ next:=path[1:]
+ switch data.(type){
+ case []interface{}:
+ dl:=data.([]interface{})
+ if k == "*" {
+ for _,d:=range dl{
+ makePath(d,next)
+ }
+ }else if i,err:=strconv.Atoi(k);err!=nil{
+ if i0 ; key = spiltKey(key){
+
+ next:=next(pattern,key)
+ if key == "*" {
+ data:= node.data
+ switch data.(type) {
+ case []interface{}:
+ {
+ sl := data.([]interface{})
+
+
+ for i, s := range sl {
+ n := &_Node{
+ data: s,
+ parent: node,
+ index: i,
+ }
+ match, isBreak := n.Pattern(next, callback)
+ if isBreak {
+ return true,true
+ }
+ isMatch = isMatch || match
+ }
+ }
+ case map[string]interface{}:
+ {
+ sm :=data.(map[string]interface{})
+
+ if len(sm) > 0{
+ for k,s:=range sm {
+ n := &_Node{
+ data: s,
+ parent: node,
+ key: k,
+ }
+ match, isBreak := n.Pattern(next, callback)
+ if isBreak {
+ return true, true
+ }
+ isMatch = isMatch || match
+ }
+ }else{
+ n := &_Node{
+ data: nil,
+ parent: node,
+ key: "",
+ }
+ match, isBreak := n.Pattern(next, callback)
+ if isBreak {
+ return true, true
+ }
+ isMatch = isMatch || match
+ }
+
+ }
+ }
+
+ }else{
+
+ child:= node.get(key)
+ if child != nil {
+ match, isBreak :=child.Pattern(next,callback)
+ if isBreak {
+ return true, true
+ }
+ isMatch = match
+ }
+ }
+ if isMatch{
+ return true,false
+ }
+ }
+ return false,false
+}
+
+func next(pattern ,key string) string{
+
+ l:=len(key)
+
+ if len(pattern)>l{
+ return pattern[l+1:]
+ }
+ return ""
+}
+func spiltKey(key string) string {
+ if index:=strings.LastIndex(key,".");index!= -1{
+ return key[:index]
+ }
+ return ""
+}
\ No newline at end of file
diff --git a/node/gateway/response/response.go b/node/gateway/response/response.go
new file mode 100644
index 0000000000000000000000000000000000000000..3bb3929557b353594684ef78758ae4b67a4dbbc7
--- /dev/null
+++ b/node/gateway/response/response.go
@@ -0,0 +1,182 @@
+package response
+
+import "strings"
+
+//Response response
+type Response struct {
+ // root 数据
+ Data interface{}
+}
+
+func (r *Response) Delete(pattern string) *Response {
+ if pattern == ""{
+ return r
+ }
+ root:=_Node{
+ data:r.Data,
+ }
+
+ root.Pattern(pattern, func(node *_Node)bool {
+ if node.parent ==nil {
+ return false
+ }
+ parent:= node.parent
+ switch parent.data.(type) {
+ case []interface{}:
+ index:= node.index
+ sl:= parent.data.([]interface{})
+
+ nl:=sl[:index]
+ sl=append(nl,sl[index+1])
+ parent.data = sl
+
+ case map[string]interface{}:
+ mp:=parent.data.(map[string]interface{})
+ delete(mp,node.key)
+ }
+ return false
+ })
+ return r
+}
+//SetValue 设置目标值,如果目标不存在,会对路径进行创建
+func (r *Response) SetValue(pattern string,value interface{}) {
+ if pattern == ""{
+ r.Data = value
+ return
+ }
+ root:=_Node{
+ data:r.Data,
+ }
+ root.Make(strings.Split(pattern,"."))
+
+ root.Pattern(pattern, func(node *_Node)bool {
+
+ if node.parent ==nil {
+ return false
+ }
+ parent:= node.parent
+ switch parent.data.(type) {
+ case []interface{}:
+ sl:= parent.data.([]interface{})
+ index:= node.index
+ sl[index] = value
+ parent.data = sl
+
+ case map[string]interface{}:
+ mp:=parent.data.(map[string]interface{})
+ mp[node.key]=value
+ }
+ return false
+ })
+
+}
+
+//ReTarget 选择目标重新设置为root
+func (r *Response) ReTarget(pattern string) {
+ if pattern == ""{
+ return
+ }
+ root:=_Node{
+ data:r.Data,
+ }
+
+ match, _ := root.Pattern(pattern, func(node *_Node) bool {
+ r.Data = node.data
+
+ return true
+ })
+ if !match{
+ r.Data = make(map[string]interface{})
+ }
+ return
+}
+//Group
+func (r *Response) Group(path []string) {
+ l:=len(path)
+ if l==0{
+ return
+ }
+ root := make(map[string]interface{})
+ node:=root
+
+ lastKey := path[l-1]
+ if l>1{
+ for _,key:=range path[:l-1]{
+ v := make(map[string]interface{})
+ node[key]=v
+ node = v
+ }
+ }
+
+ node[lastKey] = r.Data
+ r.Data = root
+}
+//ReName 重命名
+func (r *Response)ReName(pattern string,newName string) {
+ if pattern == ""{
+ return
+ }
+ root:=_Node{
+ data:r.Data,
+ }
+
+ root.Pattern(pattern, func(node *_Node) bool {
+ if node.parent ==nil {
+ return false
+ }
+ parent:= node.parent
+ switch parent.data.(type) {
+ case []interface{}:
+ return false
+
+ case map[string]interface{}:
+ mp:=parent.data.(map[string]interface{})
+ delete(mp,node.key)
+ mp[newName]=node.data
+ return false
+ }
+ return false
+ })
+}
+
+func (r *Response)Move(source ,target string) {
+
+ if strings.Index(source,"*") != -1{
+ return
+ }
+ if strings.Index(target,"*") != -1{
+ return
+ }
+ root:=_Node{
+ data:r.Data,
+ }
+ var oldValues *_Node
+ match,_:=root.Pattern(source, func(node *_Node) bool {
+ oldValues = node
+
+ if node.parent ==nil {
+ return false
+ }
+ parent:= node.parent
+ switch parent.data.(type) {
+ case []interface{}:
+ index:= node.index
+ sl:= parent.data.([]interface{})
+
+ nl:=sl[:index]
+ sl=append(nl,sl[index+1])
+ parent.data = sl
+
+ case map[string]interface{}:
+ mp:=parent.data.(map[string]interface{})
+ delete(mp,node.key)
+ }
+ return false
+ })
+ if match{
+ r.SetValue(target,oldValues.data)
+ }else{
+ r.SetValue(target,nil)
+ }
+
+}
\ No newline at end of file
diff --git a/node/gateway/router.go b/node/gateway/router.go
new file mode 100644
index 0000000000000000000000000000000000000000..146f8358a95a2d2d44902e87c28053061865eb94
--- /dev/null
+++ b/node/gateway/router.go
@@ -0,0 +1,193 @@
+package gateway
+
+import (
+ "errors"
+ "net/http"
+ "reflect"
+ "strings"
+
+ "github.com/eolinker/goku-api-gateway/config"
+ "github.com/eolinker/goku-api-gateway/goku-service/balance"
+ "github.com/eolinker/goku-api-gateway/goku-service/discovery"
+ "github.com/eolinker/goku-api-gateway/node/gateway/application"
+ plugin_executor "github.com/eolinker/goku-api-gateway/node/gateway/plugin-executor"
+ plugin_loader "github.com/eolinker/goku-api-gateway/node/plugin-loader"
+ "github.com/eolinker/goku-api-gateway/node/router"
+)
+
+var (
+ errorConfig = errors.New("config is error")
+)
+
+//Parse 解析
+func Parse(config *config.GokuConfig, factory router.Factory) (http.Handler, error) {
+
+ if config == nil {
+ return nil, errorConfig
+ }
+
+ f := genFactory(config, factory)
+
+ return &HTTPHandler{router: f.create()}, nil
+}
+
+type _RootFactory struct {
+ orgCfg *config.GokuConfig
+ beforePlugin []plugin_executor.Executor
+ gBefores []plugin_executor.Executor
+ gAccesses []plugin_executor.Executor
+ gProxies []plugin_executor.Executor
+ apis map[int]*config.APIContent
+ appFactory *application.Factory
+ routerFactory router.Factory
+ cluster string
+
+ authPlugin map[string]string
+}
+
+func (f *_RootFactory) create() *Before {
+ beforeRouter := &Before{
+ pluginBefor: f.beforePlugin,
+ pluginGlobalBefor: f.gBefores,
+ strategies: f.createStrategy(),
+ anonymousStrategy: f.orgCfg.AnonymousStrategyID,
+ }
+
+ return beforeRouter
+}
+func (f *_RootFactory) createStrategy() map[string]*Strategy {
+ strategys := make(map[string]*Strategy)
+
+ for _, cfg := range f.orgCfg.Strategy {
+
+ strategyRouter := f.genStrategy(cfg)
+ strategys[cfg.ID] = strategyRouter
+ }
+
+ return strategys
+}
+
+// 构造策略
+func (f *_RootFactory) genStrategy(cfg *config.StrategyConfig) *Strategy {
+ _, accesses, _ := genPlugins(cfg.Plugins, f.cluster, cfg.ID, 0)
+
+ s := &Strategy{
+ ID: cfg.ID,
+ Name: cfg.Name,
+ Enable: cfg.Enable,
+
+ accessPlugin: accesses,
+ globalAccessPlugin: f.gAccesses,
+ authPlugin: make(map[string]plugin_executor.Executor),
+ isNeedAuth: false,
+ }
+ if !s.Enable {
+ return s
+ }
+ s.apiRouter = f.routerFactory.New()
+ s.apiRouter.AddNotFound(s.HandlerAPINotFound)
+ for authKey, authCfg := range cfg.AUTH {
+ s.isNeedAuth = true
+ pluginName, has := f.authPlugin[authKey]
+ if has {
+ pluginFactory, e := plugin_loader.LoadPlugin(pluginName)
+ if e != nil {
+ continue
+ }
+ pluginObj, err := pluginFactory.Create(authCfg, f.cluster, "", s.ID, 0)
+ if err != nil {
+ continue
+ }
+
+ if pluginObj.Access != nil && !reflect.ValueOf(pluginObj.Access).IsNil() {
+ s.authPlugin[authKey] = plugin_executor.NewAccessExecutor(&config.PluginConfig{
+ Name: pluginName,
+ IsStop: true,
+ Config: authCfg,
+ }, pluginObj.Access)
+ }
+ }
+ }
+
+ factory := newAPIFactory(f, s.ID)
+
+ for _, apiCfg := range cfg.APIS {
+
+ iRouter, apiContent := factory.genAPIRouter(apiCfg)
+ if iRouter == nil {
+ continue
+ }
+ for _, method := range apiContent.Methods {
+
+ s.apiRouter.AddRouter(strings.ToUpper(method), apiContent.RequestURL, iRouter)
+ }
+ }
+
+ return s
+}
+
+type _ApiFactory struct {
+ root *_RootFactory
+ strategyID string
+}
+
+func newAPIFactory(root *_RootFactory, strategyID string) *_ApiFactory {
+ return &_ApiFactory{
+ root: root,
+ strategyID: strategyID,
+ }
+}
+func (f *_ApiFactory) genAPIRouter(cfg *config.APIOfStrategy) (router.IRouter, *config.APIContent) {
+
+ apiContend, has := f.root.apis[cfg.ID]
+ if !has {
+ return nil, nil
+ }
+
+ app, err := f.root.appFactory.GenApplication(cfg)
+ if err != nil {
+ return nil, nil
+ }
+ _, pluginAccesses, pluginProxies := genPlugins(cfg.Plugins, f.root.cluster, f.strategyID, cfg.ID)
+
+ return &API{
+ strategyID: f.strategyID,
+ app: app,
+ pluginAccess: pluginAccesses,
+ pluginProxies: pluginProxies,
+ pluginAccessGlobal: f.root.gAccesses,
+ pluginProxiesGlobal: f.root.gProxies,
+ }, apiContend
+}
+
+func genFactory(cfg *config.GokuConfig, factory router.Factory) *_RootFactory {
+
+ discovery.ResetAllServiceConfig(cfg.DiscoverConfig)
+ balance.ResetBalances(cfg.Balance)
+
+ beforePlugin := genBeforPlugin(cfg.Plugins.BeforePlugins, cfg.Cluster)
+
+ gBefores, gAccesses, gProxies := genPlugins(cfg.Plugins.GlobalPlugins, cfg.Cluster, "", 0)
+
+ apis := toMap(cfg.APIS)
+ return &_RootFactory{
+ beforePlugin: beforePlugin,
+ gBefores: gBefores,
+ gAccesses: gAccesses,
+ gProxies: gProxies,
+ appFactory: application.NewFactory(apis),
+ apis: apis,
+ routerFactory: factory,
+ cluster: cfg.Cluster,
+ orgCfg: cfg,
+ authPlugin: cfg.AuthPlugin,
+ }
+}
+
+func toMap(cfgs []*config.APIContent) map[int]*config.APIContent {
+ m := make(map[int]*config.APIContent)
+ for _, cfg := range cfgs {
+ m[cfg.ID] = cfg
+ }
+ return m
+}
diff --git a/node/gateway/strategy.go b/node/gateway/strategy.go
new file mode 100644
index 0000000000000000000000000000000000000000..a08a23e80b19585f1de4b57b4c96015d16cefe54
--- /dev/null
+++ b/node/gateway/strategy.go
@@ -0,0 +1,113 @@
+package gateway
+
+import (
+ "fmt"
+ "net/http"
+
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+ plugin_executor "github.com/eolinker/goku-api-gateway/node/gateway/plugin-executor"
+ "github.com/eolinker/goku-api-gateway/node/router"
+ access_field "github.com/eolinker/goku-api-gateway/server/access-field"
+)
+
+//Strategy strategy
+type Strategy struct {
+ ID string
+ Name string
+ Enable bool
+
+ apiRouter router.APIRouter
+
+ accessPlugin []plugin_executor.Executor
+ globalAccessPlugin []plugin_executor.Executor
+
+ authPlugin map[string]plugin_executor.Executor
+
+ isNeedAuth bool
+}
+
+//Router router
+func (r *Strategy) Router(w http.ResponseWriter, req *http.Request, ctx *common.Context) {
+ if !r.Enable {
+
+ go log.Info("[ERROR]StrategyID is out of service!")
+
+ ctx.SetStatus(500, "500")
+
+ ctx.SetBody([]byte("[ERROR]StrategyID is out of service!"))
+ return
+ }
+
+ ctx.SetStrategyName(r.Name)
+ ctx.SetStrategyId(r.ID)
+ ctx.LogFields[access_field.Strategy] = fmt.Sprintf("\"%s %s\"", r.ID, r.Name)
+
+ if r.isNeedAuth {
+ // 需要校验
+ if !r.auth(ctx) {
+ // 校验失败
+ ctx.SetStatus(403, "403")
+ ctx.SetBody([]byte("[ERROR]Illegal authorization type!"))
+ return
+ }
+ }
+
+ r.apiRouter.ServeHTTP(w, req, ctx)
+}
+
+func (r *Strategy) auth(ctx *common.Context) bool {
+ requestID := ctx.RequestId()
+ authType := ctx.Request().GetHeader("Authorization-Type")
+ authPlugin, has := r.authPlugin[authType]
+ if !has {
+ log.Warn(requestID, " Illegal authorization type:", authType)
+ return false
+ }
+
+ isContinue, err := authPlugin.Execute(ctx)
+ if isContinue == false {
+ pluginName := authNames[authType]
+ // 校验失败
+ if err != nil {
+ log.Warn(requestID, " access auth:[", pluginName, "] error:", err)
+ }
+ log.Info(requestID, " auth [", pluginName, "] refuse")
+
+ return false
+ }
+ log.Debug(requestID, " auth [", authType, "] pass")
+ return true
+}
+func (r *Strategy) accessFlow(ctx *common.Context) {
+ for _, handler := range r.accessPlugin {
+
+ flag, _ := handler.Execute(ctx)
+
+ if flag == false && handler.IsStop() {
+
+ return
+ }
+ }
+}
+
+func (r *Strategy) accessGlobalFlow(ctx *common.Context) {
+ // 全局插件不中断
+ for _, handler := range r.globalAccessPlugin {
+ _, _ = handler.Execute(ctx)
+
+ }
+}
+
+//HandlerAPINotFound 当接口不存在时调用
+func (r *Strategy) HandlerAPINotFound(ctx *common.Context) {
+ // 未匹配到api
+ // 执行策略access 插件
+ r.accessFlow(ctx)
+ // 执行全局access 插件
+ r.accessGlobalFlow(ctx)
+
+ log.Info(ctx.RequestId(), " URL dose not exist!")
+ ctx.SetStatus(404, "404")
+ ctx.SetBody([]byte("[ERROR]URL dose not exist!"))
+}
diff --git a/node/plugin-loader/errorCode.go b/node/plugin-loader/errorCode.go
new file mode 100644
index 0000000000000000000000000000000000000000..8d7e66c27f25f8136966006fe54cd3502b8472e2
--- /dev/null
+++ b/node/plugin-loader/errorCode.go
@@ -0,0 +1,12 @@
+package plugin_loader
+
+const (
+ //LoadOk ok
+ LoadOk = iota
+ //LoadFileError fileError
+ LoadFileError
+ //LoadLookupError lookUpError
+ LoadLookupError
+ //LoadInterFaceError interfaceError
+ LoadInterFaceError
+)
diff --git a/goku-node/manager/plugin-manager/pluginload.go b/node/plugin-loader/pluginload.go
similarity index 58%
rename from goku-node/manager/plugin-manager/pluginload.go
rename to node/plugin-loader/pluginload.go
index 7f43f6c8adaa7b6d990dfb6c6dd8b896fdad2337..27c63cc39f92c587e9d764e4d793a4c1accd1ba4 100644
--- a/goku-node/manager/plugin-manager/pluginload.go
+++ b/node/plugin-loader/pluginload.go
@@ -1,4 +1,4 @@
-package pluginmanager
+package plugin_loader
import (
"fmt"
@@ -7,10 +7,7 @@ import (
"reflect"
"sync"
- node_common "github.com/eolinker/goku-api-gateway/goku-node/node-common"
goku_plugin "github.com/eolinker/goku-plugin"
-
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
)
var (
@@ -36,7 +33,7 @@ func (m *_GlodPluginManager) check(name string) (int, error) {
return code, err
}
- _, errorCode, e := m.loadPlugin(name)
+ _, e, errorCode := m.loadPlugin(name)
return errorCode, e
}
@@ -59,64 +56,25 @@ func (m *_GlodPluginManager) getPluginHandle(name string) (goku_plugin.PluginFac
return p, has
}
-//LoadPlugin 获取所有插件列表
-func LoadPlugin(pis map[string]*entity.PluginInfo) (allFactory map[string]*entity.PluginFactoryHandler, defaultPlugins []*entity.PluginHandlerExce, beforMatchs []*entity.PluginHandlerExce) {
- plugins := make(map[string]*entity.PluginFactoryHandler)
- def := make([]*entity.PluginHandlerExce, 0, len(pis))
- before := make([]*entity.PluginHandlerExce, 0, len(pis))
-
- for key, value := range pis {
- handle, _, err := globalPluginManager.loadPlugin(key)
- if err != nil {
- goku_plugin.Warn("LoadPlugin:", err.Error())
- continue
- }
- factory := &entity.PluginFactoryHandler{
- Factory: handle,
- Info: value,
- }
- plugins[key] = factory
-
- pobj, err := factory.Factory.Create(value.Config, node_common.ClusterName(), value.UpdateTag, "", 0)
- if err != nil {
- continue
- }
- if value.Type == entity.PluginTypeGateway {
-
- def = append(def, &entity.PluginHandlerExce{
- PluginObj: pobj,
- Priority: value.Priority,
- Name: value.Name,
- IsStop: value.IsStop,
- })
- } else {
- if pobj.BeforeMatch == nil || reflect.ValueOf(pobj.BeforeMatch).IsNil() {
- continue
- }
- before = append(before, &entity.PluginHandlerExce{
- PluginObj: pobj,
- Priority: value.Priority,
- Name: value.Name,
- IsStop: value.IsStop,
- })
- }
+func LoadPlugin(name string)(goku_plugin.PluginFactory ,error) {
+ factory, err, _ := globalPluginManager.loadPlugin(name)
+
+ return factory,err
- }
- return plugins, def, before
}
-//loadPlugin 加载动态库
-func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory, int, error) {
+// 加载动态库
+func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory, error, int) {
handle, has := m.getPluginHandle(name)
if has {
- return handle, 0, nil
+ return handle, nil, LoadOk
}
m.gloadPluginLocker.Lock()
defer m.gloadPluginLocker.Unlock()
handle, has = m.gloadPlugin[name]
if has {
- return handle, LoadOk, nil
+ return handle, nil, LoadOk
}
path, _ := filepath.Abs(fmt.Sprintf("plugin/%s.so", name))
@@ -125,7 +83,7 @@ func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory,
e := fmt.Errorf("The plugin file named '%s.so' can not be found in plugin:%s ", name, err.Error())
m.errors[name] = e
m.errorCodes[name] = LoadFileError
- return nil, LoadFileError, e
+ return nil, e, LoadFileError
}
//structName := strings.Replace(name, "-", "_", -1)
@@ -139,7 +97,7 @@ func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory,
m.errors[name] = e
m.errorCodes[name] = LoadLookupError
- return nil, LoadLookupError, e
+ return nil, e, LoadLookupError
}
vp, ok := v.(func() goku_plugin.PluginFactory)
@@ -147,18 +105,18 @@ func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory,
e := fmt.Errorf("The builder func can not implemented interface named goku_plugin.PluginFactory:%s ", name)
m.errors[name] = e
m.errorCodes[name] = LoadInterFaceError
- return nil, LoadInterFaceError, e
+ return nil, e, LoadInterFaceError
}
factory := vp()
if factory == nil || reflect.ValueOf(factory).IsNil() {
e := fmt.Errorf("The builder result is nil:%s ", name)
m.errors[name] = e
m.errorCodes[name] = LoadInterFaceError
- return nil, LoadInterFaceError, e
+ return nil, e, LoadInterFaceError
}
m.gloadPlugin[name] = factory
m.errorCodes[name] = LoadOk
m.errors[name] = nil
- return factory, LoadOk, nil
+ return factory, nil, LoadOk
}
diff --git a/node/router/httprouter/context.go b/node/router/httprouter/context.go
new file mode 100644
index 0000000000000000000000000000000000000000..05f7182c4d73babcc3da23be8988761dcd432157
--- /dev/null
+++ b/node/router/httprouter/context.go
@@ -0,0 +1,33 @@
+package httprouter
+
+import (
+ "context"
+ "net/http"
+
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+)
+
+type contextKey struct {
+}
+
+//ContextKey contextKey
+var ContextKey = contextKey{}
+
+//ContextFromRequest ParamsFromContext pulls the URL parameters from a request context,
+// or returns nil if none are present.
+//
+// This is only present from go 1.7.
+func ContextFromRequest(req *http.Request) *common.Context {
+ ctx := req.Context()
+ p, _ := ctx.Value(ContextKey).(*common.Context)
+
+ return p
+}
+
+//SetContextToRequest setContextToRequest
+func SetContextToRequest(req *http.Request, ctx *common.Context) *http.Request {
+ rctx := req.Context()
+ rctx = context.WithValue(rctx, ContextKey, ctx)
+ req = req.WithContext(rctx)
+ return req
+}
diff --git a/node/router/httprouter/router.go b/node/router/httprouter/router.go
new file mode 100644
index 0000000000000000000000000000000000000000..df3cf7fc6a9f652ec5d47cfb02b5e3763dfa814b
--- /dev/null
+++ b/node/router/httprouter/router.go
@@ -0,0 +1,68 @@
+package httprouter
+
+import (
+ "net/http"
+
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+ "github.com/eolinker/goku-api-gateway/node/router"
+ "github.com/julienschmidt/httprouter"
+)
+
+//HTTPRouter httpRouter
+type HTTPRouter struct {
+}
+
+//Factory factory
+func Factory() router.Factory {
+ return &HTTPRouter{}
+}
+
+//New new
+func (*HTTPRouter) New() router.APIRouter {
+ return new(Engine)
+}
+
+//Engine engine
+type Engine struct {
+ router httprouter.Router
+}
+
+//AddRouter addRouter
+func (r *Engine) AddRouter(method, path string, router router.IRouter) {
+ r.router.Handle(method, path,
+ func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
+ ctx := ContextFromRequest(req)
+ ctx.RestfulParam = make(map[string]string)
+ for _, param := range params {
+
+ ctx.RestfulParam[param.Key] = param.Value
+ }
+ router.Router(ctx)
+ })
+}
+
+//HandleFunc handleFunc
+func (r *Engine) HandleFunc(method, path string, handler router.HandleFunc) {
+ r.router.Handle(method, path, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
+ ctx := ContextFromRequest(req)
+ handler(ctx)
+ })
+
+}
+
+func (r *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request, ctx *common.Context) {
+
+ req = SetContextToRequest(req, ctx)
+
+ r.router.ServeHTTP(w, req)
+}
+
+//AddNotFound addNotFound
+func (r *Engine) AddNotFound(handler router.HandleFunc) {
+
+ r.router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+ ctx := ContextFromRequest(req)
+ handler(ctx)
+ })
+
+}
diff --git a/node/router/router.go b/node/router/router.go
new file mode 100644
index 0000000000000000000000000000000000000000..609502efed51b9380ee311a2cf456e7e94b40e5f
--- /dev/null
+++ b/node/router/router.go
@@ -0,0 +1,33 @@
+package router
+
+import (
+ "net/http"
+
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
+)
+
+//IRouter iRouter
+type IRouter interface {
+ Router(ctx *common.Context)
+}
+
+//HandleFunc handlefunc
+type HandleFunc func(ctx *common.Context)
+
+//Router router
+func (handlerFunc HandleFunc) Router(ctx *common.Context) {
+ handlerFunc(ctx)
+}
+
+//APIRouter apiRouter
+type APIRouter interface {
+ AddRouter(method, path string, router IRouter)
+ HandleFunc(method, path string, handler HandleFunc)
+ AddNotFound(handle HandleFunc)
+ ServeHTTP(w http.ResponseWriter, req *http.Request, ctx *common.Context)
+}
+
+//Factory factory
+type Factory interface {
+ New() APIRouter
+}
diff --git a/goku-node/manager/config-manager/log.go b/node/server/log.go
similarity index 51%
rename from goku-node/manager/config-manager/log.go
rename to node/server/log.go
index 58e5f666c0f4775001344516c19b42b791bb1ce6..4dd7686f7fb24add976589fd0e17d9568bc9d190 100644
--- a/goku-node/manager/config-manager/log.go
+++ b/node/server/log.go
@@ -1,96 +1,50 @@
-package configmanager
+package server
import (
- "encoding/json"
+ "github.com/eolinker/goku-api-gateway/config"
log "github.com/eolinker/goku-api-gateway/goku-log"
access_log "github.com/eolinker/goku-api-gateway/goku-node/access-log"
- "github.com/eolinker/goku-api-gateway/goku-node/manager/updater"
access_field "github.com/eolinker/goku-api-gateway/server/access-field"
- dao "github.com/eolinker/goku-api-gateway/server/dao/config-log"
- entity "github.com/eolinker/goku-api-gateway/server/entity/config-log"
)
-const (
- //AccessLog access日志
- AccessLog = "access"
- //NodeLog 节点日志
- NodeLog = "node"
-)
+//SetLog setLog
+func SetLog(c *config.LogConfig) {
-func init() {
- updater.Add(reloadLogConfig, 1, "goku_config_log")
-}
-func defaultAccessLogConfig() *entity.LogConfig {
- return &entity.LogConfig{
- Name: AccessLog,
- Enable: 1,
- Dir: "work/logs/",
- File: "access.log",
+ if c == nil {
- Period: "hour",
- Fields: "",
- }
-}
-func defaultNodeAppLogConfig() *entity.LogConfig {
- return &entity.LogConfig{
- Name: AccessLog,
- Enable: 1,
- Dir: "work/logs/",
- File: "node.log",
- Level: "error",
- Period: "hour",
- }
-}
-
-//InitLog 初始化日志
-func InitLog() {
- reloadLogConfig()
-}
-func reloadLogConfig() {
- reloadAppLog()
- reloadAccessLog()
-
-}
-func reloadAppLog() {
- c, e := dao.Get(NodeLog)
- if e != nil {
- log.Warn("manager/config load goku_config_log fro node error:", e)
c = defaultNodeAppLogConfig()
}
+
period, err := log.ParsePeriod(c.Period)
if err != nil {
period = log.PeriodDay
- log.Warn("manager/config unmarshal access log period failed for nod , use the default config:%s", e)
+ log.Warn("manager/config unmarshal access log period failed for nod , use the default config:%s", err)
}
level, err := log.ParseLevel(c.Level)
if err != nil {
level = log.WarnLevel
- log.Warn("manager/config unmarshal access log level failed for nod , use the default config:%s", e)
+ log.Warn("manager/config unmarshal access log level failed for nod , use the default config:%s", err)
}
enable := c.Enable == 1
log.SetOutPut(enable, c.Dir, c.File, period, c.Expire)
log.SetLevel(level)
-
}
-func reloadAccessLog() {
- c, e := dao.Get(AccessLog)
- if e != nil {
- log.Warn("manager/config load goku_config_log for access log error:", e)
+
+//SetAccessLog setAccessLog
+func SetAccessLog(c *config.AccessLogConfig) {
+ if c == nil {
c = defaultAccessLogConfig()
}
-
period, err := log.ParsePeriod(c.Period)
if err != nil {
period = log.PeriodDay
- log.Warn("manager/config unmarshal period failed for , use the default config:%s", e)
+ log.Warn("manager/config unmarshal period failed for , use the default config:%s", err)
}
enable := c.Enable == 1
- fieldsConfig := make([]AccessField, 0, access_field.Size())
- err = json.Unmarshal([]byte(c.Fields), &fieldsConfig)
-
+ fieldsConfig := c.Fields
if err != nil || len(fieldsConfig) == 0 {
log.Warn("manager/config unmarshal access log fields error:", err)
@@ -98,15 +52,32 @@ func reloadAccessLog() {
} else {
fields := make([]access_field.AccessFieldKey, 0, access_field.Size())
for _, f := range fieldsConfig {
- if f.Select {
- if access_field.Has(f.Name) {
- fields = append(fields, access_field.Parse(f.Name))
- }
- }
+ fields = append(fields, access_field.Parse(f))
}
access_log.SetFields(fields)
}
access_log.SetOutput(enable, c.Dir, c.File, period, c.Expire)
+}
+func defaultAccessLogConfig() *config.AccessLogConfig {
+ return &config.AccessLogConfig{
+ Name: "access",
+ Enable: 1,
+ Dir: "work/logs/",
+ File: "access.log",
+ Period: "hour",
+ Fields: nil,
+ }
+}
+
+func defaultNodeAppLogConfig() *config.LogConfig {
+ return &config.LogConfig{
+ Name: "node",
+ Enable: 1,
+ Dir: "work/logs/",
+ File: "node.log",
+ Level: "error",
+ Period: "hour",
+ }
}
diff --git a/node/server/server.go b/node/server/server.go
new file mode 100644
index 0000000000000000000000000000000000000000..3894b0f807b828daa9aa0a091b838dbb5dd4891f
--- /dev/null
+++ b/node/server/server.go
@@ -0,0 +1,99 @@
+package server
+
+import (
+ "errors"
+ "fmt"
+ "net/http"
+
+ "github.com/eolinker/goku-api-gateway/common/endless"
+ "github.com/eolinker/goku-api-gateway/config"
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+ "github.com/eolinker/goku-api-gateway/node/console"
+ "github.com/eolinker/goku-api-gateway/node/gateway"
+ "github.com/eolinker/goku-api-gateway/node/router/httprouter"
+)
+
+//Server server
+type Server struct {
+ port int
+ console *console.Console
+ router http.Handler
+}
+
+//NewServer newServer
+func NewServer(port int) *Server {
+ return &Server{
+ port: port,
+ console: nil,
+ router: nil,
+ }
+}
+
+//SetRouter setRouter
+func (s *Server) SetRouter(r http.Handler) error {
+ s.router = r
+ return nil
+}
+
+//SetConsole setConsole
+func (s *Server) SetConsole(c *console.Console) {
+
+ s.console = c
+ return
+}
+
+//Server server
+func (s *Server) Server() error {
+ if s.router == nil && s.console == nil {
+ return errors.New("can not start server widthout router and console")
+ }
+
+ if s.console != nil {
+
+ conf, err := s.console.GetConfig()
+ if err != nil {
+ return err
+ }
+ SetLog(conf.Log)
+ SetAccessLog(conf.AccessLog)
+
+ r, err := gateway.Parse(conf, httprouter.Factory())
+ if err != nil {
+ log.Panic("parse config error:", err)
+ }
+ e := s.SetRouter(r)
+ if e != nil {
+ return e
+ }
+
+ s.console.AddListen(s.FlushConfig)
+ }
+
+ return endless.ListenAndServe(fmt.Sprintf(":%d", s.port), s)
+}
+
+//FlushConfig flushConfig
+func (s *Server) FlushConfig(config *config.GokuConfig) {
+
+ go func() {
+ r, err := gateway.Parse(config, httprouter.Factory())
+ if err != nil {
+ log.Error("parse config error:", err)
+ return
+ }
+ s.SetRouter(r)
+
+ }()
+
+}
+
+func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+
+ if s.router == nil {
+ w.WriteHeader(404)
+ return
+ }
+
+ s.router.ServeHTTP(w, req)
+
+}
diff --git a/goku-node/utils.go b/node/utils/utils.go
similarity index 52%
rename from goku-node/utils.go
rename to node/utils/utils.go
index 4e6b1c1045ef8440697ac63df9d78301753d40d9..61b11d1a9cb808fd13c4c555a08e3e24a11de880 100644
--- a/goku-node/utils.go
+++ b/node/utils/utils.go
@@ -1,12 +1,14 @@
-package gokunode
+package utils
import (
"math/rand"
"strings"
"time"
+
+ "github.com/eolinker/goku-api-gateway/goku-node/common"
)
-// GetRandomString 生成随机字符串
+//GetRandomString 生成随机字符串
func GetRandomString(num int) string {
str := "123456789abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ"
bytes := []byte(str)
@@ -18,7 +20,7 @@ func GetRandomString(num int) string {
return string(result)
}
-//Intercept 过滤子字符串
+//Intercept 获取前缀
func Intercept(str, substr string) string {
result := strings.Index(str, substr)
var rs string
@@ -29,3 +31,18 @@ func Intercept(str, substr string) string {
}
return rs
}
+
+//GetStrateyID 获取策略ID
+func GetStrateyID(ctx *common.Context) string {
+ if value := ctx.Request().GetHeader("Strategy-Id"); value != "" {
+ return value
+ }
+ if value := ctx.Request().URL().Query().Get("Strategy-Id"); value != "" {
+ return value
+ }
+ if value := ctx.Request().GetForm("Strategy-Id"); value != "" {
+ return value
+ }
+
+ return ""
+}
diff --git a/server/access-field/def.go b/server/access-field/def.go
index 78b41e38bba8adc2f8ee3a812444ae07f7ebf984..82ca30cdba2a8e582816c94d0e3be368eeaf1392 100644
--- a/server/access-field/def.go
+++ b/server/access-field/def.go
@@ -1,54 +1,54 @@
-package accessfield
+package access_field
import "strings"
-//AccessFieldKey access日志域的键名
+//AccessFieldKey access域key
type AccessFieldKey string
const (
- //RemoteAddr remote_addr
- RemoteAddr = "$remote_addr"
- //HTTPXForwardedFor http_x_forwarded_for
+ //RemoteAddr 记录客户端IP地址
+ RemoteAddr = "$remote_addr"
+ //HTTPXForwardedFor HTTP请求端真实IP
HTTPXForwardedFor = "$http_x_forwarded_for"
- //Request request
- Request = "$request"
- //StatusCode status_code
- StatusCode = "$status_code"
- //BodyBytesSent body_bytes_sent
- BodyBytesSent = "$body_bytes_sent"
- //Msec msec
- Msec = "$msec"
- //HTTPReferer http_referer
- HTTPReferer = "$http_referer"
- //HTTPUserAgent http_user_agent
- HTTPUserAgent = "$http_user_agent"
- //RequestTime request_time
- RequestTime = "$request_time"
- //TimeIso8601 time_iso8601
- TimeIso8601 = "$time_iso8601"
- //TimeLocal time_local
- TimeLocal = "$time_local"
- //RequestID request_id
- RequestID = "$request_id"
- //FinallyServer finally_server
- FinallyServer = "$finally_server"
- //Balance balance
- Balance = "$balance"
- //Strategy strategy
- Strategy = "$strategy"
- //API api
- API = "$api"
- //Retry retry
- Retry = "$retry"
- //Proxy proxy
- Proxy = "$proxy"
- //ProxyStatusCode proxy_status_code
+ //Request 记录请求的方法、URL和协议(例如 POST /proxy HTTPS)
+ Request = "$request"
+ //StatusCode 状态码
+ StatusCode = "$status_code"
+ //BodyBytesSent 发送给客户端的字节数,不包括响应头的大小; 该变量与Apache模块mod_log_config里的“%B”参数兼容。
+ BodyBytesSent = "$body_bytes_sent"
+ //Msec 日志写入时间。单位为秒,精度是毫秒。
+ Msec = "$msec"
+ //HTTPReferer 记录从哪个页面链接访问过来的
+ HTTPReferer = "$http_referer"
+ //HTTPUserAgent 记录客户端浏览器相关信息
+ HTTPUserAgent = "$http_user_agent"
+ //RequestTime 请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
+ RequestTime = "$request_time"
+ //TimeIso8601 ISO8601标准格式下的本地时间。
+ TimeIso8601 = "$time_iso8601"
+ //TimeLocal 通用日志格式下的本地时间。
+ TimeLocal = "$time_local"
+ //RequestID 请求id
+ RequestID = "$request_id"
+ //FinallyServer 最后一次转发的主机信息(IP端口或域名端口)
+ FinallyServer = "$finally_server"
+ //Balance 负载信息
+ Balance = "$balance"
+ //Strategy 策略信息,包括策略名称和ID
+ Strategy = "$strategy"
+ //API API信息,包括 API名称和ID
+ API = "$api"
+ //Retry 重试信息
+ Retry = "$retry"
+ //Proxy 记录转发的方法、URL和协议(例如 POST /proxy HTTPS)
+ Proxy = "$proxy"
+ //ProxyStatusCode 转发状态码
ProxyStatusCode = "$proxy_status_code"
- //Host host
- Host = "$host"
+ //Host 主机信息
+ Host = "$host"
)
-//Info info
+//Info 获取域信息
func (k AccessFieldKey) Info() string {
key := strings.ToLower(string(k))
v, has := infos[key]
@@ -58,18 +58,18 @@ func (k AccessFieldKey) Info() string {
return "unknown"
}
-//Key key
+//Key 获取key
func (k AccessFieldKey) Key() string {
return strings.ToLower(string(k))
}
-//Parse parse
+//Parse 解析
func Parse(key string) AccessFieldKey {
return AccessFieldKey(strings.ToLower(key))
}
-//CopyKey copy key
+//CopyKey copy
func CopyKey() map[string]string {
v := make(map[string]string)
for key, value := range infos {
@@ -78,7 +78,7 @@ func CopyKey() map[string]string {
return v
}
-//Has 判断key是否存在
+//Has 判断是否存在域key
func Has(key string) bool {
_, has := infos[AccessFieldKey(key).Key()]
return has
diff --git a/server/access-field/info.go b/server/access-field/info.go
index 105afa4618d1632ea4ef7ce6d223d7470b725ea1..e4a125cc5132e30942d69adbc1f13bf2b70867d6 100644
--- a/server/access-field/info.go
+++ b/server/access-field/info.go
@@ -1,4 +1,4 @@
-package accessfield
+package access_field
var (
infos = map[string]string{
@@ -6,21 +6,21 @@ var (
HTTPXForwardedFor: "记录客户端IP地址(反向)",
Request: "记录请求的方法、URL和协议(例如 POST /proxy HTTPS)",
StatusCode: "记录请求状态",
- BodyBytesSent: "发送给客户端的字节数,不包括响应头的大小; 该变量与Apache模块mod_log_config里的“%B”参数兼容。",
- Msec: "日志写入时间。单位为秒,精度是毫秒。",
- HTTPReferer: "记录从哪个页面链接访问过来的",
- HTTPUserAgent: "记录客户端浏览器相关信息",
- RequestTime: "请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。",
- TimeIso8601: "ISO8601标准格式下的本地时间。",
- TimeLocal: "通用日志格式下的本地时间。",
- RequestID: "请求id",
- FinallyServer: "最后一次转发的主机信息(IP端口或域名端口)",
- Balance: "负载信息",
- Strategy: "策略信息,包括策略名称和ID",
- API: "API信息,包括 API名称和ID",
- Retry: "重试信息",
- Proxy: "记录转发的方法、URL和协议(例如 POST /proxy HTTPS)",
- ProxyStatusCode: "转发状态码",
- Host: "主机信息",
+ BodyBytesSent: "发送给客户端的字节数,不包括响应头的大小; 该变量与Apache模块mod_log_config里的“%B”参数兼容。",
+ Msec: "日志写入时间。单位为秒,精度是毫秒。",
+ HTTPReferer: "记录从哪个页面链接访问过来的",
+ HTTPUserAgent: "记录客户端浏览器相关信息",
+ RequestTime: "请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。",
+ TimeIso8601: "ISO8601标准格式下的本地时间。",
+ TimeLocal: "通用日志格式下的本地时间。",
+ RequestID: "请求id",
+ FinallyServer: "最后一次转发的主机信息(IP端口或域名端口)",
+ Balance: "负载信息",
+ Strategy: "策略信息,包括策略名称和ID",
+ API: "API信息,包括 API名称和ID",
+ Retry: "重试信息",
+ Proxy: "记录转发的方法、URL和协议(例如 POST /proxy HTTPS)",
+ ProxyStatusCode: "转发状态码",
+ Host: "主机信息",
}
)
diff --git a/server/access-field/select.go b/server/access-field/select.go
index 85a8e56df00f7f0939b658b00f4aa694f15a3e0a..bbc3d8c29821f5454d4b68d10e6d0e2e503fff1a 100644
--- a/server/access-field/select.go
+++ b/server/access-field/select.go
@@ -1,4 +1,4 @@
-package accessfield
+package access_field
var (
defaultFields = []AccessFieldKey{
@@ -29,14 +29,14 @@ func init() {
}
}
-//IsDefault 是否有默认值
+//IsDefault 是否是默认配置
func IsDefault(k AccessFieldKey) bool {
_, has := defaultSet[k]
return has
}
-//Default 获取默认的字段
+//Default 获取默认配置
func Default() []AccessFieldKey {
return defaultFields
diff --git a/server/access-field/sort.go b/server/access-field/sort.go
index fa14ec60095fd3b94c69fc40453261a9305eb4d7..bf8af373f4a6eb680fe78623b1a3fdc5a6ebe8ec 100644
--- a/server/access-field/sort.go
+++ b/server/access-field/sort.go
@@ -1,4 +1,4 @@
-package accessfield
+package access_field
var (
all = []AccessFieldKey{
@@ -26,12 +26,12 @@ var (
size = len(all)
)
-//Size 返回size
+//Size 返回域数量
func Size() int {
return size
}
-//All all
+//All 获取所有域key
func All() []AccessFieldKey {
return all
}
diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go
index 9a0b3a50aa9b3176c61a22d151afdc25fb9e0cce..2432c3778af2129a6519a78d239bb4089eb6d30d 100644
--- a/server/cluster/cluster.go
+++ b/server/cluster/cluster.go
@@ -9,7 +9,7 @@ var (
nodes []*entity.Cluster
)
-//Init 初始化集群
+//Init 初始化cluster
func Init(cs []*entity.ClusterInfo) {
nt := make(map[string]*entity.ClusterInfo)
it := make(map[int]*entity.ClusterInfo)
@@ -31,24 +31,14 @@ func Init(cs []*entity.ClusterInfo) {
}
-//Get 根据集群名获取集群信息
+//Get 通过名字获取集群信息
func Get(name string) (*entity.ClusterInfo, bool) {
v, has := byName[name]
return v, has
}
-//GetAll 获取所有集群信息
-func GetAll() []*entity.ClusterInfo {
- return clusterInfos
-}
-
-//GetList 获取集群列表
-func GetList() []*entity.Cluster {
- return nodes
-}
-
-//GetID 通过集群名获取集群ID
+//GetID 通过名字获取集群ID
func GetID(name string) (id int, has bool) {
v, h := byName[name]
if !h {
@@ -56,14 +46,3 @@ func GetID(name string) (id int, has bool) {
}
return v.ID, true
}
-
-//GetClusterCount 获取集群数量
-func GetClusterCount() int {
- return len(nodes)
-}
-
-//GetByID 通过ID获取集群信息
-func GetByID(id int) (*entity.ClusterInfo, bool) {
- v, h := byID[id]
- return v, h
-}
diff --git a/server/dao/console-mysql/alert.go b/server/dao/console-mysql/alert.go
deleted file mode 100644
index f093ad1a40443ad574263d9de6afb63cd1200dd2..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/alert.go
+++ /dev/null
@@ -1,129 +0,0 @@
-package consolemysql
-
-import (
- "encoding/json"
- "strconv"
- "time"
-
- database2 "github.com/eolinker/goku-api-gateway/common/database"
-)
-
-// GetAlertMsgList 获取告警信息列表
-func GetAlertMsgList(page, pageSize int) (bool, []map[string]interface{}, int, error) {
- db := database2.GetConnection()
- var count int
- sql := `SELECT COUNT(*) FROM goku_gateway_alert;`
- err := db.QueryRow(sql).Scan(&count)
- if err != nil {
- return false, make([]map[string]interface{}, 0), 0, err
- }
- sql = "SELECT A.alertID,A.requestURL,A.targetServer,A.targetURL,A.alertPeriodType,A.alertCount,A.updateTime,IFNULL(A.clusterName,''),IFNULL(A.nodeIP,''),IFNULL(B.title,'') FROM goku_gateway_alert A LEFT JOIN goku_cluster B ON B.`name` = A.clusterName ORDER BY updateTime DESC LIMIT ?,?;"
- rows, err := db.Query(sql, (page-1)*pageSize, pageSize)
- if err != nil {
- return false, make([]map[string]interface{}, 0), 0, err
- }
- defer rows.Close()
- alertList := make([]map[string]interface{}, 0)
- for rows.Next() {
- var requestURL, targetServer, targetURL, updateTime, nodeIP, clusterName, title string
- var alertID, alertPeriodType, alertCount int
- err = rows.Scan(&alertID, &requestURL, &targetServer, &targetURL, &alertPeriodType, &alertCount, &updateTime, &clusterName, &nodeIP, &title)
- if err != nil {
- return false, make([]map[string]interface{}, 0), 0, err
- }
- period := "1"
- if alertPeriodType == 1 {
- period = "5"
- } else if alertPeriodType == 2 {
- period = "15"
- } else if alertPeriodType == 3 {
- period = "30"
- } else if alertPeriodType == 4 {
- period = "60"
- }
- var msg = "网关转发失败" + period + "分钟达到" + strconv.Itoa(alertCount) + "次"
- alertInfo := map[string]interface{}{
- "alertID": alertID,
- "requestURL": requestURL,
- "targetServer": targetServer,
- "addr": nodeIP,
- "name": clusterName,
- "title": title,
- "msg": msg,
- "updateTime": updateTime,
- "targetURL": targetURL,
- }
- alertList = append(alertList, alertInfo)
- }
- return true, alertList, count, nil
-}
-
-// ClearAlertMsg 清空告警信息列表
-func ClearAlertMsg() (bool, string, error) {
- db := database2.GetConnection()
- sql := "DELETE FROM goku_gateway_alert;"
- _, err := db.Exec(sql)
- if err != nil {
- return false, "[ERROR]Illegal SQL Statement!", err
- }
- return true, "", nil
-}
-
-// DeleteAlertMsg 删除告警信息
-func DeleteAlertMsg(alertID int) (bool, string, error) {
- db := database2.GetConnection()
- sql := "DELETE FROM goku_gateway_alert WHERE alertID = ?;"
- _, err := db.Exec(sql, alertID)
- if err != nil {
- return false, "[ERROR]Illegal SQL Statement!", err
- }
- return true, "", nil
-}
-
-// AddAlertMsg 新增告警信息
-func AddAlertMsg(requestURL, targetServer, targetURL, ip, clusterName string, alertPeriodType, alertCount int) (bool, string, error) {
- db := database2.GetConnection()
- now := time.Now().Format("2006-01-02 15:04:05")
- sql := "INSERT INTO goku_gateway_alert (requestURL,targetServer,targetURL,alertPeriodType,alertCount,nodeIP,clusterName,updateTime) VALUES (?,?,?,?,?,?,?,?);"
- _, err := db.Exec(sql, requestURL, targetServer, targetURL, alertPeriodType, alertCount, ip, clusterName, now)
- if err != nil {
- return false, "[ERROR]Illegal SQL Statement!", err
- }
- return true, "", nil
-}
-
-//GetAlertConfig 获取告警配置
-func GetAlertConfig() (bool, map[string]interface{}, error) {
- db := database2.GetConnection()
- var apiAlertInfo, sender, senderPassword, smtpAddress string
- var alertStatus, smtpPort, smtpProtocol int
- sql := `SELECT alertStatus,IFNULL(apiAlertInfo,"{}"),IFNULL(sender,""),IFNULL(senderPassword,""),IFNULL(smtpAddress,""),IFNULL(smtpPort,25),IFNULL(smtpProtocol,0) FROM goku_gateway WHERE id = 1;`
- err := db.QueryRow(sql).Scan(&alertStatus, &apiAlertInfo, &sender, &senderPassword, &smtpAddress, &smtpPort, &smtpProtocol)
- if err != nil {
- return false, nil, err
- }
-
- apiAlertInfoJSON := map[string]interface{}{}
-
- if apiAlertInfo == "" || apiAlertInfo == "{}" {
- apiAlertInfoJSON["alertPeriodType"] = 0
- apiAlertInfoJSON["alertAddr"] = ""
- apiAlertInfoJSON["receiverList"] = ""
- } else {
- err = json.Unmarshal([]byte(apiAlertInfo), &apiAlertInfoJSON)
- if err != nil {
- return false, nil, err
- }
- }
-
- gatewayConfig := map[string]interface{}{
- "alertStatus": alertStatus,
- "sender": sender,
- "senderPassword": senderPassword,
- "smtpAddress": smtpAddress,
- "smtpPort": smtpPort,
- "smtpProtocol": smtpProtocol,
- "apiAlertInfo": apiAlertInfoJSON,
- }
- return true, gatewayConfig, nil
-}
diff --git a/server/dao/console-mysql/auth.go b/server/dao/console-mysql/auth.go
deleted file mode 100644
index 9a9a662e1e4fc69f15da2c3d39db3673a8b63440..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/auth.go
+++ /dev/null
@@ -1,315 +0,0 @@
-package consolemysql
-
-import (
- "encoding/json"
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "time"
-
- database2 "github.com/eolinker/goku-api-gateway/common/database"
- "github.com/eolinker/goku-api-gateway/utils"
-)
-
-type basicAuthConf struct {
- UserName string `json:"userName"`
- Password string `json:"password"`
- HideCredential bool `json:"hideCredential"`
- Remark string `json:"remark"`
-}
-
-//APIKeyConf apiKey配置
-type APIKeyConf struct {
- APIKey string `json:"Apikey"`
- TokenPlace string `json:"tokenPlace"`
- HideCredential bool `json:"hideCredential"`
- Remark string `json:"remark"`
-}
-
-//OAuth2GlobalConf oauth2全局配置
-type OAuth2GlobalConf struct {
- oauth2Conf
- Oauth2CredentialList []*oauth2Credential `json:"oauth2CredentialList"`
-}
-
-type oauth2Conf struct {
- Scopes []string `json:"scopes"` //scopes = { required = false, type = "array" },
- MandatoryScope bool `json:"mandatoryScope"` //mandatory_scope = { required = true, type = "boolean", default = false, func = check_mandatory_scope },
- TokenExpiration int `json:"tokenExpiration"` //token_expiration = { required = true, type = "number", default = 7200 },
- EnableAuthorizationCode bool `json:"enableAuthorizationCode"` //enable_authorization_code = { required = true, type = "boolean", default = false },
- EnableImplicitGrant bool `json:"enableImplicitGrant"` //enable_implicit_grant = { required = true, type = "boolean", default = false },
- EnableClientCredentials bool `json:"enableClientCredentials"` //enable_client_credentials = { required = true, type = "boolean", default = false },
- HideCredentials bool `json:"hideCredentials"` //hide_credentials = { type = "boolean", default = false },
- AcceptHTTPIfAlreadyTerminated bool `json:"acceptHttpIfAlreadyTerminated"` //accept_http_if_already_terminated = { required = false, type = "boolean", default = false },
- RefreshTokenTTL int `json:"refreshTokenTTL"` //refresh_token_ttl = {required = true, type = "number", default = 1209600} -- original hardcoded value - 14 days
-}
-
-type jwtCredential struct {
- ISS string `json:"iss"`
- Secret string `json:"secret"`
- RsaPublicKey string `json:"rsaPublicKey"`
- Algorithm string `json:"algorithm"`
- Remark string `json:"remark"`
-}
-
-type jwtConf struct {
- SignatureIsBase64 bool `json:"signatureIsBase64"`
- ClaimsToVerify []string `json:"claimsToVerify"`
- RunOnPreflight bool `json:"runOnPreflight"`
- JwtCredentials []jwtCredential `json:"jwtCredentials"`
- HideCredentials bool `json:"hideCredentials"`
-}
-
-type oauth2Credential struct {
- CredentialID string `json:"credentialID"`
- ClientID string `json:"clientID"`
- ClientSecret string `json:"clientSecret"`
- RedirectURI string `json:"redirectURI"`
- Remark string `json:"remark"`
-}
-
-// GetAuthStatus 获取鉴权状态信息
-func GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) {
- db := database2.GetConnection()
- var basicStatus, apikeyStatus, jwtStatus, oAuthStatus int
- sql := `SELECT IF(goku_plugin.pluginStatus = 0,0,goku_conn_plugin_strategy.pluginStatus) AS pluginStatus FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_strategy.pluginName WHERE goku_conn_plugin_strategy.pluginName = ? AND goku_conn_plugin_strategy.strategyID = ?;`
- err := db.QueryRow(sql, "goku-basic_auth", strategyID).Scan(&basicStatus)
- if err != nil {
-
- }
- sql = `SELECT IF(goku_plugin.pluginStatus = 0,0,goku_conn_plugin_strategy.pluginStatus) AS pluginStatus FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_strategy.pluginName WHERE goku_conn_plugin_strategy.pluginName = ? AND goku_conn_plugin_strategy.strategyID = ?;`
- err = db.QueryRow(sql, "goku-apikey_auth", strategyID).Scan(&apikeyStatus)
- if err != nil {
-
- }
- sql = `SELECT IF(goku_plugin.pluginStatus = 0,0,goku_conn_plugin_strategy.pluginStatus) AS pluginStatus FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_strategy.pluginName WHERE goku_conn_plugin_strategy.pluginName = ? AND goku_conn_plugin_strategy.strategyID = ?;`
- err = db.QueryRow(sql, "goku-jwt_auth", strategyID).Scan(&jwtStatus)
- if err != nil {
-
- }
- sql = `SELECT IF(goku_plugin.pluginStatus = 0,0,goku_conn_plugin_strategy.pluginStatus) AS pluginStatus FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_strategy.pluginName WHERE goku_conn_plugin_strategy.pluginName = ? AND goku_conn_plugin_strategy.strategyID = ?;`
- err = db.QueryRow(sql, "goku-oauth2_auth", strategyID).Scan(&oAuthStatus)
- if err != nil {
-
- }
- authInfo := map[string]interface{}{
- "basicAuthStatus": basicStatus,
- "apiKeyStatus": apikeyStatus,
- "jwtStatus": jwtStatus,
- "oAuthStatus": oAuthStatus,
- }
- return true, authInfo, err
-}
-
-// GetAuthInfo 获取认证信息
-func GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) {
- db := database2.GetConnection()
- var strategyName, auth string
- sql := "SELECT auth,strategyName FROM goku_gateway_strategy WHERE strategyID = ?;"
- err := db.QueryRow(sql, strategyID).Scan(&auth, &strategyName)
- if err != nil {
- return false, make(map[string]interface{}), err
- }
- basicAuthList := make([]basicAuthConf, 0)
- apiKeyList := make([]APIKeyConf, 0)
- jwtConf := jwtConf{JwtCredentials: make([]jwtCredential, 0)}
- oauth2Conf := OAuth2GlobalConf{}
-
- var basicConfig, apiKeyConfig, jwtConfig, oAuthConfig string
- sql = `SELECT pluginConfig FROM goku_conn_plugin_strategy WHERE pluginName = ? AND strategyID = ? AND pluginStatus = 1;`
- err = db.QueryRow(sql, "goku-basic_auth", strategyID).Scan(&basicConfig)
- if err == nil {
- if basicConfig != "" {
- json.Unmarshal([]byte(basicConfig), &basicAuthList)
- if err != nil {
- return false, make(map[string]interface{}), err
- }
- }
- }
- sql = `SELECT pluginConfig FROM goku_conn_plugin_strategy WHERE pluginName = ? AND strategyID = ? AND pluginStatus = 1;`
- err = db.QueryRow(sql, "goku-apikey_auth", strategyID).Scan(&apiKeyConfig)
- if err == nil {
- if apiKeyConfig != "" {
- err = json.Unmarshal([]byte(apiKeyConfig), &apiKeyList)
- if err != nil {
- return false, make(map[string]interface{}), err
- }
- }
- }
- sql = `SELECT pluginConfig FROM goku_conn_plugin_strategy WHERE pluginName = ? AND strategyID = ? AND pluginStatus = 1;`
- err = db.QueryRow(sql, "goku-jwt_auth", strategyID).Scan(&jwtConfig)
- if err == nil {
- if jwtConfig != "" {
- err = json.Unmarshal([]byte(jwtConfig), &jwtConf)
- if err != nil {
- return false, make(map[string]interface{}), err
- }
- }
- }
-
- sql = `SELECT pluginConfig FROM goku_conn_plugin_strategy WHERE pluginName = ? AND strategyID = ? AND pluginStatus = 1;`
- err = db.QueryRow(sql, "goku-oauth2_auth", strategyID).Scan(&oAuthConfig)
- if err == nil {
- if oAuthConfig != "" {
- err = json.Unmarshal([]byte(oAuthConfig), &oauth2Conf)
- if err != nil {
- return false, make(map[string]interface{}), err
- }
- }
- }
- if oauth2Conf.Oauth2CredentialList == nil {
- oauth2Conf.Oauth2CredentialList = make([]*oauth2Credential, 0)
- }
-
- authInfo := map[string]interface{}{
- "strategyID": strategyID,
- "strategyName": strategyName,
- "auth": auth,
- "basicAuthList": basicAuthList,
- "apiKeyList": apiKeyList,
- "jwtCredentialList": jwtConf.JwtCredentials,
- "oauth2CredentialList": oauth2Conf.Oauth2CredentialList,
- }
- return true, authInfo, nil
-}
-
-// EditAuthInfo 编辑认证信息
-func EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList string, delClientIDList []string) (bool, error) {
- db := database2.GetConnection()
- now := time.Now().Format("2006-01-02 15:04:05")
- sql := "UPDATE goku_gateway_strategy SET strategyName = ? WHERE strategyID = ?;"
- stmt, err := db.Prepare(sql)
- if err != nil {
- return false, err
- }
- defer stmt.Close()
- _, err = stmt.Exec(strategyName, strategyID)
- if err != nil {
- return false, err
- }
- // 设置basic信息
- Tx, _ := db.Begin()
- _, err = Tx.Exec("UPDATE goku_conn_plugin_strategy SET pluginConfig = ?,updateTime = ? WHERE strategyID = ? AND pluginName = ? AND pluginStatus = 1;", basicAuthList, now, strategyID, "goku-basic_auth")
- if err != nil {
- Tx.Rollback()
- return false, err
- }
- _, err = Tx.Exec("UPDATE goku_conn_plugin_strategy SET pluginConfig = ?,updateTime = ? WHERE strategyID = ? AND pluginName = ? AND pluginStatus = 1;", apikeyList, now, strategyID, "goku-apikey_auth")
- if err != nil {
- Tx.Rollback()
- return false, err
- }
-
- // 获取jwt配置信息
- var jwtConfInfo string
- err = Tx.QueryRow(`SELECT pluginConfig FROM goku_conn_plugin_strategy WHERE pluginName = ? AND strategyID = ? AND pluginStatus = 1;`, "goku-jwt_auth", strategyID).Scan(&jwtConfInfo)
- if err != nil {
- }
- jwtConf := &jwtConf{}
- jwtList := make([]jwtCredential, 0)
- if jwtCredentialList != "" {
- err = json.Unmarshal([]byte(jwtCredentialList), &jwtList)
- if err != nil {
- Tx.Rollback()
- return false, err
- }
- } else {
-
- sql = "UPDATE goku_gateway_strategy SET updateTime = ? WHERE strategyID = ?;"
- _, err = Tx.Exec(sql, now, strategyID)
- if err != nil {
- Tx.Rollback()
- return false, err
- }
- Tx.Commit()
- return true, nil
- }
-
- err = json.Unmarshal([]byte(jwtConfInfo), &jwtConf)
- if err != nil && jwtConfInfo != "" {
- Tx.Rollback()
- return false, err
- }
- jwtConf.JwtCredentials = jwtList
- jwtJSON, err := json.Marshal(jwtConf)
- if err != nil {
- Tx.Rollback()
- return false, err
- }
- _, err = Tx.Exec("UPDATE goku_conn_plugin_strategy SET pluginConfig = ?,updateTime = ? WHERE strategyID = ? AND pluginName = ? AND pluginStatus = 1 ", jwtJSON, now, strategyID, "goku-jwt_auth")
- if err != nil {
- Tx.Rollback()
- return false, err
- }
-
- var oAuthConf string
- // 获取oAuth配置信息
- err = Tx.QueryRow(`SELECT pluginConfig FROM goku_conn_plugin_strategy WHERE pluginName = ? AND strategyID = ? AND pluginStatus = 1;`, "goku-oauth2_auth", strategyID).Scan(&oAuthConf)
- if err != nil {
-
- sql = "UPDATE goku_gateway_strategy SET updateTime = ? WHERE strategyID = ?;"
- _, err = Tx.Exec(sql, now, strategyID)
- if err != nil {
- Tx.Rollback()
- return false, err
- }
- Tx.Commit()
- return true, nil
- }
- oConf := &OAuth2GlobalConf{}
- oAuthList := make([]*oauth2Credential, 0)
- if oauth2CredentialList != "" {
- err = json.Unmarshal([]byte(oauth2CredentialList), &oAuthList)
- if err != nil {
- Tx.Rollback()
- return false, err
- }
- } else {
-
- sql = "UPDATE goku_gateway_strategy SET updateTime = ? WHERE strategyID = ?;"
- _, err = Tx.Exec(sql, now, strategyID)
- if err != nil {
- Tx.Rollback()
- return false, err
- }
- Tx.Commit()
- return true, nil
- }
- err = json.Unmarshal([]byte(oAuthConf), &oConf)
- if err != nil {
- Tx.Rollback()
- return false, err
- }
- oConf.Oauth2CredentialList = make([]*oauth2Credential, 0)
- for _, value := range oAuthList {
- if value.CredentialID == "" {
- value.CredentialID = utils.GetRandomString(16)
- }
- if value.ClientID == "" {
- value.ClientID = utils.GetRandomString(16)
- }
- oConf.Oauth2CredentialList = append(oConf.Oauth2CredentialList, value)
- }
-
- oAuthGlobalConf, err := json.Marshal(oConf)
- if err != nil {
- Tx.Rollback()
- return false, err
- }
- _, err = Tx.Exec("UPDATE goku_conn_plugin_strategy SET pluginConfig = ?,updateTime = ? WHERE strategyID = ? AND pluginName = ? ", oAuthGlobalConf, now, strategyID, "goku-oauth2_auth")
- if err != nil {
- Tx.Rollback()
- return false, err
- }
-
- sql = "UPDATE goku_gateway_strategy SET updateTime = ? WHERE strategyID = ?;"
- _, err = Tx.Exec(sql, now, strategyID)
- if err != nil {
- Tx.Rollback()
- return false, err
- }
- err = Tx.Commit()
- if err != nil {
- info := err.Error()
- log.Info(info)
- }
- return true, nil
-}
diff --git a/server/dao/console-mysql/cluster.go b/server/dao/console-mysql/cluster.go
deleted file mode 100644
index 82b1b4be7585ae909d55ed02cce4487f45a42206..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/cluster.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package consolemysql
-
-import (
- "github.com/eolinker/goku-api-gateway/common/database"
- "github.com/eolinker/goku-api-gateway/server/entity"
- jsoniter "github.com/json-iterator/go"
-)
-
-//InsertClusters 插入集群信息
-func InsertClusters(cs []*entity.ClusterInfo) error {
- db := database.GetConnection()
- stmt, e := db.Prepare("INSERT INTO `goku_cluster`(`name`,`title`,`note`,`db`,`redis`) VALUES (?,?,?,?,?) ON DUPLICATE KEY UPDATE `title`=VALUES(`title`),`note`=VALUES(`note`),`db`=VALUES(`db`),`redis`=VALUES(`redis`)")
- if e != nil {
- return e
- }
- for _, c := range cs {
- db, _ := jsoniter.MarshalToString(c.DB)
- redis, _ := jsoniter.MarshalToString(c.Redis)
- stmt.Exec(c.Name, c.Title, c.Note, db, redis)
- }
-
- return nil
-}
-
-//LoadClusters 加载集群列表
-func LoadClusters() (map[string]*entity.ClusterInfo, error) {
- db := database.GetConnection()
- sql := "select `id`, `name`,`title`,`note`,`db`,`redis` from `goku_cluster`;"
- stmt, e := db.Prepare(sql)
- if e != nil {
- return nil, e
- }
-
- rows, e := stmt.Query()
- if e != nil {
- return nil, e
- }
-
- vs := make(map[string]*entity.ClusterInfo)
- for rows.Next() {
- v := new(entity.ClusterInfo)
- db := ""
- redis := ""
- err := rows.Scan(&v.ID, &v.Name, &v.Title, &v.Note, &db, &redis)
- if err != nil {
- return nil, nil
- }
-
- err = jsoniter.UnmarshalFromString(db, &v.DB)
- if err != nil {
- return nil, nil
- }
-
- err = jsoniter.UnmarshalFromString(redis, &v.Redis)
- if err != nil {
- return nil, nil
- }
- vs[v.Name] = v
- }
- return vs, nil
-}
diff --git a/server/dao/console-mysql/dao-monitor/cluster.go b/server/dao/console-mysql/dao-monitor/cluster.go
deleted file mode 100644
index d361aded0a8a11a54fa8c6b0442d76cb92377ff9..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/dao-monitor/cluster.go
+++ /dev/null
@@ -1,199 +0,0 @@
-package dao_monitor
-
-import (
- "fmt"
- "github.com/eolinker/goku-api-gateway/common/database"
- monitor_key "github.com/eolinker/goku-api-gateway/server/monitor/monitor-key"
- "strconv"
-)
-
-var (
- valueField []string
-
- sqlSave string
- sqlSaveParameterSize = 0
-
- sqlSelectGateway string
- sqlSelectAllGateway string
- sqlSelectGatewayByHour string
- sqlSelectGatewayAllByHour string
-
- sqlSelectStrategy string
- sqlSelectStrategyWhere string
- sqlSelectAllStrategy string
- sqlSelectAllStrategyWhere string
-
- sqlSelectApi string
- sqlSelectApiWhere string
- sqlSelectAllApi string
- sqlSelectAllApiWhere string
-
- sqlSelectApiOfStrategy string
- sqlSelectApiOfStrategyWhere string
- sqlSelectAllApiOfStrategy string
- sqlSelectAllApiOfStrategyWhere string
-
- sqlSelectStrategyOfAPI string
- sqlSelectStrategyOfAPIWhere string
- sqlSelectAllStrategyOfAPI string
- sqlSelectAllStrategyOfAPIWhere string
-
- sqlSelectStrategyByHour _HourSqlBuild
- sqlSelectStrategyOfAPIByHour _HourSqlBuild
- sqlSelectApiByHour _HourSqlBuild
- sqlSelectApiOfStrategyByHour _HourSqlBuild
-)
-
-type SCAN interface {
- Scan(dest ...interface{}) error
-}
-
-func init() {
- keys := monitor_key.Keys()
- fields := make([]string, len(keys))
- keyFields := make([]string, len(keys))
- for i := range keys {
- fields[i] = fmt.Sprintf("`%s`", keys[i].String())
- keyFields[i] = keys[i].String()
- }
- valueField = keyFields
-
- sqlSave, sqlSaveParameterSize = genSqlSave(fields)
-
- sqlSelectGateway = genSqlSelectGateway(fields, false)
- sqlSelectStrategy = genSqlSelectStrategy(fields, false)
- sqlSelectStrategyWhere = genSqlSelectStrategySearch(fields, false)
-
- sqlSelectAllGateway = genSqlSelectGateway(fields, true)
-
- sqlSelectApiOfStrategy = genSqlSelectApiOfStrategy(fields, false)
- sqlSelectApiOfStrategyWhere = genSqlSelectApiOfStrategySearch(fields, false)
-
- sqlSelectApi = genSqlSelectAPI(fields, false)
- sqlSelectApiWhere = genSqlSelectAPISearch(fields, false)
-
- sqlSelectStrategyOfAPI = genSqlSelectStrategyOfApi(fields, false)
- sqlSelectStrategyOfAPIWhere = genSqlSelectStrategyOfApiSearch(fields, false)
-
- sqlSelectGatewayByHour = genSqlSelectGatewayByHour(fields, false)
- sqlSelectStrategyByHour = initSqlSelectStrategyByHour(fields)
- sqlSelectStrategyOfAPIByHour = initSqlSelectStrategyOfApiByHour(fields)
- sqlSelectApiByHour = initSqlSelectAPIByHour(fields)
- sqlSelectApiOfStrategyByHour = initSqlSelectAPIOfStrategyByHour(fields)
-
- sqlSelectGatewayAllByHour = genSqlSelectGatewayByHour(fields, true)
- sqlSelectAllStrategy = genSqlSelectStrategy(fields, true)
- sqlSelectAllStrategyWhere = genSqlSelectStrategySearch(fields, true)
- sqlSelectAllApi = genSqlSelectAPI(fields, true)
- sqlSelectAllApiWhere = genSqlSelectAPISearch(fields, true)
-
- sqlSelectAllApiOfStrategy = genSqlSelectApiOfStrategy(fields, true)
- sqlSelectAllApiOfStrategyWhere = genSqlSelectApiOfStrategySearch(fields, true)
- sqlSelectAllStrategyOfAPI = genSqlSelectStrategyOfApi(fields, true)
- sqlSelectAllStrategyOfAPIWhere = genSqlSelectStrategyOfApiSearch(fields, true)
-
-}
-
-func Save(strategyId string, apiId int, clusterId int, hour int, now string, values map[string]string) error {
-
- parameter := make([]interface{}, 0, sqlSaveParameterSize)
- parameter = append(parameter, strategyId, apiId, clusterId, hour)
- for i := range valueField {
- v, has := values[valueField[i]]
- if has {
- vint, err := strconv.Atoi(v)
- if err != nil {
- parameter = append(parameter, 0)
- } else {
- parameter = append(parameter, vint)
- }
- } else {
- parameter = append(parameter, 0)
- }
- }
-
- parameter = append(parameter, now)
- stmt, e := database.GetConnection().Prepare(sqlSave)
- if e != nil {
- return e
- }
- defer stmt.Close()
- _, err := stmt.Exec(parameter...)
- if err != nil {
- return err
- }
-
- return nil
-
-}
-
-func GetGateway(clusterId, start, end int) (monitor_key.MonitorValues, error) {
- s := make([]interface{}, 0, 3)
- s = append(s, start, end)
- sql := sqlSelectAllGateway
- if clusterId != 0 {
- sql = sqlSelectGateway
- s = append(s, clusterId)
- }
- stmt, e := database.GetConnection().Prepare(sql)
- if e != nil {
- return nil, e
- }
- defer stmt.Close()
- row := stmt.QueryRow(s...)
- values, _ := read(row)
- //if err!=nil{
- // return nil,err
- //}
- return values, nil
-}
-
-func GetGatewayInfo() (nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount int, err error) {
- db := database.GetConnection()
- // 获取节点启动数量
-
- err = db.QueryRow("SELECT COUNT(0) FROM goku_node_info WHERE nodeStatus = 1;").Scan(&nodeStartCount)
- if err != nil {
- return
- }
-
- // 获取节点关闭数量
-
- err = db.QueryRow("SELECT COUNT(0) FROM goku_node_info WHERE nodeStatus = 0;").Scan(&nodeStopCount)
- if err != nil {
- return
- }
- // 获取项目数量
- err = db.QueryRow("SELECT COUNT(0) FROM goku_gateway_project;").Scan(&projectCount)
- if err != nil {
- return
- }
-
- // 获取api数量
- err = db.QueryRow("SELECT COUNT(0) FROM goku_gateway_api;").Scan(&apiCount)
- if err != nil {
- return
- }
-
- // 获取策略数量
- err = db.QueryRow("SELECT COUNT(0) FROM goku_gateway_strategy;").Scan(&strategyCount)
- if err != nil {
- return
- }
- return
-}
-
-type MonitorValueWidthStrategy struct {
- Id string
- Name string
- Value monitor_key.MonitorValues
- Status int
- Hour int
-}
-type MonitorValueWidthAPI struct {
- Id int
- Name string
- RequestURL string
- Value monitor_key.MonitorValues
- Hour int
-}
diff --git a/server/dao/console-mysql/dao-monitor/download.go b/server/dao/console-mysql/dao-monitor/download.go
deleted file mode 100644
index 462e04fdbb72fc76303441c9f34ed2a84a9e33a1..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/dao-monitor/download.go
+++ /dev/null
@@ -1,127 +0,0 @@
-package dao_monitor
-
-import (
- "github.com/eolinker/goku-api-gateway/common/database"
-)
-
-func GetStrategyByHour(clusterId int, hours []int) ([]*MonitorValueWidthStrategy, error) {
-
- stmt, e := database.GetConnection().Prepare(sqlSelectStrategyByHour.Build(hours))
- if e != nil {
- return nil, e
- }
- defer stmt.Close()
- rows, err := stmt.Query(clusterId)
- if err != nil {
- return nil, err
- }
- defer rows.Close()
-
- all := make([]*MonitorValueWidthStrategy, 0, 1000)
-
- for rows.Next() {
- v := new(MonitorValueWidthStrategy)
-
- values, err := read(rows, &v.Hour, &v.Id, &v.Name, &v.Status)
- if err != nil {
- return nil, err
- }
-
- v.Value = values
-
- all = append(all, v)
- }
-
- return all, nil
-}
-
-func GetAPIByHour(clusterId int, hours []int) ([]*MonitorValueWidthAPI, error) {
-
- stmt, e := database.GetConnection().Prepare(sqlSelectApiByHour.Build(hours))
- if e != nil {
- return nil, e
- }
- defer stmt.Close()
- rows, err := stmt.Query(clusterId)
- if err != nil {
- return nil, err
- }
- defer rows.Close()
-
- all := make([]*MonitorValueWidthAPI, 0, 1000)
-
- for rows.Next() {
- v := new(MonitorValueWidthAPI)
-
- values, err := read(rows, &v.Hour, &v.Id, &v.Name, &v.RequestURL)
- if err != nil {
- return nil, err
- }
-
- v.Value = values
-
- all = append(all, v)
- }
-
- return all, nil
-}
-func GetAPIOfStrategyByHour(clusterId int, strategyID string, hours []int) ([]*MonitorValueWidthAPI, error) {
-
- stmt, e := database.GetConnection().Prepare(sqlSelectApiOfStrategyByHour.Build(hours))
- if e != nil {
- return nil, e
- }
- defer stmt.Close()
- rows, err := stmt.Query(strategyID, clusterId)
- if err != nil {
- return nil, err
- }
- defer rows.Close()
-
- all := make([]*MonitorValueWidthAPI, 0, 1000)
-
- for rows.Next() {
- v := new(MonitorValueWidthAPI)
-
- values, err := read(rows, &v.Hour, &v.Id, &v.Name, &v.RequestURL)
- if err != nil {
- return nil, err
- }
-
- v.Value = values
-
- all = append(all, v)
- }
-
- return all, nil
-}
-func GetStrategyOfAPIHour(clusterId int, apiId int, hours []int) ([]*MonitorValueWidthStrategy, error) {
-
- stmt, e := database.GetConnection().Prepare(sqlSelectStrategyOfAPIByHour.Build(hours))
- if e != nil {
- return nil, e
- }
- defer stmt.Close()
- rows, err := stmt.Query(apiId, clusterId, )
- if err != nil {
- return nil, err
- }
- defer rows.Close()
-
- all := make([]*MonitorValueWidthStrategy, 0, 1000)
-
- for rows.Next() {
- strategy := new(MonitorValueWidthStrategy)
-
- values, err := read(rows, &strategy.Hour, &strategy.Id, &strategy.Name, &strategy.Status)
- if err != nil {
- return nil, err
- }
-
- strategy.Value = values
-
- all = append(all, strategy)
- }
-
- return all, nil
-}
diff --git a/server/dao/console-mysql/dao-monitor/read.go b/server/dao/console-mysql/dao-monitor/read.go
deleted file mode 100644
index 283c88b45fa8e1ba5617ae149f2d424a20d546cd..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/dao-monitor/read.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package dao_monitor
-
-import monitor_key "github.com/eolinker/goku-api-gateway/server/monitor/monitor-key"
-
-func read(s SCAN, args ...interface{}) (monitor_key.MonitorValues, error) {
- v := monitor_key.MakeValue()
- vp := make([]interface{}, 0, monitor_key.MonitorKeyTypeSize+len(args))
-
- vp = append(vp, args...)
-
- for i := range v {
- vp = append(vp, &v[i])
- }
- err := s.Scan(vp...)
- if err != nil {
- return v, err
- }
- return v, nil
-}
diff --git a/server/dao/console-mysql/dao-monitor/sql.go b/server/dao/console-mysql/dao-monitor/sql.go
deleted file mode 100644
index 97fc965b7c3b901e2d6c725b1ff17fb05f12354e..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/dao-monitor/sql.go
+++ /dev/null
@@ -1,522 +0,0 @@
-package dao_monitor
-
-import (
- "fmt"
- "strconv"
- "strings"
-)
-
-// sava
-func genSqlSave(fields []string) (string, int) {
-
- insertField := make([]string, 0, len(fields)+5)
-
- insertField = append(insertField, "`strategyID`")
- insertField = append(insertField, "`apiID`")
- insertField = append(insertField, "`clusterID`")
- insertField = append(insertField, "`hour`")
-
- insertField = append(insertField, fields...)
-
- insertField = append(insertField, "`updateTime`")
- sqlSaveParameterSize := len(insertField)
- args := make([]string, sqlSaveParameterSize)
- for i := range args {
- args[i] = "?"
- }
-
- build := strings.Builder{}
- build.WriteString("INSERT INTO `goku_monitor_cluster`(")
- build.WriteString(strings.Join(insertField, ","))
- build.WriteString(")VALUES(")
- build.WriteString(strings.Join(args, ","))
- build.WriteString(") ON DUPLICATE KEY UPDATE ")
- for i := range fields {
- build.WriteString(fields[i])
- build.WriteString(" = ")
- build.WriteString("VALUES(")
- build.WriteString(fields[i])
- build.WriteString("),")
- }
- build.WriteString("`updateTIme` = VALUES(`updateTime`)")
- return build.String(), sqlSaveParameterSize
-}
-
-// 全局
-func genSqlSelectGateway(fields []string, isAll bool) string {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- build := strings.Builder{}
- build.WriteString("SELECT ")
- build.WriteString(strings.Join(sums, ","))
- build.WriteString(" FROM `goku_monitor_cluster` M")
- if isAll {
- build.WriteString(" WHERE M.`hour`>= ? AND M.`hour` <= ?")
- } else {
- build.WriteString(" WHERE M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
- }
-
- return build.String()
-}
-
-// // strategy
-// func genSqlSelectStrategyCount(isAll bool) string {
-
-// build := strings.Builder{}
-// build.WriteString("SELECT")
-// build.WriteString("\nCOUNT(*)")
-// build.WriteString("\nFROM `goku_monitor_cluster` M ")
-// build.WriteString("\nRIGHT JOIN `goku_gateway_strategy` S ON M.`strategyID` = S.`strategyID`")
-// if isAll {
-// build.WriteString("\nAND M.`hour`>= ? AND M.`hour` <= ?")
-// } else {
-// build.WriteString("\nAND M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
-// }
-// return build.String()
-// }
-
-// // strategy
-// func genSqlSelectStrategyCountSearch(isAll bool) string {
-
-// build := strings.Builder{}
-// build.WriteString("SELECT")
-// build.WriteString("\nCOUNT(*)")
-// build.WriteString("\nFROM `goku_monitor_cluster` M ")
-// build.WriteString("\nRIGHT JOIN `goku_gateway_strategy` S ON M.`strategyID` = S.`strategyID`")
-// if isAll {
-// build.WriteString("\nAND M.`hour`>= ? AND M.`hour` <= ?")
-// } else {
-// build.WriteString("\nAND M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
-// }
-// build.WriteString("\nWHERE S.`strategyName` LIKE ? OR S.`strategyID` LIKE ?")
-// return build.String()
-// }
-
-// strategy
-func genSqlSelectStrategy(fields []string, isAll bool) string {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- build := strings.Builder{}
- build.WriteString("SELECT")
- build.WriteString("\nS.`strategyId` AS `strategyId`,")
- build.WriteString("\nS.`strategyName` AS `strategyName`,")
- build.WriteString("\nS.`enableStatus` AS `enableStatus`,")
- build.WriteString("\n")
- build.WriteString(strings.Join(sums, ",\n"))
- build.WriteString("\nFROM `goku_monitor_cluster` M ")
- build.WriteString("\nRIGHT JOIN `goku_gateway_strategy` S ON M.`strategyID` = S.`strategyID`")
- if isAll {
- build.WriteString("\nAND M.`hour`>= ? AND M.`hour` <= ?")
- } else {
- build.WriteString("\nAND M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
- }
- // build.WriteString("\nAND M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
- build.WriteString("\nGROUP by `strategyId`,`strategyName`,`enableStatus`")
-
- return build.String()
-}
-
-// strategy
-func genSqlSelectStrategySearch(fields []string, isAll bool) string {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- build := strings.Builder{}
- build.WriteString("SELECT")
- build.WriteString("\nS.`strategyId` AS `strategyId`,")
- build.WriteString("\nS.`strategyName` AS `strategyName`,")
- build.WriteString("\nS.`enableStatus` AS `enableStatus`,")
- build.WriteString("\n")
- build.WriteString(strings.Join(sums, ",\n"))
- build.WriteString("\nFROM `goku_monitor_cluster` M ")
- build.WriteString("\nRIGHT JOIN `goku_gateway_strategy` S ON M.`strategyID` = S.`strategyID`")
- if isAll {
- build.WriteString("\nAND M.`hour`>= ? AND M.`hour` <= ?")
- } else {
- build.WriteString("\nAND M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
- }
- // build.WriteString("\nAND M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
- build.WriteString("\nWHERE S.`strategyName` LIKE ? OR S.`strategyID` LIKE ?")
- build.WriteString("\nGROUP by `strategyId`,`strategyName`,`enableStatus`")
-
- return build.String()
-}
-
-// strategy
-func genSqlSelectAPICount(isAll bool) string {
-
- build := strings.Builder{}
- build.WriteString("SELECT")
- build.WriteString("\nCOUNT(*)")
- build.WriteString("\nFROM `goku_gateway_api` A")
- build.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`apiID` = A.`apiID`")
- if isAll {
- build.WriteString(" AND M.`hour`>= ? AND M.`hour` <= ?")
- } else {
- build.WriteString(" AND M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
- }
- // build.WriteString(" AND M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
- build.WriteString("\nGROUP by `apiID`,`apiName` ,`requestURL`")
- return build.String()
-}
-
-// API
-func genSqlSelectAPI(fields []string, isAll bool) string {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- build := strings.Builder{}
- build.WriteString("SELECT")
- build.WriteString("\nA.`apiID` AS `apiID`,")
- build.WriteString("\nA.`apiName` AS `apiName`,")
- build.WriteString("\nA.`requestURL` AS `requestURL`,")
- build.WriteString("\n")
- build.WriteString(strings.Join(sums, ",\n"))
- build.WriteString("\nFROM `goku_gateway_api` A")
- build.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`apiID` = A.`apiID`")
- if isAll {
- build.WriteString(" AND M.`hour`>= ? AND M.`hour` <= ?")
- } else {
- build.WriteString(" AND M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
- }
- // build.WriteString(" AND M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
- build.WriteString("\nGROUP by `apiID`,`apiName` ,`requestURL`")
-
- return build.String()
-
-}
-
-// API
-func genSqlSelectAPISearch(fields []string, isAll bool) string {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- build := strings.Builder{}
- build.WriteString("SELECT")
- build.WriteString("\nA.`apiID` AS `apiID`,")
- build.WriteString("\nA.`apiName` AS `apiName`,")
- build.WriteString("\nA.`requestURL` AS `requestURL`,")
- build.WriteString("\n")
- build.WriteString(strings.Join(sums, ",\n"))
- build.WriteString("\nFROM `goku_gateway_api` A")
- build.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`apiID` = A.`apiID`")
- if isAll {
- build.WriteString(" AND M.`hour`>= ? AND M.`hour` <= ?")
- } else {
- build.WriteString(" AND M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
- }
- // build.WriteString(" AND `hour`>= ? AND `hour` <= ? AND `clusterID` = ?")
- build.WriteString("\nWHERE A.`apiName` like ? OR A.`requestURL` like ? \n")
- build.WriteString("\nGROUP by `apiID`,`apiName` ,`requestURL`")
-
- return build.String()
-
-}
-
-// 通过apiID 查 策略监控
-func genSqlSelectStrategyOfApi(fields []string, isAll bool) string {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- build := strings.Builder{}
- build.WriteString("SELECT")
- build.WriteString("\nS.`strategyId` AS `strategyId`,")
- build.WriteString("\nS.`strategyName` AS `strategyName`,")
- build.WriteString("\nS.`enableStatus` AS `enableStatus`,")
- build.WriteString("\n")
- build.WriteString(strings.Join(sums, ",\n"))
- build.WriteString("\nFROM `goku_conn_strategy_api` SAPI ")
- build.WriteString("\nINNER JOIN `goku_gateway_strategy` S ON S.`strategyID` = SAPI.`strategyID` AND SAPI.`apiID` = ?")
- build.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`strategyID` = SAPI.`strategyID`")
-
- build.WriteString(" AND M.`hour`>= ? AND M.`hour` <= ? AND SAPI.`apiID` = M.`apiID`")
-
- if !isAll {
- build.WriteString(" AND M.`clusterID` = ?")
- }
- build.WriteString(" GROUP by `strategyId`,M.`apiID`,`strategyName`,`enableStatus`")
-
- return build.String()
-} // 通过apiID 查 策略监控
-func genSqlSelectStrategyOfApiSearch(fields []string, isAll bool) string {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- build := strings.Builder{}
- build.WriteString("SELECT")
- build.WriteString("\nS.`strategyId` AS `strategyId`,")
- build.WriteString("\nS.`strategyName` AS `strategyName`,")
- build.WriteString("\nS.`enableStatus` AS `enableStatus`,")
- build.WriteString("\n")
- build.WriteString(strings.Join(sums, ",\n"))
- build.WriteString("\nFROM `goku_conn_strategy_api` SAPI ")
- build.WriteString("\nINNER JOIN `goku_gateway_strategy` S ON S.`strategyID` = SAPI.`strategyID` AND SAPI.`apiID` = ?")
- build.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`strategyID` = SAPI.`strategyID` AND SAPI.`apiID` = M.`apiID")
- build.WriteString(" AND M.`hour`>= ? AND M.`hour` <= ?`")
- // build.WriteString(" AND `hour`>= ? AND `hour` <= ? AND `clusterID` = ?")
- if !isAll {
- build.WriteString(" AND M.`clusterID` = ?\n")
- }
- build.WriteString("\nWHERE S.`strategyName` LIKE ? OR S.`strategyID` LIKE ?\n")
-
- build.WriteString(" GROUP by `strategyId`,M.`apiID`,`strategyName`,`enableStatus`")
-
- return build.String()
-}
-
-// 通过strategyId 查 API监控
-func genSqlSelectApiOfStrategy(fields []string, isAll bool) string {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- build := strings.Builder{}
- build.WriteString("SELECT")
- build.WriteString("\nA.`apiID` AS `apiID`,")
- build.WriteString("\nA.`apiName` AS `apiName`,")
- build.WriteString("\nA.`requestURL` AS `requestURL`,")
- build.WriteString("\n")
- build.WriteString(strings.Join(sums, ",\n"))
- build.WriteString("\nFROM `goku_conn_strategy_api` SAPI\n")
- build.WriteString("\nINNER JOIN `goku_gateway_api` A ON A.`apiID`=SAPI.`apiID` AND SAPI.`strategyID`= ? \n")
- if isAll {
- build.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`apiID` = SAPI.`apiID` AND M.`hour`>= ? AND M.`hour` <= ?\n")
- } else {
- build.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`apiID` = SAPI.`apiID` AND M.`hour`>= ? AND M.`hour` <= ? AND `clusterID` = ?\n")
- }
-
- build.WriteString("\nGROUP BY `apiID`,`apiName` ,`requestURL`")
-
- return build.String()
-}
-
-// 通过strategyId 查 API监控
-func genSqlSelectApiOfStrategySearch(fields []string, isAll bool) string {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- build := strings.Builder{}
- build.WriteString("SELECT")
- build.WriteString("\nA.`apiID` AS `apiID`,")
- build.WriteString("\nA.`apiName` AS `apiName`,")
- build.WriteString("\nA.`requestURL` AS `requestURL`,")
- build.WriteString("\n")
- build.WriteString(strings.Join(sums, ",\n"))
- build.WriteString("\nFROM `goku_conn_strategy_api` SAPI\n")
- build.WriteString("\nINNER JOIN `goku_gateway_api` A ON A.`apiID`=SAPI.`apiID` AND SAPI.`strategyID`= ? \n")
- if isAll {
- build.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`apiID` = SAPI.`apiID`\n")
- } else {
- build.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`apiID` = SAPI.`apiID` AND M.`hour`>= ? AND M.`hour` <= ? AND `clusterID` = ?\n")
- }
- // build.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`apiID` = SAPI.`apiID` AND M.`hour`>= ? AND M.`hour` <= ? AND `clusterID` = ?\n")
- build.WriteString("\nWHERE A.`apiName` like ? OR A.`requestURL` like ? \n")
-
- build.WriteString("\nGROUP BY `apiID`,`apiName` ,`requestURL`")
-
- return build.String()
-}
-
-// 按小时取全局数据
-func genSqlSelectGatewayByHour(fields []string, isAll bool) string {
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
- }
- build := strings.Builder{}
- build.WriteString("SELECT")
- build.WriteString("\nM.`hour` AS `hour`,")
- build.WriteString("\n")
- build.WriteString(strings.Join(sums, ","))
- build.WriteString("\nFROM `goku_monitor_cluster` M")
- if isAll {
- build.WriteString("\nWHERE M.`hour`>= ? AND M.`hour` <= ?")
- } else {
- build.WriteString("\nWHERE M.`hour`>= ? AND M.`hour` <= ? AND M.`clusterID` = ?")
- }
-
- build.WriteString("\nGROUP by `hour`")
-
- return build.String()
-}
-
-type _HourSqlBuild struct {
- start string
- end string
-}
-
-func (b *_HourSqlBuild) Build(hours []int) string {
-
- build := strings.Builder{}
- build.WriteString(b.start)
- build.WriteString("\nJOIN (")
- for i := range hours {
- if i > 0 {
- build.WriteString(" UNION ALL ")
- }
- build.WriteString("SELECT ")
- build.WriteString(strconv.Itoa(hours[i]))
- build.WriteString(" AS `hour`")
- }
- //build.WriteString("select 2019060921 AS `hour` UNION ALL select 2019060920")
- build.WriteString(") T ON 1=1")
- build.WriteString(b.end)
-
- return build.String()
-}
-
-func initSqlSelectStrategyByHour(fields []string) _HourSqlBuild {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- start := strings.Builder{}
- start.WriteString("SELECT")
- start.WriteString("\nT.`hour`,")
- start.WriteString("\nS.`strategyId` AS `strategyId`,")
- start.WriteString("\nS.`strategyName` AS `strategyName`,")
- start.WriteString("\nS.`enableStatus` AS `enableStatus`,")
-
- start.WriteString("\n")
- start.WriteString(strings.Join(sums, ",\n"))
- start.WriteString("\nFROM `goku_gateway_strategy` S")
-
- //build.WriteString("\nJOIN (select 2019060921 AS `hour` UNION ALL select 2019060920) T ON 1=1")
- end := strings.Builder{}
- end.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`strategyID` = S.`strategyID`")
- end.WriteString("\nAND T.`hour` = M.`hour` AND M.`clusterID` = ?")
- end.WriteString("\nGROUP by `strategyId`,`strategyName`,`enableStatus`,`hour`")
-
- return _HourSqlBuild{
- start: start.String(),
- end: end.String(),
- }
-}
-func initSqlSelectStrategyOfApiByHour(fields []string) _HourSqlBuild {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
-
- start := strings.Builder{}
- start.WriteString("SELECT")
- start.WriteString("\nT.`hour`,")
- start.WriteString("\nS.`strategyId` AS `strategyId`,")
- start.WriteString("\nS.`strategyName` AS `strategyName`,")
- start.WriteString("\nS.`enableStatus` AS `enableStatus`,")
- start.WriteString("\n")
- start.WriteString(strings.Join(sums, ",\n"))
- start.WriteString("\nFROM `goku_conn_strategy_api` SAPI ")
- start.WriteString("\nINNER JOIN `goku_gateway_strategy` S ON S.`strategyID` = SAPI.`strategyID` AND SAPI.`apiID` = ?")
- //build.WriteString("\nJOIN (select 2019060921 AS `hour` UNION ALL select 2019060920) T ON 1=1")
- end := strings.Builder{}
- end.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`strategyID` = SAPI.`strategyID`")
- end.WriteString("\nAND T.`hour` = M.`hour` AND `clusterID` = ?")
- end.WriteString("\nGROUP by `strategyId`,`strategyName`,`enableStatus`,`hour`")
- return _HourSqlBuild{
- start: start.String(),
- end: end.String(),
- }
-}
-
-func initSqlSelectAPIByHour(fields []string) _HourSqlBuild {
-
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- start := strings.Builder{}
- start.WriteString("SELECT")
- start.WriteString("\nT.`hour`,")
- start.WriteString("\nA.`apiID` AS `apiID`,")
- start.WriteString("\nA.`apiName` AS `apiName`,")
- start.WriteString("\nA.`requestURL` AS `requestURL`,")
- start.WriteString("\n")
- start.WriteString(strings.Join(sums, ",\n"))
- start.WriteString("\nFROM `goku_gateway_api` A")
-
- //build.WriteString("\nJOIN (select 2019060921 AS `hour` UNION ALL select 2019060920) T ON 1=1")
- end := strings.Builder{}
- end.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`apiID` = A.`apiID`")
- end.WriteString("\nAND T.`hour` = M.`hour` AND M.`clusterID` = ?")
- end.WriteString("\nGROUP by `apiID`,`apiName` ,`requestURL`,`hour`")
-
- return _HourSqlBuild{
- start: start.String(),
- end: end.String(),
- }
-}
-func initSqlSelectAPIOfStrategyByHour(fields []string) _HourSqlBuild {
- sums := make([]string, len(fields))
-
- for i := range fields {
- sums[i] = fmt.Sprintf("IFNULL(SUM(M.%s), 0) AS %s", fields[i], fields[i])
-
- }
- start := strings.Builder{}
- start.WriteString("SELECT")
- start.WriteString("\nT.`hour`,")
- start.WriteString("\nA.`apiID` AS `apiID`,")
- start.WriteString("\nA.`apiName` AS `apiName`,")
- start.WriteString("\nA.`requestURL` AS `requestURL`,")
- start.WriteString("\n")
- start.WriteString(strings.Join(sums, ",\n"))
- start.WriteString("\nFROM `goku_conn_strategy_api` SAPI ")
- start.WriteString("\nINNER JOIN `goku_gateway_api` A ON A.`apiID` = SAPI.`apiID` AND SAPI.`strategyID` = ?")
- //build.WriteString("\nJOIN (select 2019060921 AS `hour` UNION ALL select 2019060920) T ON 1=1")
- end := strings.Builder{}
- end.WriteString("\nLEFT JOIN `goku_monitor_cluster` M ON M.`apiID` = A.`apiID`")
- end.WriteString("\nAND T.`hour` = M.`hour` AND M.`clusterID` = ?")
- end.WriteString("\nGROUP by `apiID`,`apiName` ,`requestURL`,`hour`")
-
- return _HourSqlBuild{
- start: start.String(),
- end: end.String(),
- }
-}
diff --git a/server/dao/console-mysql/dao-monitor/sql_test.go b/server/dao/console-mysql/dao-monitor/sql_test.go
deleted file mode 100644
index 4c479ffd535676cff218151b45a2410823f842e1..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/dao-monitor/sql_test.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package dao_monitor
-
-import (
- "fmt"
- monitor_key "github.com/eolinker/goku-api-gateway/server/monitor/monitor-key"
- "testing"
-)
-
-func TestGenSql(t *testing.T) {
- keys := monitor_key.Keys()
- fields := make([]string, len(keys))
-
- for i := range keys {
- fields[i] = fmt.Sprintf("`%s`", keys[i].String())
- }
- fmt.Println("# save ")
- fmt.Println(genSqlSave(fields))
-
- fmt.Println("#全局")
- fmt.Println(genSqlSelectGateway(fields))
-
- fmt.Println("#全局 按小时")
- fmt.Println(genSqlSelectGatewayByHour(fields))
-
- fmt.Println("#API")
- fmt.Println(genSqlSelectAPI(fields))
-
- fmt.Println("#API 下 策略")
- fmt.Println(genSqlSelectStrategyOfApi(fields))
-
- fmt.Println("#策略")
- fmt.Println(genSqlSelectStrategy(fields))
-
- fmt.Println("#策略内API")
- fmt.Println(genSqlSelectApiOfStrategy(fields))
-}
diff --git a/server/dao/console-mysql/import.go b/server/dao/console-mysql/import.go
deleted file mode 100644
index 4e010d0bd35f6ef73dc21caaecfae4423e62e871..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/import.go
+++ /dev/null
@@ -1,296 +0,0 @@
-package consolemysql
-
-import (
- SQL "database/sql"
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "net/url"
- "strconv"
- "strings"
- "time"
-
- database2 "github.com/eolinker/goku-api-gateway/common/database"
- entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity"
-)
-
-var method = []string{"POST", "GET", "PUT", "DELETE", "HEAD", "OPTIONS", "PATCH"}
-
-// importAPIGroupInfo 导入分组信息
-func importAPIGroupInfo(Tx *SQL.Tx, groupName, groupPath string, parentGroupID, projectID, groupDepth int) (bool, int, string) {
- result, err := Tx.Exec("INSERT INTO goku_gateway_api_group (projectID,groupName,parentGroupID,groupDepth) VALUES (?,?,?,?);", projectID, groupName, parentGroupID, groupDepth)
- if err != nil {
- info := err.Error()
- log.Info(info)
- return false, 0, ""
- }
- groupID, err := result.LastInsertId()
- if err != nil {
- info := err.Error()
- log.Info(info)
- return false, 0, ""
- }
- id := int(groupID)
- groupPath = groupPath + "," + strconv.Itoa(id)
- // 更新groupPath
- _, err = Tx.Exec("UPDATE goku_gateway_api_group SET groupPath = ? WHERE groupID = ?;", groupPath, id)
- if err != nil {
- info := err.Error()
- log.Info(info)
- return false, 0, ""
- }
- return true, id, groupPath
-}
-
-// importAPIInfo 导入接口信息
-func importAPIInfo(Tx *SQL.Tx, api entity.AmsAPIInfo, projectID, groupID, userID int) bool {
- // 新增API
- requestURL := ""
- host := ""
- protocol := "http"
- u, err := url.ParseRequestURI(api.BaseInfo.APIURI)
- if err == nil {
- requestURL = u.Path
- if u.Scheme != "" {
- protocol = strings.ToLower(u.Scheme)
- if u.Host != "" {
- host = strings.ToLower(u.Host)
- }
- }
- } else {
- requestURL = api.BaseInfo.APIURI
- }
- stripSlash := true
- log.Debug(protocol, host, stripSlash)
- now := time.Now().Format("2006-01-02 15:04:05")
- requestMethod := method[api.BaseInfo.APIRequestType]
- _, err = Tx.Exec("INSERT INTO goku_gateway_api (projectID,groupID,apiName,requestURL,targetURL,requestMethod,targetMethod,isFollow,stripPrefix,timeout,retryCount,createTime,updateTime,managerID,lastUpdateUserID,createUserID,protocol,balanceName,stripSlash) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", projectID, groupID, api.BaseInfo.APIName, requestURL, requestURL, requestMethod, requestMethod, "true", "true", 2000, 0, now, now, userID, userID, userID, protocol, host, stripSlash)
- if err != nil {
- log.Error(err)
- return false
- }
- return true
-}
-
-//ImportAPIGroupFromAms 导入接口分组
-func ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) (bool, string, error) {
- db := database2.GetConnection()
- Tx, _ := db.Begin()
- now := time.Now().Format("2006-01-02 15:04:05")
- // 插入分组信息
- result, err := Tx.Exec("INSERT INTO goku_gateway_api_group (projectID,groupName,groupDepth) VALUES (?,?,1);", projectID, groupInfo.GroupName)
- if err != nil {
- Tx.Rollback()
- info := err.Error()
- log.Info(info)
- }
- groupID, err := result.LastInsertId()
- if err != nil {
- Tx.Rollback()
- info := err.Error()
- log.Info(info)
- }
- groupPath := strconv.Itoa(int(groupID))
- // 更新groupPath
- _, err = Tx.Exec("UPDATE goku_gateway_api_group SET groupPath = ? WHERE groupID = ?;", groupPath, groupID)
- if err != nil {
- Tx.Rollback()
- info := err.Error()
- log.Info(info)
- }
- // 插入子分组信息
- for _, value := range groupInfo.ChildGroupList {
- flag, secGroupID, secgroupPath := importAPIGroupInfo(Tx, value.GroupName, groupPath, int(groupID), projectID, 2)
- if !flag {
- continue
- }
- for _, v := range value.ChildGroupList {
- flag, thirdGroupID, thirdgroupPath := importAPIGroupInfo(Tx, v.GroupName, secgroupPath, secGroupID, projectID, 3)
- if !flag {
- continue
- }
- for _, vv := range v.ChildGroupList {
- flag, fourthGroupID, fourthgroupPath := importAPIGroupInfo(Tx, vv.GroupName, thirdgroupPath, thirdGroupID, projectID, 4)
- if !flag {
- continue
- }
- for _, vvv := range vv.ChildGroupList {
- flag, fifthGroupID, _ := importAPIGroupInfo(Tx, vvv.GroupName, fourthgroupPath, fourthGroupID, projectID, 5)
- if !flag {
- continue
- }
- for _, aaa := range vvv.APIList {
- flag = importAPIInfo(Tx, aaa, projectID, fifthGroupID, userID)
- if !flag {
- continue
- }
- }
- }
- for _, aa := range vv.APIList {
- flag = importAPIInfo(Tx, aa, projectID, fourthGroupID, userID)
- if !flag {
- continue
- }
- }
- }
- for _, a := range v.APIList {
- flag = importAPIInfo(Tx, a, projectID, thirdGroupID, userID)
- if !flag {
- continue
- }
- }
- }
- for _, api := range value.APIList {
- flag := importAPIInfo(Tx, api, projectID, secGroupID, userID)
- if !flag {
- continue
- }
- }
- }
- for _, apiInfo := range groupInfo.APIList {
- flag := importAPIInfo(Tx, apiInfo, projectID, int(groupID), userID)
- if !flag {
- continue
- }
- }
- // 更新项目更新时间
- _, err = Tx.Exec("UPDATE goku_gateway_project SET updateTime = ? WHERE projectID = ?;", now, projectID)
- if err != nil {
- Tx.Rollback()
- return false, "[ERROR]Fail to update data!", err
- }
- Tx.Commit()
- return true, "", nil
-}
-
-// ImportProjectFromAms 导入项目
-func ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, string, error) {
- db := database2.GetConnection()
- Tx, _ := db.Begin()
- now := time.Now().Format("2006-01-02 15:04:05")
- // 插入项目信息
- projectResult, err := Tx.Exec("INSERT INTO goku_gateway_project (projectName,updateTime,createTime) VALUES (?,?,?)", projectInfo.ProjectInfo.ProjectName, now, now)
- if err != nil {
- Tx.Rollback()
- log.Info(err.Error())
- }
- projectID, err := projectResult.LastInsertId()
- if err != nil {
- Tx.Rollback()
- log.Info(err.Error())
- }
- id := int(projectID)
- for _, groupInfo := range projectInfo.APIGroupList {
- // 插入分组信息
- result, err := Tx.Exec("INSERT INTO goku_gateway_api_group (projectID,groupName,groupDepth) VALUES (?,?,1);", projectID, groupInfo.GroupName)
- if err != nil {
- Tx.Rollback()
- log.Info(err.Error())
- }
- groupID, err := result.LastInsertId()
- if err != nil {
- Tx.Rollback()
- log.Info(err.Error())
- }
- groupPath := strconv.Itoa(int(groupID))
- // 更新groupPath
- _, err = Tx.Exec("UPDATE goku_gateway_api_group SET groupPath = ? WHERE groupID = ?;", groupPath, groupID)
- if err != nil {
- Tx.Rollback()
- info := err.Error()
- log.Info(info)
- }
-
- // 插入子分组信息
- for _, value := range groupInfo.APIGroupChildList {
- flag, secGroupID, secgroupPath := importAPIGroupInfo(Tx, value.GroupName, groupPath, int(groupID), id, 2)
- if !flag {
- continue
- }
- for _, v := range value.APIGroupChildList {
- flag, thirdGroupID, thirdgroupPath := importAPIGroupInfo(Tx, v.GroupName, secgroupPath, secGroupID, id, 3)
- if !flag {
- continue
- }
- for _, vv := range v.APIGroupChildList {
- flag, fourthGroupID, fourthgroupPath := importAPIGroupInfo(Tx, vv.GroupName, thirdgroupPath, thirdGroupID, id, 4)
- if !flag {
- continue
- }
- for _, vvv := range vv.APIGroupChildList {
- flag, fifthGroupID, _ := importAPIGroupInfo(Tx, vvv.GroupName, fourthgroupPath, fourthGroupID, id, 5)
- if !flag {
- continue
- }
- for _, aaa := range v.APIList {
- flag = importAPIInfo(Tx, aaa, id, fifthGroupID, userID)
- if !flag {
- continue
- }
- }
- }
- for _, aa := range v.APIList {
- flag = importAPIInfo(Tx, aa, id, fourthGroupID, userID)
- if !flag {
- continue
- }
- }
- }
- for _, a := range v.APIList {
- flag = importAPIInfo(Tx, a, id, thirdGroupID, userID)
- if !flag {
- continue
- }
- }
- }
- for _, api := range value.APIList {
- flag = importAPIInfo(Tx, api, id, secGroupID, userID)
- if !flag {
- continue
- }
- }
- }
- for _, apiInfo := range groupInfo.APIList {
- flag := importAPIInfo(Tx, apiInfo, id, int(groupID), userID)
- if !flag {
- continue
- }
- }
- }
- Tx.Commit()
- return true, "", nil
-}
-
-//ImportAPIFromAms 导入接口
-func ImportAPIFromAms(projectID, groupID, userID int, apiList []entity.AmsAPIInfo) (bool, string, error) {
- db := database2.GetConnection()
- Tx, _ := db.Begin()
- now := time.Now().Format("2006-01-02 15:04:05")
- for _, apiInfo := range apiList {
- // 新增API
- requestURL := ""
- host := ""
- u, err := url.ParseRequestURI(apiInfo.BaseInfo.APIURI)
- if err == nil {
- requestURL = u.Path
- if u.Scheme != "" && u.Host != "" {
- host = u.Scheme + "://" + u.Host
- }
- } else {
- requestURL = apiInfo.BaseInfo.APIURI
- }
- now = time.Now().Format("2006-01-02 15:04:05")
- requestMethod := method[apiInfo.BaseInfo.APIRequestType]
- _, err = Tx.Exec("INSERT INTO goku_gateway_api (projectID,groupID,apiName,requestURL,targetURL,requestMethod,targetServer,targetMethod,isFollow,stripPrefix,timeout,retryCount,createTime,updateTime,managerID,lastUpdateUserID,createUserID) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", projectID, groupID, apiInfo.BaseInfo.APIName, requestURL, requestURL, requestMethod, host, requestMethod, "true", "true", 2000, 0, now, now, userID, userID, userID)
- if err != nil {
- Tx.Rollback()
- log.Info(err.Error())
- }
- }
- // 更新项目更新时间
- _, err := Tx.Exec("UPDATE goku_gateway_project SET updateTime = ? WHERE projectID = ?;", now, projectID)
- if err != nil {
- Tx.Rollback()
- return false, "[ERROR]Fail to update data!", err
- }
- Tx.Commit()
- return true, "", nil
-}
diff --git a/server/dao/console-mysql/redis.go b/server/dao/console-mysql/redis.go
deleted file mode 100644
index 4969a27f5af86f40b3984796f6ffd76cc2d88cc8..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/redis.go
+++ /dev/null
@@ -1,106 +0,0 @@
-package consolemysql
-
-import (
- database2 "github.com/eolinker/goku-api-gateway/common/database"
- "github.com/eolinker/goku-api-gateway/common/general"
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "github.com/eolinker/goku-api-gateway/server/entity/console-entity"
- "strings"
-)
-
-func init() {
- general.RegeditLater(CreateTable)
-}
-
-//GetServers 获取redis服务列表
-func GetServers(clusterID int) ([]*entity.RedisNode, error) {
-
- db := database2.GetConnection()
- rows, err := db.Query("SELECT `server`,`password`,`clusterID` from `goku_redis_server` WHERE `clusterID`=?;", clusterID)
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
-
- servers := make([]*entity.RedisNode, 0)
- for rows.Next() {
- node := new(entity.RedisNode)
- err := rows.Scan(&node.Server, &node.Password, &node.ClusterID)
-
- if err != nil {
- return nil, err
- }
- servers = append(servers, node)
- }
- return servers, nil
-}
-
-// GetRedisCount 获取redis数量
-func GetRedisCount() (int, int) {
- sql := "SELECT status,COUNT(*) FROM goku_redis_server GROUP BY status;"
- rows, err := database2.GetConnection().Query(sql)
- if err != nil {
- return 0, 0
- }
- var normalCount, errorCount int
- defer rows.Close()
- for rows.Next() {
- var status, count int
- err := rows.Scan(&status, &count)
- if err != nil {
- return 0, 0
- }
- if status == 0 {
- normalCount = count
- } else {
- errorCount = count
- }
- }
- return normalCount, errorCount
-}
-
-//CreateTable 创建表
-func CreateTable() error {
- sqlDatas := []string{
-
- `CREATE TABLE IF NOT EXISTS '''goku_redis_info''' (
- '''id''' int(11) unsigned NOT NULL AUTO_INCREMENT,
- '''server''' varchar(20) NOT NULL COMMENT 'ip:port',
- '''info''' text NOT NULL COMMENT 'info,json',
- '''datetime''' timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY ('''id'''),
- KEY '''server''' ('''server''')
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;`,
- `CREATE TABLE IF NOT EXISTS '''goku_redis_memory''' (
- '''id''' int(11) unsigned NOT NULL AUTO_INCREMENT,
- '''server''' varchar(20) DEFAULT NULL COMMENT 'ip:port',
- '''used''' int(11) DEFAULT NULL,
- '''peak''' int(11) DEFAULT NULL,
- '''datetime''' timestamp NULL DEFAULT NULL,
- PRIMARY KEY ('''id'''),
- KEY '''server''' ('''server''')
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;`,
- `CREATE TABLE IF NOT EXISTS '''goku_redis_server''' (
- '''id''' INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
- '''server''' VARCHAR(20) NOT NULL DEFAULT '' COMMENT 'ip:port',
- '''password''' VARCHAR(20) DEFAULT NULL,
- '''clusterID''' INT(11) DEFAULT '1',
- '''status''' INT(11) DEFAULT NULL,
- PRIMARY KEY ('''id'''),
- UNIQUE KEY '''server''' ('''server''','''clusterID'''),
- KEY '''clusterID''' ('''clusterID'''),
- KEY '''status''' ('''status''')
-) ENGINE=INNODB AUTO_INCREMENT=224 DEFAULT CHARSET=utf8;`}
- for _, sql := range sqlDatas {
- sqlData := strings.ReplaceAll(sql, "'''", "`")
- db := database2.GetConnection()
- _, err := db.Exec(sqlData)
- if err != nil {
- log.Info(err.Error())
- return err
- }
- }
-
- return nil
-}
diff --git a/server/dao/console-mysql/redis_test.go b/server/dao/console-mysql/redis_test.go
deleted file mode 100644
index 61e6c368e7512a73be197e61908bfad1fdca436f..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/redis_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package consolemysql
diff --git a/server/dao/console-mysql/script.go b/server/dao/console-mysql/script.go
deleted file mode 100644
index 12a877c31a8800bd145968a244cd96964758c8ae..0000000000000000000000000000000000000000
--- a/server/dao/console-mysql/script.go
+++ /dev/null
@@ -1,105 +0,0 @@
-package consolemysql
-
-import (
- "encoding/json"
- database2 "github.com/eolinker/goku-api-gateway/common/database"
- log "github.com/eolinker/goku-api-gateway/goku-log"
-)
-
-type balanceConfig struct {
- LoadBalancingServer []server `json:"loadBalancingServer"`
-}
-
-type server struct {
- Server string `json:"server"`
- Weight int `json:"weight"`
-}
-
-// RefreshGatewayAlertConfig 新建项目
-func RefreshGatewayAlertConfig() bool {
- db := database2.GetConnection()
- var (
- alertAddr string
- alertLogPath string
- alertPeriodType int
- receiverList string
- )
- // 获取网关告警配置
- sqlCode := `SELECT alertAddress,alertLogPath,alertPeriodType,receiverList FROM goku_gateway;`
- err := db.QueryRow(sqlCode).Scan(&alertAddr, &alertLogPath, &alertPeriodType, &receiverList)
- if err != nil {
- log.Error(err)
- return false
- }
- if alertLogPath == "" {
- alertLogPath = "./log/apiAlert"
- }
- // 构造告警需要的信息
- apiAlertInfo := map[string]interface{}{
- "alertPeriodType": alertPeriodType,
- "receiverList": receiverList,
- "alertAddr": alertAddr,
- }
- nodeAlertInfo := map[string]interface{}{
- "receiverList": receiverList,
- "alertAddr": alertAddr,
- }
- redisAlertInfo := map[string]interface{}{
- "receiverList": receiverList,
- "alertAddr": alertAddr,
- }
- apiAlertInfoByte, err := json.Marshal(apiAlertInfo)
- if err != nil {
- log.Error(err)
- return false
- }
- nodeAlertInfoByte, err := json.Marshal(nodeAlertInfo)
- if err != nil {
- log.Error(err)
- return false
- }
- redisAlertInfoByte, err := json.Marshal(redisAlertInfo)
- if err != nil {
- log.Error(err)
- return false
- }
- Tx, _ := db.Begin()
-
- _, err = Tx.Exec("UPDATE goku_gateway SET apiAlertInfo = ?,nodeAlertInfo = ?,redisAlertInfo = ?;", string(apiAlertInfoByte), string(nodeAlertInfoByte), string(redisAlertInfoByte))
- if err != nil {
- Tx.Rollback()
- log.Error(err)
- return false
- }
- dropColomn := []string{"alertPeriodType", "alertAddress", "alertLogPath", "receiverList"}
- for _, colomn := range dropColomn {
- sql := "ALTER TABLE goku_gateway DROP COLUMN " + colomn + ";"
- log.Debug("RefreshGatewayAlertConfig-sql:", sql)
- _, err = Tx.Exec(sql)
- if err != nil {
- Tx.Rollback()
- log.Error(err)
- return false
- }
- }
- Tx.Commit()
- return true
-}
-
-type monitorRecord struct {
- gatewayRequestCount int
- gatewaySuccessCount int
- gatewayStatus2xxCount int
- gatewayStatus4xxCount int
- gatewayStatus5xxCount int
- proxyRequestCount int
- proxySuccessCount int
- proxyStatus2xxCount int
- proxyStatus4xxCount int
- proxyStatus5xxCount int
- proxyTimeoutCount int
- updateTime string
- hour string
- strategyID string
- apiID int
-}
diff --git a/server/dao/console-mysql/api.go b/server/dao/console-sqlite3/api.go
similarity index 78%
rename from server/dao/console-mysql/api.go
rename to server/dao/console-sqlite3/api.go
index 87402815bdf0bec3d6fb034467654a5d561e7ef2..6a8cbb67aa7c7f38769dac026a16c7351be20ff5 100644
--- a/server/dao/console-mysql/api.go
+++ b/server/dao/console-sqlite3/api.go
@@ -1,7 +1,8 @@
-package consolemysql
+package console_sqlite3
import (
SQL "database/sql"
+ "encoding/json"
"fmt"
"strconv"
"strings"
@@ -12,11 +13,11 @@ import (
)
// AddAPI 新增接口
-func AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, stripPrefix, stripSlash, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID int) (bool, int, error) {
+func AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType int) (bool, int, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
Tx, _ := db.Begin()
- res, err := Tx.Exec("INSERT INTO goku_gateway_api (projectID,groupID,apiName,requestURL,targetURL,requestMethod,targetMethod,protocol,stripSlash,balanceName,isFollow,stripPrefix,timeout,retryCount,alertValve,createTime,updateTime,managerID,lastUpdateUserID,createUserID) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", projectID, groupID, apiName, requestURL, targetURL, requestMethod, targetMethod, protocol, stripSlash, balanceName, isFollow, stripPrefix, timeout, retryCount, alertValve, now, now, managerID, userID, userID)
+ res, err := Tx.Exec("INSERT INTO goku_gateway_api (projectID,groupID,apiName,requestURL,targetURL,requestMethod,targetMethod,protocol,linkAPIs,staticResponse,responseDataType,balanceName,isFollow,timeout,retryCount,alertValve,createTime,updateTime,managerID,lastUpdateUserID,createUserID,apiType) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", projectID, groupID, apiName, requestURL, targetURL, requestMethod, targetMethod, protocol, linkAPIs, staticResponse, responseDataType, balanceName, isFollow, timeout, retryCount, alertValve, now, now, managerID, userID, userID, apiType)
if err != nil {
Tx.Rollback()
@@ -33,12 +34,12 @@ func AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollo
return true, int(apiID), nil
}
-// EditAPI 新增接口
-func EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, stripPrefix, stripSlash, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) {
+// EditAPI 修改接口
+func EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
Tx, _ := db.Begin()
- _, err := Tx.Exec("UPDATE goku_gateway_api SET projectID = ?,groupID = ?,apiName = ?,requestURL = ?,targetURL = ?,requestMethod = ?,protocol = ?,balanceName = ?,targetMethod = ?,isFollow = ?,stripPrefix = ?,stripSlash = ?,timeout = ?,retryCount = ?,alertValve = ?,updateTime = ?,managerID = ?,lastUpdateUserID = ? WHERE apiID = ?", projectID, groupID, apiName, requestURL, targetURL, requestMethod, protocol, balanceName, targetMethod, isFollow, stripPrefix, stripSlash, timeout, retryCount, alertValve, now, managerID, userID, apiID)
+ _, err := Tx.Exec("UPDATE goku_gateway_api SET projectID = ?,groupID = ?,apiName = ?,requestURL = ?,targetURL = ?,requestMethod = ?,protocol = ?,balanceName = ?,targetMethod = ?,isFollow = ?,linkAPIs = ?,staticResponse = ?,responseDataType = ?,timeout = ?,retryCount = ?,alertValve = ?,updateTime = ?,managerID = ?,lastUpdateUserID = ? WHERE apiID = ?", projectID, groupID, apiName, requestURL, targetURL, requestMethod, protocol, balanceName, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, timeout, retryCount, alertValve, now, managerID, userID, apiID)
if err != nil {
Tx.Rollback()
@@ -57,15 +58,15 @@ func EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFoll
// GetAPIInfo 获取接口信息
func GetAPIInfo(apiID int) (bool, *entity.API, error) {
db := database2.GetConnection()
- sql := `SELECT goku_gateway_api.apiID,goku_gateway_api.groupID,goku_gateway_api.apiName,goku_gateway_api.requestURL,goku_gateway_api.targetURL,goku_gateway_api.requestMethod,goku_gateway_api.targetMethod,IFNULL(goku_gateway_api.protocol,"http"),goku_gateway_api.stripSlash,IFNULL(goku_gateway_api.balanceName,""),goku_gateway_api.isFollow,goku_gateway_api.stripPrefix,goku_gateway_api.timeout,goku_gateway_api.retryCount,goku_gateway_api.alertValve,goku_gateway_api.createTime,goku_gateway_api.updateTime,goku_gateway_api.managerID,goku_gateway_api.lastUpdateUserID,goku_gateway_api.createUserID,IFNULL(goku_gateway_api_group.groupPath,"0") FROM goku_gateway_api LEFT JOIN goku_gateway_api_group ON goku_gateway_api.groupID = goku_gateway_api_group.groupID WHERE goku_gateway_api.apiID = ?`
+ sql := `SELECT goku_gateway_api.apiID,goku_gateway_api.groupID,goku_gateway_api.apiName,goku_gateway_api.requestURL,goku_gateway_api.targetURL,goku_gateway_api.requestMethod,goku_gateway_api.targetMethod,IFNULL(goku_gateway_api.protocol,"http"),IFNULL(goku_gateway_api.balanceName,""),goku_gateway_api.isFollow,goku_gateway_api.timeout,goku_gateway_api.retryCount,goku_gateway_api.alertValve,goku_gateway_api.createTime,goku_gateway_api.updateTime,goku_gateway_api.managerID,goku_gateway_api.lastUpdateUserID,goku_gateway_api.createUserID,IFNULL(goku_gateway_api_group.groupPath,"0"),goku_gateway_api.apiType,IFNULL(goku_gateway_api.linkAPIs,''),IFNULL(goku_gateway_api.staticResponse,''),IFNULL(goku_gateway_api.responseDataType,'origin') FROM goku_gateway_api LEFT JOIN goku_gateway_api_group ON goku_gateway_api.groupID = goku_gateway_api_group.groupID WHERE goku_gateway_api.apiID = ?`
api := &entity.API{}
var managerInfo entity.ManagerInfo
- err := db.QueryRow(sql, apiID).Scan(&api.APIID, &api.GroupID, &api.APIName, &api.RequestURL, &api.ProxyURL, &api.RequestMethod, &api.TargetMethod, &api.Protocol, &api.StripSlash, &api.BalanceName, &api.IsFollow, &api.StripPrefix, &api.Timeout, &api.RetryConut, &api.Valve, &api.CreateTime, &api.UpdateTime, &managerInfo.ManagerID, &managerInfo.UpdaterID, &managerInfo.CreateUserID, &api.GroupPath)
+ var linkAPIs string
+ err := db.QueryRow(sql, apiID).Scan(&api.APIID, &api.GroupID, &api.APIName, &api.RequestURL, &api.ProxyURL, &api.RequestMethod, &api.TargetMethod, &api.Protocol, &api.BalanceName, &api.IsFollow, &api.Timeout, &api.RetryConut, &api.Valve, &api.CreateTime, &api.UpdateTime, &managerInfo.ManagerID, &managerInfo.UpdaterID, &managerInfo.CreateUserID, &api.GroupPath, &api.APIType, &linkAPIs, &api.StaticResponse, &api.ResponseDataType)
if err != nil {
- panic(err)
return false, &entity.API{}, err
}
-
+ json.Unmarshal([]byte(linkAPIs), &api.LinkAPIs)
api.RequestMethod = strings.ToUpper(api.RequestMethod)
sql = `SELECT IFNULL(remark,loginCall) as userName FROM goku_admin WHERE userID = ?;`
@@ -91,7 +92,7 @@ func GetAPIInfo(apiID int) (bool, *entity.API, error) {
return true, api, nil
}
-// GetAPIListByGroupList 通过分组列表获取接口列表
+//GetAPIListByGroupList 通过分组列表获取接口列表
func GetAPIListByGroupList(projectID int, groupIDList string) (bool, []map[string]interface{}, error) {
db := database2.GetConnection()
// 获取分组ID列表
@@ -104,9 +105,7 @@ func GetAPIListByGroupList(projectID int, groupIDList string) (bool, []map[strin
defer rows.Close()
apiList := make([]map[string]interface{}, 0)
//获取记录列
- if _, err = rows.Columns(); err != nil {
- return false, make([]map[string]interface{}, 0), err
- }
+
for rows.Next() {
var apiID, updaterID, managerID int
var apiName, requestURL, updateTime, managerName, updaterName string
@@ -217,7 +216,6 @@ func GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids
sql := fmt.Sprintf(`SELECT A.apiID FROM goku_gateway_api A %s`, ruleStr)
rows, err := db.Query(sql)
if err != nil {
- panic(err)
return false, make([]int, 0), err
}
defer rows.Close()
@@ -267,22 +265,21 @@ func GetAPIList(projectID int, groupID int, keyword string, condition, page, pag
ruleStr += "WHERE " + strings.Join(rule, " AND ")
}
- sql := fmt.Sprintf(`SELECT A.apiID,A.apiName,A.requestURL,A.requestMethod,A.targetURL,IFNULL(A.balanceName,''),IFNULL(A.updateTime,""),IF(B.remark is null or B.remark = "",B.loginCall,B.remark) AS updaterName,IF(C.remark is null or C.remark = "",C.loginCall,C.remark) AS managerName,A.lastUpdateUserID,A.managerID,A.isFollow,IFNULL(A.protocol,"http"),A.targetMethod,A.groupID,IFNULL(D.groupPath,"0"),IFNULL(D.groupName,"未分组") FROM goku_gateway_api A INNER JOIN goku_admin B ON A.lastUpdateUserID = B.userID INNER JOIN goku_admin C ON A.managerID=C.userID LEFT JOIN goku_gateway_api_group D ON D.groupID = A.groupID %s`, ruleStr)
+ sql := fmt.Sprintf(`SELECT A.apiID,A.apiName,A.requestURL,A.requestMethod,CASE WHEN A.apiType=0 THEN A.targetURL ELSE '' END,A.apiType,IFNULL(A.balanceName,''),IFNULL(A.updateTime,""),CASE WHEN B.remark is null or B.remark = "" THEN B.loginCall ELSE B.remark END AS updaterName,CASE WHEN C.remark is null or C.remark = "" THEN C.loginCall ELSE C.remark END AS managerName,A.lastUpdateUserID,A.managerID,A.isFollow,IFNULL(A.protocol,"http"),A.targetMethod,A.groupID,IFNULL(D.groupPath,"0"),IFNULL(D.groupName,"未分组") FROM goku_gateway_api A INNER JOIN goku_admin B ON A.lastUpdateUserID = B.userID INNER JOIN goku_admin C ON A.managerID=C.userID LEFT JOIN goku_gateway_api_group D ON D.groupID = A.groupID %s`, ruleStr)
count := getCountSQL(sql)
rows, err := getPageSQL(sql, "A.updateTime", "DESC", page, pageSize)
if err != nil {
- panic(err)
return false, make([]map[string]interface{}, 0), 0, err
}
defer rows.Close()
apiList := make([]map[string]interface{}, 0)
//获取记录列
for rows.Next() {
- var apiID, updaterID, managerID, groupID int
+ var apiID, updaterID, managerID, groupID, apiType int
var apiName, requestURL, updateTime, managerName, updaterName, requestMethod, targetURL, balanceName, targetMethod, protocol, groupPath, groupName string
var isFollow bool
- err = rows.Scan(&apiID, &apiName, &requestURL, &requestMethod, &targetURL, &balanceName, &updateTime, &updaterName, &managerName, &updaterID, &managerID, &isFollow, &protocol, &targetMethod, &groupID, &groupPath, &groupName)
+ err = rows.Scan(&apiID, &apiName, &requestURL, &requestMethod, &targetURL, &apiType, &balanceName, &updateTime, &updaterName, &managerName, &updaterID, &managerID, &isFollow, &protocol, &targetMethod, &groupID, &groupPath, &groupName)
if err != nil {
return false, make([]map[string]interface{}, 0), 0, err
}
@@ -302,13 +299,14 @@ func GetAPIList(projectID int, groupID int, keyword string, condition, page, pag
"groupID": groupID,
"groupPath": groupPath,
"groupName": groupName,
+ "apiType": apiType,
}
apiList = append(apiList, apiInfo)
}
return true, apiList, count, nil
}
-// CheckURLIsExist 接口路径是否存在
+//CheckURLIsExist 接口路径是否存在
func CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) bool {
db := database2.GetConnection()
var id int
@@ -333,7 +331,7 @@ func CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) boo
return false
}
-// CheckAPIIsExist CheckAPIIsExist 检查接口是否存在
+//CheckAPIIsExist 检查接口是否存在
func CheckAPIIsExist(apiID int) (bool, error) {
db := database2.GetConnection()
sql := "SELECT apiID FROM goku_gateway_api WHERE apiID = ?;"
@@ -345,7 +343,7 @@ func CheckAPIIsExist(apiID int) (bool, error) {
return true, err
}
-// BatchEditAPIBalance 批量修改接口负载
+//BatchEditAPIBalance 批量修改接口负载
func BatchEditAPIBalance(apiIDList []string, balance string) (string, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
@@ -365,7 +363,7 @@ func BatchEditAPIBalance(apiIDList []string, balance string) (string, error) {
return "", nil
}
-// BatchEditAPIGroup 批量修改接口分组
+//BatchEditAPIGroup 批量修改接口分组
func BatchEditAPIGroup(apiIDList []string, groupID int) (string, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
@@ -385,7 +383,7 @@ func BatchEditAPIGroup(apiIDList []string, groupID int) (string, error) {
}
-// BatchDeleteAPI 批量修改接口
+//BatchDeleteAPI 批量修改接口
func BatchDeleteAPI(apiIDList string) (bool, string, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
diff --git a/server/dao/console-mysql/apiGroup.go b/server/dao/console-sqlite3/apiGroup.go
similarity index 62%
rename from server/dao/console-mysql/apiGroup.go
rename to server/dao/console-sqlite3/apiGroup.go
index 2b65ee028f6139c06c1dfde693b06c6d2ed7bd2a..023143eda7deb216ac5dbe0e3fb64dff56b81bf2 100644
--- a/server/dao/console-mysql/apiGroup.go
+++ b/server/dao/console-sqlite3/apiGroup.go
@@ -1,4 +1,4 @@
-package consolemysql
+package console_sqlite3
import (
SQL "database/sql"
@@ -6,10 +6,9 @@ import (
"time"
database2 "github.com/eolinker/goku-api-gateway/common/database"
- log "github.com/eolinker/goku-api-gateway/goku-log"
)
-// AddAPIGroup 新建接口分组
+//AddAPIGroup 新建接口分组
func AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interface{}, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
@@ -49,7 +48,7 @@ func AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interfac
groupPath = strconv.Itoa(int(groupID))
} else {
groupDepth = groupDepth + 1
- groupPath = groupPath + "," + strconv.Itoa(int(groupID))
+ groupPath += "," + strconv.Itoa(int(groupID))
}
// 更新groupDepth和groupPath
@@ -69,7 +68,7 @@ func AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interfac
return true, groupID, nil
}
-// EditAPIGroup 修改接口分组
+//EditAPIGroup 修改接口分组
func EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
@@ -90,7 +89,7 @@ func EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error
return true, "", nil
}
-// DeleteAPIGroup 删除接口分组
+//DeleteAPIGroup 删除接口分组
func DeleteAPIGroup(projectID, groupID int) (bool, string, error) {
db := database2.GetConnection()
Tx, _ := db.Begin()
@@ -152,12 +151,7 @@ func DeleteAPIGroup(projectID, groupID int) (bool, string, error) {
Tx.Rollback()
return false, "[ERROR]Fail to delete data!", err
}
- //sql = "DELETE FROM goku_conn_plugin_api_cache WHERE apiID IN (" + apiIDList + ");"
- //_, err = Tx.Exec(sql)
- //if err != nil {
- // Tx.Rollback()
- // return false, "[ERROR]Fail to delete data!", err
- //}
+
}
}
now := time.Now().Format("2006-01-02 15:04:05")
@@ -172,7 +166,7 @@ func DeleteAPIGroup(projectID, groupID int) (bool, string, error) {
return true, "", nil
}
-// GetAPIGroupList 获取接口分组列表
+//GetAPIGroupList 获取接口分组列表
func GetAPIGroupList(projectID int) (bool, []map[string]interface{}, error) {
db := database2.GetConnection()
sql := "SELECT groupID,groupName,parentGroupID,groupDepth FROM goku_gateway_api_group WHERE projectID = ?;"
@@ -182,11 +176,7 @@ func GetAPIGroupList(projectID int) (bool, []map[string]interface{}, error) {
}
defer rows.Close()
//获取记录列
- if _, err = rows.Columns(); err != nil {
- info := err.Error()
- log.Info(info)
- return false, make([]map[string]interface{}, 0), err
- }
+
groupList := make([]map[string]interface{}, 0)
for rows.Next() {
var groupID, parentGroupID, groupDepth int
@@ -205,92 +195,3 @@ func GetAPIGroupList(projectID int) (bool, []map[string]interface{}, error) {
}
return true, groupList, nil
}
-
-// UpdateAPIGroupScript 更新接口分组脚本
-func UpdateAPIGroupScript() bool {
- db := database2.GetConnection()
- // 获取一级分组
- sql := "SELECT groupID,groupName,parentGroupID FROM goku_gateway_api_group WHERE isChild = ?;"
- rows, err := db.Query(sql, 0)
- if err != nil {
- return false
- }
- defer rows.Close()
- //获取记录列
- if _, err = rows.Columns(); err != nil {
- return false
- }
- groupList := make([]map[string]interface{}, 0)
- for rows.Next() {
- var groupID, parentGroupID int
- var groupName, groupPath string
- err = rows.Scan(&groupID, &groupName, &parentGroupID)
- if err != nil {
- return false
- }
- sql = "SELECT groupID,groupName,parentGroupID FROM goku_gateway_api_group WHERE isChild = ? AND parentGroupID = ?;"
- r, err := db.Query(sql, 1, groupID)
- if err != nil {
- return false
- }
- groupPath = strconv.Itoa(groupID)
- defer r.Close()
-
- for r.Next() {
- var childGroupID, childParentGroupID int
- var childGroupName, childGroupPath string
- err = r.Scan(&childGroupID, &childGroupName, &childParentGroupID)
- if err != nil {
- return false
- }
- childGroupPath = groupPath + "," + strconv.Itoa(childGroupID)
- sql = "SELECT groupID,groupName,parentGroupID FROM goku_gateway_api_group WHERE isChild = ? AND parentGroupID = ?;"
- rw, err := db.Query(sql, 2, childGroupID)
- if err != nil {
- return false
- }
- defer rw.Close()
- for rw.Next() {
- var secChildGroupID, secChildParentGroupID int
- var secChildGroupName, secChildGroupPath string
- err = rw.Scan(&secChildGroupID, &secChildGroupName, &secChildParentGroupID)
- if err != nil {
- return false
- }
- secChildGroupPath = childGroupPath + "," + strconv.Itoa(secChildGroupID)
- groupList = append(groupList, map[string]interface{}{
- "groupID": secChildGroupID,
- "groupName": secChildGroupName,
- "groupDepth": 3,
- "parentGroupID": secChildParentGroupID,
- "groupPath": secChildGroupPath,
- })
- }
- groupList = append(groupList, map[string]interface{}{
- "groupID": childGroupID,
- "groupName": childGroupName,
- "groupDepth": 2,
- "parentGroupID": childParentGroupID,
- "groupPath": childGroupPath,
- })
- }
- groupInfo := map[string]interface{}{
- "groupID": groupID,
- "groupName": groupName,
- "groupDepth": 1,
- "parentGroupID": parentGroupID,
- "groupPath": groupPath,
- }
- groupList = append(groupList, groupInfo)
- }
- Tx, _ := db.Begin()
- for _, groupInfo := range groupList {
- _, err = Tx.Exec("UPDATE goku_gateway_api_group SET groupPath = ?,groupDepth =? WHERE groupID = ?;", groupInfo["groupPath"].(string), groupInfo["groupDepth"].(int), groupInfo["groupID"].(int))
- if err != nil {
- Tx.Rollback()
-
- }
- }
- Tx.Commit()
- return true
-}
diff --git a/server/dao/console-mysql/apiPlugin.go b/server/dao/console-sqlite3/apiPlugin.go
similarity index 82%
rename from server/dao/console-mysql/apiPlugin.go
rename to server/dao/console-sqlite3/apiPlugin.go
index 58b860ecafef2a67596c5b196668be54ff0a2bca..ec4e4f81d661463a5529b8ebf4c61595cfa8c552 100644
--- a/server/dao/console-mysql/apiPlugin.go
+++ b/server/dao/console-sqlite3/apiPlugin.go
@@ -1,4 +1,4 @@
-package consolemysql
+package console_sqlite3
import (
SQL "database/sql"
@@ -15,7 +15,7 @@ import (
var apiPlugins = []string{"goku-proxy_caching", "goku-circuit_breaker"}
-// AddPluginToAPI 新增插件到接口
+//AddPluginToAPI 新增接口插件
func AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) {
db := database2.GetConnection()
// 查询接口是否添加该插件
@@ -43,7 +43,7 @@ func AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (b
return true, int(connID), nil
}
-// EditAPIPluginConfig 修改接口插件配置
+//EditAPIPluginConfig 修改接口插件配置
func EditAPIPluginConfig(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) {
db := database2.GetConnection()
// 查询接口是否添加该插件
@@ -85,6 +85,7 @@ func GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interfac
defer rows.Close()
pluginList := make([]map[string]interface{}, 0)
//获取记录列
+
for rows.Next() {
var pluginPriority, pluginStatus, connID int
var pluginName, pluginConfig, createTime, updateTime, requestURL string
@@ -108,7 +109,7 @@ func GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interfac
return true, pluginList, nil
}
-// GetPluginIndex 获取插件优先级
+//GetPluginIndex 获取插件优先级
func GetPluginIndex(pluginName string) (bool, int, error) {
db := database2.GetConnection()
var pluginPriority int
@@ -120,7 +121,7 @@ func GetPluginIndex(pluginName string) (bool, int, error) {
return true, pluginPriority, nil
}
-// GetAPIPluginConfig 通过APIID获取配置信息
+//GetAPIPluginConfig 通过APIID获取配置信息
func GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[string]string, error) {
db := database2.GetConnection()
sql := "SELECT goku_gateway_api.apiName,goku_gateway_api.requestURL,goku_conn_plugin_api.pluginConfig FROM goku_conn_plugin_api INNER JOIN goku_gateway_api ON goku_gateway_api.apiID = goku_conn_plugin_api.apiID WHERE goku_conn_plugin_api.apiID = ? AND goku_conn_plugin_api.strategyID = ? AND goku_conn_plugin_api.pluginName = ?;"
@@ -131,7 +132,6 @@ func GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[str
return false, nil, errors.New("[ERROR]Can not find the plugin")
}
return false, nil, err
-
}
apiPluginInfo := map[string]string{
"pluginConfig": p,
@@ -141,7 +141,7 @@ func GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[str
return true, apiPluginInfo, nil
}
-// CheckPluginIsExistInAPI 检查策略组是否绑定插件
+//CheckPluginIsExistInAPI 检查策略组是否绑定插件
func CheckPluginIsExistInAPI(strategyID, pluginName string, apiID int) (bool, error) {
db := database2.GetConnection()
sql := "SELECT apiID FROM goku_conn_plugin_api WHERE strategyID = ? AND pluginName = ? AND apiID = ?;"
@@ -186,16 +186,15 @@ func GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string,
rule = append(rule, searchRule)
}
if condition > 0 {
- rule = append(rule, fmt.Sprintf("IF(C.pluginStatus=0,-1,A.pluginStatus) = %d", condition-1))
+ rule = append(rule, fmt.Sprintf("CASE WHEN C.pluginStatus=0 THEN -1 ELSE A.pluginStatus END = %d", condition-1))
}
ruleStr := ""
if len(rule) > 0 {
ruleStr += "WHERE " + strings.Join(rule, " AND ")
}
- sql = fmt.Sprintf(`SELECT A.connID,A.pluginName,IFNULL(A.createTime,""),IFNULL(A.updateTime,""),IF(C.pluginStatus=0,-1,A.pluginStatus) as pluginStatus,IFNULL(C.pluginDesc,""),IF(B.remark is null or B.remark = "",B.loginCall,B.remark) AS updaterName FROM goku_conn_plugin_api A LEFT JOIN goku_admin B ON A.updaterID=B.userID INNER JOIN goku_plugin C ON C.pluginName = A.pluginName %s ORDER BY pluginStatus DESC,A.updateTime DESC;`, ruleStr)
+ sql = fmt.Sprintf(`SELECT A.connID,A.pluginName,IFNULL(A.createTime,""),IFNULL(A.updateTime,""),CASE WHEN C.pluginStatus=0 THEN -1 ELSE A.pluginStatus END as pluginStatus,IFNULL(C.pluginDesc,""),CASE WHEN B.remark is null or B.remark = "" THEN B.loginCall ELSE B.remark END AS updaterName FROM goku_conn_plugin_api A LEFT JOIN goku_admin B ON A.updaterID=B.userID INNER JOIN goku_plugin C ON C.pluginName = A.pluginName %s ORDER BY pluginStatus DESC,A.updateTime DESC;`, ruleStr)
rows, err := db.Query(sql)
if err != nil {
- panic(err)
return false, nil, nil, err
}
defer rows.Close()
@@ -224,7 +223,7 @@ func GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string,
return true, pluginList, apiInfo, nil
}
-// GetAllAPIPluginInStrategy 获取策略组中所有接口插件列表
+//GetAllAPIPluginInStrategy 获取策略组中所有接口插件列表
func GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{}, error) {
db := database2.GetConnection()
sql := `SELECT goku_conn_plugin_api.connID,goku_conn_plugin_api.apiID,goku_gateway_api.apiName,goku_gateway_api.requestURL,goku_conn_plugin_api.pluginName,IFNULL(goku_conn_plugin_api.createTime,""),IFNULL(goku_conn_plugin_api.updateTime,""),IF(goku_plugin.pluginStatus=0,-1,goku_conn_plugin_api.pluginStatus) as pluginStatus,IFNULL(goku_plugin.pluginDesc,"") FROM goku_conn_plugin_api INNER JOIN goku_gateway_api ON goku_gateway_api.apiID = goku_conn_plugin_api.apiID INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_api.pluginName WHERE goku_conn_plugin_api.strategyID = ? ORDER BY pluginStatus DESC,goku_conn_plugin_api.updateTime DESC;`
@@ -235,6 +234,7 @@ func GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{
defer rows.Close()
pluginList := make([]map[string]interface{}, 0)
//获取记录列
+
for rows.Next() {
var pluginStatus, apiID, connID int
var apiName, pluginName, pluginDesc, createTime, updateTime, requestURL string
@@ -258,7 +258,7 @@ func GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{
return true, pluginList, nil
}
-// BatchEditAPIPluginStatus 批量修改策略组插件状态
+//BatchEditAPIPluginStatus 批量修改策略组插件状态
func BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userID int) (bool, string, error) {
db := database2.GetConnection()
t := time.Now()
@@ -281,6 +281,7 @@ func BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userI
}
defer rows.Close()
//获取记录列
+
for rows.Next() {
var apiID int
err = rows.Scan(&apiID)
@@ -299,7 +300,7 @@ func BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userI
return true, "", nil
}
-// BatchDeleteAPIPlugin 批量删除策略组插件
+//BatchDeleteAPIPlugin 批量删除策略组插件
func BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
@@ -314,6 +315,7 @@ func BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) {
}
defer rows.Close()
//获取记录列
+
for rows.Next() {
var apiID int
err = rows.Scan(&apiID)
@@ -340,7 +342,7 @@ func BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) {
return true, "", nil
}
-// GetAPIPluginName 通过connID获取插件名称
+//GetAPIPluginName 通过connID获取插件名称
func GetAPIPluginName(connID int) (bool, string, error) {
db := database2.GetConnection()
var pluginName string
@@ -352,7 +354,7 @@ func GetAPIPluginName(connID int) (bool, string, error) {
return true, "", nil
}
-// CheckAPIPluginIsExistByConnIDList 通过connIDList判断插件是否存在
+//CheckAPIPluginIsExistByConnIDList 通过connIDList判断插件是否存在
func CheckAPIPluginIsExistByConnIDList(connIDList, pluginName string) (bool, []int, error) {
db := database2.GetConnection()
sql := "SELECT apiID FROM goku_conn_plugin_api WHERE connID IN (" + connIDList + ") AND pluginName = ?;"
@@ -374,7 +376,7 @@ func CheckAPIPluginIsExistByConnIDList(connIDList, pluginName string) (bool, []i
return true, apiIDList, nil
}
-// GetAPIPluginListWithNotAssignAPIList 获取没有绑定嵌套插件列表
+//GetAPIPluginListWithNotAssignAPIList 获取没有绑定嵌套插件列表
func GetAPIPluginListWithNotAssignAPIList(strategyID string) (bool, []map[string]interface{}, error) {
db := database2.GetConnection()
sql := "SELECT pluginID,pluginDesc,pluginName FROM goku_plugin WHERE pluginType = 2 AND pluginStatus = 1;"
@@ -385,6 +387,7 @@ func GetAPIPluginListWithNotAssignAPIList(strategyID string) (bool, []map[string
defer rows.Close()
pluginList := make([]map[string]interface{}, 0)
//获取记录列
+
sql = "SELECT goku_gateway_api.apiID,goku_gateway_api.apiName,goku_gateway_api.requestURL FROM goku_gateway_api INNER JOIN goku_conn_strategy_api ON goku_gateway_api.apiID = goku_conn_strategy_api.apiID WHERE goku_conn_strategy_api.strategyID = ? AND goku_gateway_api.apiID NOT IN (SELECT goku_conn_plugin_api.apiID FROM goku_conn_plugin_api WHERE goku_conn_plugin_api.strategyID = ? AND goku_conn_plugin_api.pluginName = ?);"
for rows.Next() {
var pluginID int
@@ -428,63 +431,3 @@ func GetAPIPluginListWithNotAssignAPIList(strategyID string) (bool, []map[string
}
return true, pluginList, nil
}
-
-//BatchUpdateAPIPluginUpdateTag 批量更新插件更新标识
-func BatchUpdateAPIPluginUpdateTag(strategyIDList string) error {
- db := database2.GetConnection()
- code := make([]string, 0, len(apiPlugins))
- strategyIDs := strings.Split(strategyIDList, ",")
- strategyCode := make([]string, 0, len(strategyIDs))
- updateTag := time.Now().Format("20060102150405")
- s := make([]interface{}, 0, len(strategyPlugins)+1+len(strategyIDs))
- s = append(s, updateTag)
- for i := 0; i < len(strategyIDs); i++ {
- strategyCode = append(strategyCode, "?")
- s = append(s, strategyIDs[i])
- }
- for i := 0; i < len(apiPlugins); i++ {
- code = append(code, "?")
- s = append(s, apiPlugins[i])
- }
-
- sql := "UPDATE goku_conn_plugin_api SET updateTag = ? WHERE strategyID IN (" + strings.Join(strategyCode, ",") + ") AND pluginName IN (" + strings.Join(code, ",") + ");"
- _, err := db.Exec(sql, s...)
- if err != nil {
- return err
- }
- return nil
-}
-
-//UpdateAPITagByPluginName 通过插件名称更新接口插件标识
-func UpdateAPITagByPluginName(strategyID string, apiIDList string, pluginList string) error {
- db := database2.GetConnection()
- plugins := strings.Split(pluginList, ",")
- code := make([]string, 0, len(plugins))
- updateTag := time.Now().Format("20060102150405")
- s := make([]interface{}, 0, len(plugins)+2)
- s = append(s, updateTag, strategyID)
- for i := 0; i < len(plugins); i++ {
- code = append(code, "?")
- s = append(s, plugins[i])
- }
-
- sql := "UPDATE goku_conn_plugin_api SET updateTag = ? WHERE strategyID = ? AND apiID IN (" + apiIDList + ") AND pluginName IN (" + strings.Join(code, ",") + ");"
- _, err := db.Exec(sql, s...)
- if err != nil {
- return err
- }
- return nil
-}
-
-//UpdateAllAPIPluginUpdateTag 更新所有接口插件更新标识
-func UpdateAllAPIPluginUpdateTag() error {
- db := database2.GetConnection()
- updateTag := time.Now().Format("20060102150405")
- // s := make([]interface{}
- sql := "UPDATE goku_conn_plugin_api SET updateTag = ?;"
- _, err := db.Exec(sql, updateTag)
- if err != nil {
- return err
- }
- return nil
-}
diff --git a/server/dao/console-mysql/apiStrategy.go b/server/dao/console-sqlite3/apiStrategy.go
similarity index 85%
rename from server/dao/console-mysql/apiStrategy.go
rename to server/dao/console-sqlite3/apiStrategy.go
index 4238c7fef98f819eb8e81fe5a00a8125da274166..3b9798f758dc21985d34ac8f673031d66898375f 100644
--- a/server/dao/console-mysql/apiStrategy.go
+++ b/server/dao/console-sqlite3/apiStrategy.go
@@ -1,4 +1,4 @@
-package consolemysql
+package console_sqlite3
import (
"fmt"
@@ -9,7 +9,7 @@ import (
database2 "github.com/eolinker/goku-api-gateway/common/database"
)
-// AddAPIToStrategy 将接口加入策略组
+//AddAPIToStrategy 将接口加入策略组
func AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
@@ -103,55 +103,6 @@ func BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string)
return true, "", nil
}
-// getAPIStrategyRule
-func getAPIStrategyRule(strategyID int, keyword string, condition int, ids []int) []string {
- rule := make([]string, 0, 5)
- rule = append(rule, fmt.Sprintf("S.`strategyID` = %d", strategyID))
- if keyword != "" {
- searchRule := "A.apiName LIKE '%" + keyword + "%' OR A.requestURL LIKE '%" + keyword + "%'"
- rule = append(rule, searchRule)
- }
- switch condition {
- case 0:
- {
- break
- }
- case 1:
- {
-
- }
- case 2:
- {
-
- }
- case 3, 4:
- {
- idsStr := ""
- idLen := len(ids)
- if len(ids) < 1 {
- break
- }
- for i, id := range ids {
- idsStr += strconv.Itoa(id)
- if i < idLen-1 {
- idsStr += ","
- }
- }
- if condition == 1 {
- rule = append(rule, fmt.Sprintf("A.managerID IN (%s)", idsStr))
- } else if condition == 2 {
- rule = append(rule, fmt.Sprintf("A.lastUpdateUserID IN (%s)", idsStr))
- }
-
- }
- default:
- {
- break
- }
- }
- return rule
-}
-
func getAPIOfStrategyRule(condition int, balanceNames []string, ids []int) []string {
rule := make([]string, 0, 2)
switch condition {
@@ -248,8 +199,8 @@ func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSiz
if len(rule) > 0 {
ruleStr += "WHERE " + strings.Join(rule, " AND ")
}
- // IF(B.remark is null or B.remark = "",B.loginCall,B.remark) AS updaterName,IF(C.remark is null or C.remark = "",C.loginCall,C.remark) AS managerName
- sql := fmt.Sprintf("SELECT A.`apiID`, A.`apiName`, A.`requestURL`,A.`requestMethod`,A.`targetURL`,IFNULL(A.`targetMethod`,''), A.`isFollow`, IFNULL(A.`updateTime`,'') AS updateTime, A.`lastUpdateUserID`, A.`managerID`, IFNULL(A.`balanceName`,'') As `target`, IFNULL(S.`target`,'') as `rewriteTarget`, IF(AD.`remark` is null or AD.`remark` = '', AD.`loginCall`,AD.`remark`) as managerName, IF(AD2.`remark` is null or AD2.`remark` = '', AD2.`loginCall`,AD2.`remark`) as updaterName FROM `goku_gateway_api` A INNER JOIN `goku_conn_strategy_api` S ON S.`apiID` = A.`apiID` LEFT JOIN `goku_admin` AD ON A.`managerID` = AD.`userID` LEFT JOIN `goku_admin` AD2 ON A.`lastUpdateUserID` = AD2.`userID` %s", ruleStr)
+
+ sql := fmt.Sprintf("SELECT A.`apiID`, A.`apiName`, A.`requestURL`,A.`requestMethod`,CASE WHEN A.`apiType`=0 THEN A.`targetURL` ELSE '' END,A.apiType,IFNULL(A.`targetMethod`,''), A.`isFollow`, IFNULL(A.`updateTime`,'') AS updateTime, A.`lastUpdateUserID`, A.`managerID`, IFNULL(A.`balanceName`,'') As `target`, IFNULL(S.`target`,'') as `rewriteTarget`, CASE WHEN AD.`remark` is null or AD.`remark` = '' THEN AD.`loginCall` ELSE AD.`remark` END AS managerName, CASE WHEN AD2.`remark` is null or AD2.`remark` = '' THEN AD2.`loginCall` ELSE AD2.`remark` END AS updaterName FROM `goku_gateway_api` A INNER JOIN `goku_conn_strategy_api` S ON S.`apiID` = A.`apiID` LEFT JOIN `goku_admin` AD ON A.`managerID` = AD.`userID` LEFT JOIN `goku_admin` AD2 ON A.`lastUpdateUserID` = AD2.`userID` %s", ruleStr)
count := getCountSQL(sql)
rows, err := getPageSQL(sql, "S.`connID`", "DESC", page, pageSize)
if err != nil {
@@ -260,10 +211,10 @@ func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSiz
//获取记录列
apiList := make([]map[string]interface{}, 0)
for rows.Next() {
- var apiID, updaterID, managerID int
+ var apiID, updaterID, managerID, apiType int
var apiName, requestURL, updateTime, updaterName, managerName, target, targetURL, rewriteTarget, requestMethod, targetMethod string
var isFollow bool
- err = rows.Scan(&apiID, &apiName, &requestURL, &requestMethod, &targetURL, &targetMethod, &isFollow, &updateTime, &updaterID, &managerID, &target, &rewriteTarget, &managerName, &updaterName)
+ err = rows.Scan(&apiID, &apiName, &requestURL, &requestMethod, &targetURL, &apiType, &targetMethod, &isFollow, &updateTime, &updaterID, &managerID, &target, &rewriteTarget, &managerName, &updaterName)
if err != nil {
return false, make([]map[string]interface{}, 0), 0, err
}
@@ -280,6 +231,7 @@ func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSiz
"requestMethod": strings.ToUpper(requestMethod),
"targetMethod": strings.ToUpper(targetMethod),
"isFollow": isFollow,
+ "apiType": apiType,
}
apiList = append(apiList, apiInfo)
}
@@ -304,7 +256,7 @@ func getSimpleAPIListInStrategy(strategyID string, projectID int) map[string]str
sql := "SELECT goku_gateway_api.requestURL,GROUP_CONCAT(DISTINCT goku_gateway_api.requestMethod) AS requestMethod FROM goku_gateway_api INNER JOIN goku_conn_strategy_api ON goku_gateway_api.apiID = goku_conn_strategy_api.apiID where goku_conn_strategy_api.strategyID = ? AND goku_gateway_api.projectID = ? GROUP BY requestURL"
rows, err := db.Query(sql, strategyID, projectID)
if err != nil {
- panic(err)
+ return nil
}
defer rows.Close()
simpleMap := make(map[string]string)
@@ -312,7 +264,7 @@ func getSimpleAPIListInStrategy(strategyID string, projectID int) map[string]str
var requestURL, requestMethod string
err = rows.Scan(&requestURL, &requestMethod)
if err != nil {
- panic(err)
+ return nil
}
simpleMap[requestURL] = requestMethod
}
@@ -418,7 +370,7 @@ func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSi
if len(rule) > 0 {
ruleStr += "WHERE " + strings.Join(rule, " AND ")
}
- sql := fmt.Sprintf("SELECT A.apiID,A.apiName,A.requestURL,A.requestMethod,IFNULL(A.balanceName,''),A.targetURL,IFNULL(A.`targetMethod`,''), A.`isFollow`,A.groupID,IFNULL(G.groupPath,A.groupID) FROM goku_gateway_api A LEFT JOIN goku_gateway_api_group G ON G.groupID = A.groupID %s", ruleStr)
+ sql := fmt.Sprintf("SELECT A.apiID,A.apiName,A.requestURL,A.requestMethod,IFNULL(A.balanceName,''),CASE WHEN A.apiType=0 THEN A.targetURL ELSE '' END,A.apiType,IFNULL(A.`targetMethod`,''), A.`isFollow`,A.groupID,IFNULL(G.groupPath,A.groupID) FROM goku_gateway_api A LEFT JOIN goku_gateway_api_group G ON G.groupID = A.groupID %s", ruleStr)
count := getCountSQL(sql)
rows, err := getPageSQL(sql, "A.`updateTime`", "DESC", page, pageSize)
if err != nil {
@@ -428,10 +380,10 @@ func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSi
apiList := make([]map[string]interface{}, 0)
//获取记录列
for rows.Next() {
- var apiID, groupID int
+ var apiID, groupID, apiType int
var apiName, requestURL, requestMethod, targetServer, groupPath, targetURL, targetMethod string
var isFollow bool
- err = rows.Scan(&apiID, &apiName, &requestURL, &requestMethod, &targetServer, &targetURL, &targetMethod, &isFollow, &groupID, &groupPath)
+ err = rows.Scan(&apiID, &apiName, &requestURL, &requestMethod, &targetServer, &targetURL, &apiType, &targetMethod, &isFollow, &groupID, &groupPath)
if err != nil {
return false, make([]map[string]interface{}, 0), 0, err
}
@@ -452,13 +404,14 @@ func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSi
"groupPath": groupPath,
"targetMethod": strings.ToUpper(targetMethod),
"isFollow": isFollow,
+ "apiType": apiType,
}
apiList = append(apiList, apiInfo)
}
return true, apiList, count, nil
}
-// BatchDeleteAPIInStrategy 批量删除策略组接口
+//BatchDeleteAPIInStrategy 批量删除策略组接口
func BatchDeleteAPIInStrategy(apiIDList, strategyID string) (bool, string, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
diff --git a/server/dao/console-sqlite3/auth.go b/server/dao/console-sqlite3/auth.go
new file mode 100644
index 0000000000000000000000000000000000000000..0f42c389327d9758a1c3253d41806dc60046c445
--- /dev/null
+++ b/server/dao/console-sqlite3/auth.go
@@ -0,0 +1,173 @@
+package console_sqlite3
+
+import (
+ "encoding/json"
+ "time"
+
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+
+ database2 "github.com/eolinker/goku-api-gateway/common/database"
+)
+
+type basicAuthConf struct {
+ UserName string `json:"userName"`
+ Password string `json:"password"`
+ HideCredential bool `json:"hideCredential"`
+ Remark string `json:"remark"`
+}
+
+//APIKeyConf apiKey配置
+type APIKeyConf struct {
+ APIKey string `json:"Apikey"`
+ TokenPlace string `json:"tokenPlace"`
+ HideCredential bool `json:"hideCredential"`
+ Remark string `json:"remark"`
+}
+
+//OAuth2GlobalConf oauth2配置
+type OAuth2GlobalConf struct {
+ oauth2Conf
+ Oauth2CredentialList []*oauth2Credential `json:"oauth2CredentialList"`
+}
+
+type oauth2Conf struct {
+ Scopes []string `json:"scopes"` //scopes = { required = false, type = "array" },
+ MandatoryScope bool `json:"mandatoryScope"` //mandatory_scope = { required = true, type = "boolean", default = false, func = check_mandatory_scope },
+ TokenExpiration int `json:"tokenExpiration"` //token_expiration = { required = true, type = "number", default = 7200 },
+ EnableAuthorizationCode bool `json:"enableAuthorizationCode"` //enable_authorization_code = { required = true, type = "boolean", default = false },
+ EnableImplicitGrant bool `json:"enableImplicitGrant"` //enable_implicit_grant = { required = true, type = "boolean", default = false },
+ EnableClientCredentials bool `json:"enableClientCredentials"` //enable_client_credentials = { required = true, type = "boolean", default = false },
+ HideCredentials bool `json:"hideCredentials"` //hide_credentials = { type = "boolean", default = false },
+ AcceptHTTPIfAlreadyTerminated bool `json:"acceptHttpIfAlreadyTerminated"` //accept_http_if_already_terminated = { required = false, type = "boolean", default = false },
+ RefreshTokenTTL int `json:"refreshTokenTTL"` //refresh_token_ttl = {required = true, type = "number", default = 1209600} -- original hardcoded value - 14 days
+}
+
+type jwtCredential struct {
+ ISS string `json:"iss"`
+ Secret string `json:"secret"`
+ RsaPublicKey string `json:"rsaPublicKey"`
+ Algorithm string `json:"algorithm"`
+ Remark string `json:"remark"`
+}
+
+type jwtConf struct {
+ SignatureIsBase64 bool `json:"signatureIsBase64"`
+ ClaimsToVerify []string `json:"claimsToVerify"`
+ RunOnPreflight bool `json:"runOnPreflight"`
+ JwtCredentials []jwtCredential `json:"jwtCredentials"`
+ HideCredentials bool `json:"hideCredentials"`
+}
+
+type oauth2Credential struct {
+ CredentialID string `json:"credentialID"`
+ ClientID string `json:"clientID"`
+ ClientSecret string `json:"clientSecret"`
+ RedirectURI string `json:"redirectURI"`
+ Remark string `json:"remark"`
+}
+
+//GetAuthStatus 获取认证状态
+func GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) {
+ db := database2.GetConnection()
+ var basicStatus, apikeyStatus int
+ sql := `SELECT CASE WHEN goku_plugin.pluginStatus = 0 THEN 0 ELSE goku_conn_plugin_strategy.pluginStatus END AS pluginStatus FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_strategy.pluginName WHERE goku_conn_plugin_strategy.pluginName = ? AND goku_conn_plugin_strategy.strategyID = ?;`
+ db.QueryRow(sql, "goku-basic_auth", strategyID).Scan(&basicStatus)
+
+ db.QueryRow(sql, "goku-apikey_auth", strategyID).Scan(&apikeyStatus)
+
+ authInfo := map[string]interface{}{
+ "basicAuthStatus": basicStatus,
+ "apiKeyStatus": apikeyStatus,
+ "jwtStatus": 0,
+ "oAuthStatus": 0,
+ }
+ return true, authInfo, nil
+}
+
+//GetAuthInfo 获取认证信息
+func GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) {
+ db := database2.GetConnection()
+ var strategyName, auth string
+ sql := "SELECT IFNULL(auth,''),strategyName FROM goku_gateway_strategy WHERE strategyID = ?;"
+ err := db.QueryRow(sql, strategyID).Scan(&auth, &strategyName)
+ if err != nil {
+ return false, make(map[string]interface{}), err
+ }
+ basicAuthList := make([]basicAuthConf, 0)
+ apiKeyList := make([]APIKeyConf, 0)
+
+ var basicConfig, apiKeyConfig string
+ sql = `SELECT pluginConfig FROM goku_conn_plugin_strategy WHERE pluginName = ? AND strategyID = ? AND pluginStatus = 1;`
+ err = db.QueryRow(sql, "goku-basic_auth", strategyID).Scan(&basicConfig)
+ if err == nil {
+ if basicConfig != "" {
+ json.Unmarshal([]byte(basicConfig), &basicAuthList)
+ if err != nil {
+ panic(err)
+ return false, make(map[string]interface{}), err
+ }
+ }
+ }
+ err = db.QueryRow(sql, "goku-apikey_auth", strategyID).Scan(&apiKeyConfig)
+ if err == nil {
+ if apiKeyConfig != "" {
+ err = json.Unmarshal([]byte(apiKeyConfig), &apiKeyList)
+ if err != nil {
+ panic(err)
+ return false, make(map[string]interface{}), err
+ }
+ }
+ }
+
+ authInfo := map[string]interface{}{
+ "strategyID": strategyID,
+ "strategyName": strategyName,
+ "auth": auth,
+ "basicAuthList": basicAuthList,
+ "apiKeyList": apiKeyList,
+ "jwtCredentialList": make([]interface{}, 0),
+ "oauth2CredentialList": make([]interface{}, 0),
+ }
+ return true, authInfo, nil
+}
+
+//EditAuthInfo 编辑认证信息
+func EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList string, delClientIDList []string) (bool, error) {
+ db := database2.GetConnection()
+ now := time.Now().Format("2006-01-02 15:04:05")
+ sql := "UPDATE goku_gateway_strategy SET strategyName = ? WHERE strategyID = ?;"
+ stmt, err := db.Prepare(sql)
+ if err != nil {
+ return false, err
+ }
+ defer stmt.Close()
+ _, err = stmt.Exec(strategyName, strategyID)
+ if err != nil {
+ return false, err
+ }
+ // 设置basic信息
+ Tx, _ := db.Begin()
+ _, err = Tx.Exec("UPDATE goku_conn_plugin_strategy SET pluginConfig = ?,updateTime = ? WHERE strategyID = ? AND pluginName = ? AND pluginStatus = 1;", basicAuthList, now, strategyID, "goku-basic_auth")
+ if err != nil {
+ Tx.Rollback()
+ return false, err
+ }
+ _, err = Tx.Exec("UPDATE goku_conn_plugin_strategy SET pluginConfig = ?,updateTime = ? WHERE strategyID = ? AND pluginName = ? AND pluginStatus = 1;", apikeyList, now, strategyID, "goku-apikey_auth")
+ if err != nil {
+ Tx.Rollback()
+ return false, err
+ }
+
+ sql = "UPDATE goku_gateway_strategy SET updateTime = ? WHERE strategyID = ?;"
+ _, err = Tx.Exec(sql, now, strategyID)
+ if err != nil {
+ Tx.Rollback()
+ return false, err
+ }
+ err = Tx.Commit()
+ if err != nil {
+ info := err.Error()
+ log.Info(info)
+ }
+ return true, nil
+}
diff --git a/server/dao/console-sqlite3/cluster.go b/server/dao/console-sqlite3/cluster.go
new file mode 100644
index 0000000000000000000000000000000000000000..630f08fcb7ab981cbd222a29f024decb5523ce83
--- /dev/null
+++ b/server/dao/console-sqlite3/cluster.go
@@ -0,0 +1,131 @@
+package console_sqlite3
+
+import (
+ "github.com/eolinker/goku-api-gateway/common/database"
+ entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity"
+)
+
+//AddCluster 新增集群
+func AddCluster(name, title, note string) error {
+ db := database.GetConnection()
+ sql := "INSERT INTO goku_cluster (`name`,`title`,`note`) VALUES (?,?,?)"
+ stmt, err := db.Prepare(sql)
+ if err != nil {
+ return err
+ }
+ defer stmt.Close()
+ _, err = stmt.Exec(name, title, note)
+ return err
+}
+
+//EditCluster 修改集群信息
+func EditCluster(name, title, note string) error {
+ db := database.GetConnection()
+ sql := "UPDATE goku_cluster SET `title` = ?,`note` = ? WHERE `name` = ?"
+ stmt, err := db.Prepare(sql)
+ if err != nil {
+ return err
+ }
+ defer stmt.Close()
+ _, err = stmt.Exec(title, note, name)
+ return err
+}
+
+//DeleteCluster 删除集群
+func DeleteCluster(name string) error {
+ db := database.GetConnection()
+ sql := "DELETE FROM goku_cluster WHERE `name` = ?"
+ stmt, err := db.Prepare(sql)
+ if err != nil {
+ return err
+ }
+ defer stmt.Close()
+ _, err = stmt.Exec(name)
+ return err
+}
+
+//GetClusterCount 获取集群数量
+func GetClusterCount() int {
+ db := database.GetConnection()
+ var count int
+ sql := "SELECT COUNT(*) FROM goku_cluster;"
+ err := db.QueryRow(sql).Scan(&count)
+ if err != nil {
+ return 0
+ }
+ return count
+}
+
+//GetClusterNodeCount 获取集群节点数量
+func GetClusterNodeCount(name string) int {
+ db := database.GetConnection()
+ var count int
+ sql := "SELECT COUNT(*) FROM goku_node_info INNER JOIN goku_cluster ON goku_node_info.clusterID = goku_clutser.id WHERE goku_clutser.`name` = ?;"
+ err := db.QueryRow(sql, name).Scan(&count)
+ if err != nil {
+ return 0
+ }
+ return count
+}
+
+//GetClusterIDByName 通过集群名称获取集群ID
+func GetClusterIDByName(name string) int {
+ db := database.GetConnection()
+ var id int
+ sql := "SELECT `id` FROM goku_cluster WHERE `name` = ?"
+ err := db.QueryRow(sql, name).Scan(&id)
+ if err != nil {
+ return 0
+ }
+ return id
+}
+
+//GetClusters 获取集群列表
+func GetClusters() ([]*entity.Cluster, error) {
+ db := database.GetConnection()
+ sql := "SELECT `id`,`name`,`title`,`note` FROM goku_cluster"
+ rows, err := db.Query(sql)
+ if err != nil {
+ return []*entity.Cluster{}, err
+ }
+ clusters := make([]*entity.Cluster, 0, 10)
+ defer rows.Close()
+ for rows.Next() {
+ var cluster entity.Cluster
+ err = rows.Scan(&cluster.ID, &cluster.Name, &cluster.Title, &cluster.Note)
+ if err != nil {
+ return []*entity.Cluster{}, err
+ }
+ sql = "SELECT COUNT(*) FROM goku_node_info WHERE clusterID = ?;"
+ err = db.QueryRow(sql, cluster.ID).Scan(&cluster.NodeCount)
+ if err != nil {
+ return []*entity.Cluster{}, err
+ }
+ clusters = append(clusters, &cluster)
+ }
+ return clusters, nil
+}
+
+//GetCluster 获取集群信息
+func GetCluster(name string) (*entity.Cluster, error) {
+ db := database.GetConnection()
+ sql := "SELECT `id`,`name`,`title`,`note` FROM goku_cluster WHERE `name` = ?"
+ var cluster entity.Cluster
+ err := db.QueryRow(sql, name).Scan(&cluster.ID, &cluster.Name, &cluster.Title, &cluster.Note)
+ if err != nil {
+ return nil, err
+ }
+ return &cluster, nil
+}
+
+//CheckClusterNameIsExist 判断集群名称是否存在
+func CheckClusterNameIsExist(name string) bool {
+ db := database.GetConnection()
+ sql := "SELECT `name` FROM goku_cluster WHERE `name` = ?"
+ var clusterName string
+ err := db.QueryRow(sql, name).Scan(&clusterName)
+ if err != nil {
+ return false
+ }
+ return true
+}
diff --git a/server/dao/config-log/log.go b/server/dao/console-sqlite3/config-log/log.go
similarity index 73%
rename from server/dao/config-log/log.go
rename to server/dao/console-sqlite3/config-log/log.go
index e96a364736aaa19df635949b30b123b2c0254fa3..15f0ccc420a46d287dca80330cb0617ef949f11e 100644
--- a/server/dao/config-log/log.go
+++ b/server/dao/console-sqlite3/config-log/log.go
@@ -1,4 +1,4 @@
-package configlog
+package config_log
import (
"github.com/eolinker/goku-api-gateway/common/database"
@@ -6,9 +6,9 @@ import (
)
const sqlSelect = "SELECT `name`,`enable`,`dir`,`file`,`level`,`period`,`expire`,`fields` FROM `goku_config_log` WHERE `name` = ? LIMIT 1;"
-const sqlInsert = "INSERT INTO `goku_config_log`(`name`,`enable`,`dir`,`file`,`level`,`period`,`expire`,`fields`)VALUES(?,?,?,?,?,?,?,?)ON DUPLICATE KEY UPDATE `enable`=VALUES(`enable`),`dir`=VALUES(`dir`),`file`=VALUES(`file`),`level`=VALUES(`level`),`period`=VALUES(`period`),`expire`=VALUES(`expire`),`fields`=VALUES(`fields`);"
+const sqlInsert = "REPLACE INTO `goku_config_log`(`name`,`enable`,`dir`,`file`,`level`,`period`,`expire`,`fields`)VALUES(?,?,?,?,?,?,?,?);"
-//Get 通过名称获取日志配置
+//Get get
func Get(name string) (*entity.LogConfig, error) {
stmt, e := database.GetConnection().Prepare(sqlSelect)
if e != nil {
@@ -31,7 +31,7 @@ func Get(name string) (*entity.LogConfig, error) {
return ent, nil
}
-//Set 设置日志配置
+//Set set
func Set(ent *entity.LogConfig) error {
stmt, e := database.GetConnection().Prepare(sqlInsert)
if e != nil {
diff --git a/server/dao/console-mysql/dao-balance-update/update.go b/server/dao/console-sqlite3/dao-balance-update/update.go
similarity index 80%
rename from server/dao/console-mysql/dao-balance-update/update.go
rename to server/dao/console-sqlite3/dao-balance-update/update.go
index a557414451ee90146f4ea6d9108fa5b7d5c64123..8ff0b881f488eae4a3309b7d57f5d3f25af78dd8 100644
--- a/server/dao/console-mysql/dao-balance-update/update.go
+++ b/server/dao/console-sqlite3/dao-balance-update/update.go
@@ -2,10 +2,11 @@ package dao_balance_update
import (
"github.com/eolinker/goku-api-gateway/common/database"
- dao_service "github.com/eolinker/goku-api-gateway/server/dao/console-mysql/dao-service"
+ dao_service2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-service"
entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity"
)
+//GetAllOldVerSion 获取所有旧负载配置
func GetAllOldVerSion() ([]*entity.BalanceInfoEntity, error) {
const sql = "SELECT `balanceName`,IFNULL(`balanceDesc`, ''),IFNULL(`balanceConfig`, ''),IFNULL(`defaultConfig`, ''),IFNULL(`clusterConfig`, ''),`updateTime`,`createTime` FROM `goku_balance` WHERE `serviceName` = '';"
db := database.GetConnection()
@@ -28,6 +29,7 @@ func GetAllOldVerSion() ([]*entity.BalanceInfoEntity, error) {
return r, nil
}
+//GetDefaultServiceStatic 获取默认静态负载
func GetDefaultServiceStatic() string {
tx := database.GetConnection()
@@ -35,7 +37,7 @@ func GetDefaultServiceStatic() string {
err := tx.QueryRow("SELECT `name` FROM `goku_service_config` WHERE `driver`='static' ORDER BY `default` DESC LIMIT 1; ").Scan(&name)
if err != nil {
name = "static"
- dao_service.Add(name, "static", "默认静态服务", "", "", false, false, "", "", 5, 300)
+ dao_service2.Add(name, "static", "默认静态服务", "", "", false, false, "", "", 5, 300)
}
return name
diff --git a/server/dao/dao-balance/add.go b/server/dao/console-sqlite3/dao-balance/add.go
similarity index 96%
rename from server/dao/dao-balance/add.go
rename to server/dao/console-sqlite3/dao-balance/add.go
index 3a2874135fd2f315f6fc1c73a3870d9d1dcc531f..57abc93fd043c36ea502b33e120e200e16f09126 100644
--- a/server/dao/dao-balance/add.go
+++ b/server/dao/console-sqlite3/dao-balance/add.go
@@ -1,10 +1,10 @@
-package daobalance
+package dao_balance
import (
"github.com/eolinker/goku-api-gateway/common/database"
)
-//Add 新增负载
+//Add add
func Add(name, serviceName, desc, appName, static, staticCluster, now string) (string, error) {
//const sql = "INSERT INTO goku_balance (`balanceName`,`serviceName`,`appName`,`balanceDesc`,`static`,`staticCluster`,`createTime`,`updateTime`) VALUES (?,?,?,?,?,?,?,?,);"
@@ -22,7 +22,7 @@ func Add(name, serviceName, desc, appName, static, staticCluster, now string) (s
return "", nil
}
-//AddStatic 新增静态
+//AddStatic 新增静态负载
func AddStatic(name, serviceName, static, staticCluster, desc, now string) (string, error) {
const sql = "INSERT INTO goku_balance (`balanceName`,`serviceName`,`static`,`staticCluster`,`balanceDesc`,`createTime`,`updateTime`,`appName`,`defaultConfig`,`clusterConfig`,`balanceConfig`) VALUES (?,?,?,?,?,?,?,'','','','');"
@@ -58,7 +58,7 @@ func AddDiscovery(name, serviceName, appName, desc, now string) (string, error)
return "", nil
}
-//SaveStatic 保存静态
+//SaveStatic 保存静态负载信息
func SaveStatic(name, serviceName, static, staticCluster, desc string, now string) (string, error) {
const sql = "UPDATE `goku_balance` SET `serviceName`=? ,`static` = ?,`staticCluster`=?,`balanceDesc` =?,`updateTime`=? WHERE `balanceName`=?;"
db := database.GetConnection()
@@ -74,7 +74,7 @@ func SaveStatic(name, serviceName, static, staticCluster, desc string, now strin
return "", nil
}
-//SaveDiscover 保存服务发现
+//SaveDiscover 保存服务发现信息
func SaveDiscover(name, serviceName, appName, desc string, now string) (string, error) {
const sql = "UPDATE `goku_balance` SET `serviceName`=? ,`appName` = ?,`balanceDesc` =?,`updateTime`=? WHERE `balanceName`=?;"
db := database.GetConnection()
@@ -90,7 +90,7 @@ func SaveDiscover(name, serviceName, appName, desc string, now string) (string,
return "", nil
}
-//Save 保存
+//Save save
func Save(name, desc, static, staticCluster, now string) (string, error) {
//const sql = "UPDATE `goku_balance` SET `balanceDesc` = ?,`static` =?,`staticCluster`=?,`updateTime`=? WHERE `balanceName` = ?;"
//
@@ -107,7 +107,7 @@ func Save(name, desc, static, staticCluster, now string) (string, error) {
return "", nil
}
-//Delete 删除
+//Delete 删除负载
func Delete(name string) (string, error) {
const sql = "DELETE FROM `goku_balance` WHERE `balanceName`= ?;"
db := database.GetConnection()
diff --git a/server/dao/dao-balance/balance.go b/server/dao/console-sqlite3/dao-balance/balance.go
similarity index 97%
rename from server/dao/dao-balance/balance.go
rename to server/dao/console-sqlite3/dao-balance/balance.go
index d1eae3500dc0ae93e5ac2c0294af258cfe25db9d..61f1f8e5181bc248d7c562857e0740a810241dbc 100644
--- a/server/dao/dao-balance/balance.go
+++ b/server/dao/console-sqlite3/dao-balance/balance.go
@@ -1,4 +1,4 @@
-package daobalance
+package dao_balance
import (
"github.com/eolinker/goku-api-gateway/common/database"
diff --git a/server/dao/dao-balance/get.go b/server/dao/console-sqlite3/dao-balance/get.go
similarity index 93%
rename from server/dao/dao-balance/get.go
rename to server/dao/console-sqlite3/dao-balance/get.go
index 9001c280ae72d68a20565abcb13d6587f16c1248..c7d2dd540b4c033b9b1681e9c5adc8002af90d33 100644
--- a/server/dao/dao-balance/get.go
+++ b/server/dao/console-sqlite3/dao-balance/get.go
@@ -1,13 +1,14 @@
-package daobalance
+package dao_balance
import (
"fmt"
+ "strings"
+
"github.com/eolinker/goku-api-gateway/common/database"
entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity-service"
- "strings"
)
-//Get 获取负载信息
+//Get 根据负载名获取负载配置
func Get(name string) (*entity.Balance, error) {
const sql = "SELECT A.`balanceName`,A.`serviceName`,IFNULL(B.`driver`,''),A.`appName`,IFNULL(A.`static`,''),IFNULL(A.`staticCluster`,''),A.`balanceDesc`,A.`updateTime`,A.`createTime` FROM `goku_balance` A LEFT JOIN `goku_service_config` B ON A.`serviceName` = B.`NAME` WHERE A.`balanceName`= ?;"
db := database.GetConnection()
@@ -20,9 +21,9 @@ func Get(name string) (*entity.Balance, error) {
return v.Type(), nil
}
-//GetAll 获取负载列表
+//GetAll 获取所有负载配置
func GetAll() ([]*entity.Balance, error) {
- const sql = "SELECT A.`balanceName`,A.`serviceName`,IFNULL(B.`driver`,''),A.`appName`,IFNULL(A.`static`,''),IFNULL(A.`staticCluster`,''),A.`balanceDesc`,A.`updateTime`,A.`createTime` FROM `goku_balance` A LEFT JOIN `goku_service_config` B ON A.`serviceName` = B.`name` ORDER BY `updateTime` DESC;"
+ const sql = "SELECT A.`balanceName`,A.`serviceName`,IFNULL(B.`driver`,''),A.`appName`,IFNULL(A.`static`,''),IFNULL(A.`staticCluster`,''),A.`balanceDesc`,A.`updateTime`,A.`createTime` FROM `goku_balance` A LEFT JOIN `goku_service_config` B ON A.`serviceName` = B.`name` ORDER BY A.`updateTime` DESC;"
db := database.GetConnection()
rows, err := db.Query(sql)
if err != nil {
@@ -42,7 +43,7 @@ func GetAll() ([]*entity.Balance, error) {
return r, nil
}
-//Search 查询
+//Search 关键字获取负载列表
func Search(keyword string) ([]*entity.Balance, error) {
const sqlTpl = "SELECT A.`balanceName`,A.`serviceName`,IFNULL(B.`driver`,''),A.`appName`,IFNULL(A.`static`,''),IFNULL(A.`staticCluster`,''),A.`balanceDesc`,A.`updateTime`,A.`createTime` FROM `goku_balance` A LEFT JOIN `goku_service_config` B ON A.`serviceName` = B.`name` %s ORDER BY `updateTime` DESC;"
diff --git a/server/dao/console-mysql/dao-service/add.go b/server/dao/console-sqlite3/dao-service/add.go
similarity index 92%
rename from server/dao/console-mysql/dao-service/add.go
rename to server/dao/console-sqlite3/dao-service/add.go
index b1d2c2ddd5aabefd7aed351f8fe85adaf7857e72..bfc59b45e2dacdfefc9a981285dda72a72efe2af 100644
--- a/server/dao/console-mysql/dao-service/add.go
+++ b/server/dao/console-sqlite3/dao-service/add.go
@@ -1,15 +1,17 @@
package dao_service
import (
- "github.com/eolinker/goku-api-gateway/common/database"
"time"
+
+ "github.com/eolinker/goku-api-gateway/common/database"
)
const sqlAdd = "INSERT INTO `goku_service_config`(`name`,`driver`,`default`,`desc`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut`,`createTime`,`updateTime`)VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?);"
+//Add 新增服务
func Add(name, driver, desc, config, clusterConfig string, isDefault, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error {
- now := time.Now()
+ now := time.Now().Format("2006-01-02 15:04:05")
stmt, e := database.GetConnection().Prepare(sqlAdd)
if e != nil {
diff --git a/server/dao/console-mysql/dao-service/default.go b/server/dao/console-sqlite3/dao-service/default.go
similarity index 95%
rename from server/dao/console-mysql/dao-service/default.go
rename to server/dao/console-sqlite3/dao-service/default.go
index 0dd727811f639e1fdff5b2daa717186116fdf219..edcf25a36fc3bde6af1678e227676cdeda06985b 100644
--- a/server/dao/console-mysql/dao-service/default.go
+++ b/server/dao/console-sqlite3/dao-service/default.go
@@ -2,9 +2,11 @@ package dao_service
import (
"fmt"
+
"github.com/eolinker/goku-api-gateway/common/database"
)
+//SetDefault 设置默认服务
func SetDefault(name string) error {
count := 0
err := database.GetConnection().QueryRow("SELECT count(1) FROM `goku_service_config` WHERE `name` = ?;", name).Scan(&count)
diff --git a/server/dao/console-mysql/dao-service/delete.go b/server/dao/console-sqlite3/dao-service/delete.go
similarity index 94%
rename from server/dao/console-mysql/dao-service/delete.go
rename to server/dao/console-sqlite3/dao-service/delete.go
index 7211b9dc7c035a6e03585d010fb1ca2d7bd04150..e17fef74e3df520df7504566e76bcaa417468bf7 100644
--- a/server/dao/console-mysql/dao-service/delete.go
+++ b/server/dao/console-sqlite3/dao-service/delete.go
@@ -2,17 +2,20 @@ package dao_service
import (
"fmt"
+
"github.com/eolinker/goku-api-gateway/common/database"
)
const sqlDelete = "DELETE FROM `goku_service_config` WHERE `name` = ? AND NOT EXISTS (SELECT * FROM `goku_balance` B WHERE B.`serviceName` = `goku_service_config`.`name` ) "
+//DeleteError delete error
type DeleteError string
func (e DeleteError) Error() string {
return fmt.Sprintf("can not delete :%s", string(e))
}
+//Delete 删除服务发现
func Delete(names []string) error {
tx, err := database.GetConnection().Begin()
diff --git a/server/dao/console-mysql/dao-service/get.go b/server/dao/console-sqlite3/dao-service/get.go
similarity index 97%
rename from server/dao/console-mysql/dao-service/get.go
rename to server/dao/console-sqlite3/dao-service/get.go
index fff766f6520c68a80e377522df9c1c2223a1e7a5..ddff8f963748b4d655e66fc8afae0e7f224c1ee3 100644
--- a/server/dao/console-mysql/dao-service/get.go
+++ b/server/dao/console-sqlite3/dao-service/get.go
@@ -2,12 +2,14 @@ package dao_service
import (
"fmt"
+
"github.com/eolinker/goku-api-gateway/common/database"
entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity"
)
const sqlGet = "SELECT `name`,`driver`,`default`,`desc`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut`,`createTime`,`updateTime` FROM `goku_service_config` WHERE `name`=?; "
+//Get 获取服务发现信息
func Get(name string) (*entity.Service, error) {
stmt, e := database.GetConnection().Prepare(sqlGet)
diff --git a/server/dao/console-mysql/dao-service/list.go b/server/dao/console-sqlite3/dao-service/list.go
similarity index 97%
rename from server/dao/console-mysql/dao-service/list.go
rename to server/dao/console-sqlite3/dao-service/list.go
index e86597a50ae830da9e151944de781982a9d11be5..cc434ac500a191ad3aa9aa63f48641ba4263f4a4 100644
--- a/server/dao/console-mysql/dao-service/list.go
+++ b/server/dao/console-sqlite3/dao-service/list.go
@@ -9,6 +9,7 @@ import (
const sqlList = "SELECT `name`,`driver`,`default`,`desc`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut`,`createTime`,`updateTime` FROM `goku_service_config` %s ORDER BY `updateTime` DESC;"
+//List 获取服务发现列表
func List(keyword string) ([]*entity.Service, error) {
where := ""
if keyword != "" {
diff --git a/server/dao/console-mysql/dao-service/save.go b/server/dao/console-sqlite3/dao-service/save.go
similarity index 89%
rename from server/dao/console-mysql/dao-service/save.go
rename to server/dao/console-sqlite3/dao-service/save.go
index 6ea863f3cc89884f358c8f1ba6492cbe4b1f6ae3..ad54a28288ef63d5fbeccd796b2a6fddd8ca6dbf 100644
--- a/server/dao/console-mysql/dao-service/save.go
+++ b/server/dao/console-sqlite3/dao-service/save.go
@@ -1,14 +1,16 @@
package dao_service
import (
- "github.com/eolinker/goku-api-gateway/common/database"
"time"
+
+ "github.com/eolinker/goku-api-gateway/common/database"
)
const sqlSave = "UPDATE `goku_service_config` SET `desc`=?,`config`=?,`clusterConfig`=?,`healthCheck`=?,`healthCheckPath`=?,`healthCheckPeriod`=?,`healthCheckCode`=?,`healthCheckTimeOut`=?,`updateTime`=? WHERE `name`=?;"
+//Save 存储服务发现信息
func Save(name, desc, config, clusterConfig string, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error {
- now := time.Now()
+ now := time.Now().Format("2006-01-02 15:04:05")
stmt, e := database.GetConnection().Prepare(sqlSave)
if e != nil {
diff --git a/server/dao/console-sqlite3/dao-version-config/api.go b/server/dao/console-sqlite3/dao-version-config/api.go
new file mode 100644
index 0000000000000000000000000000000000000000..28e5629fec7a743cada0be642833e97d51a7011d
--- /dev/null
+++ b/server/dao/console-sqlite3/dao-version-config/api.go
@@ -0,0 +1,94 @@
+package dao_version_config
+
+import (
+ "encoding/json"
+ "strings"
+
+ "github.com/eolinker/goku-api-gateway/common/database"
+ "github.com/eolinker/goku-api-gateway/config"
+)
+
+//GetAPIContent 获取接口信息
+func GetAPIContent() ([]*config.APIContent, error) {
+ db := database.GetConnection()
+ sql := "SELECT apiID,apiName,IFNULL(protocol,'http'),IFNULL(balanceName,''),IFNULL(targetURL,''),CASE WHEN isFollow = 'true' THEN 'FOLLOW' ELSE targetMethod END targetMethod,responseDataType,requestURL,requestMethod,timeout,alertValve,retryCount,IFNULL(linkApis,''),IFNULL(staticResponse,'') FROM goku_gateway_api"
+ rows, err := db.Query(sql)
+ if err != nil {
+ return nil, err
+ }
+
+ apiContents := make([]*config.APIContent, 0, 100)
+ defer rows.Close()
+ for rows.Next() {
+ var apiContent config.APIContent
+ var linkApisStr, protocol, balance, targetURL, targetMethod, requestMethod string
+ var retryCount int
+ linkApis := make([]config.APIStepUIConfig, 0)
+ err = rows.Scan(&apiContent.ID, &apiContent.Name, &protocol, &balance, &targetURL, &targetMethod, &apiContent.OutPutEncoder, &apiContent.RequestURL, &requestMethod, &apiContent.TimeOutTotal, &apiContent.AlertThreshold, &retryCount, &linkApisStr, &apiContent.StaticResponse)
+ if err != nil {
+ return nil, err
+ }
+ if linkApisStr != "" {
+ err = json.Unmarshal([]byte(linkApisStr), &linkApis)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ apiContent.Methods = strings.Split(requestMethod, ",")
+ if len(linkApis) < 1 {
+ apiContent.Steps = append(apiContent.Steps, &config.APIStepConfig{
+ Proto: protocol,
+ Balance: balance,
+ Path: targetURL,
+ Method: targetMethod,
+ Encode: "origin",
+ Decode: apiContent.OutPutEncoder,
+ TimeOut: apiContent.TimeOutTotal,
+ Retry: retryCount,
+ })
+ } else {
+ for _, api := range linkApis {
+ actions := make([]*config.ActionConfig, 0, 20)
+ for _, del := range api.Delete {
+ actions = append(actions, &config.ActionConfig{
+ ActionType: "delete",
+ Original: del.Origin,
+ })
+ }
+ for _, move := range api.Move {
+ actions = append(actions, &config.ActionConfig{
+ ActionType: "move",
+ Original: move.Origin,
+ Target: move.Target,
+ })
+ }
+ for _, rename := range api.Rename {
+ actions = append(actions, &config.ActionConfig{
+ ActionType: "rename",
+ Original: rename.Origin,
+ Target: rename.Target,
+ })
+ }
+ apiContent.Steps = append(apiContent.Steps, &config.APIStepConfig{
+ Proto: api.Proto,
+ Balance: api.Balance,
+ Path: api.Path,
+ Body: api.Body,
+ Method: api.Method,
+ Encode: api.Encode,
+ Decode: api.Decode,
+ TimeOut: api.TimeOut,
+ Retry: api.Retry,
+ Group: api.Group,
+ Target: api.Target,
+ WhiteList: api.WhiteList,
+ BlackList: api.BlackList,
+ Actions: actions,
+ })
+ }
+ }
+ apiContents = append(apiContents, &apiContent)
+ }
+ return apiContents, nil
+}
diff --git a/server/dao/console-sqlite3/dao-version-config/balance.go b/server/dao/console-sqlite3/dao-version-config/balance.go
new file mode 100644
index 0000000000000000000000000000000000000000..873e5a50103e7f12a346ef05d29d700b4dad35df
--- /dev/null
+++ b/server/dao/console-sqlite3/dao-version-config/balance.go
@@ -0,0 +1,58 @@
+package dao_version_config
+
+import (
+ "encoding/json"
+
+ "github.com/eolinker/goku-api-gateway/common/database"
+ "github.com/eolinker/goku-api-gateway/config"
+ entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity"
+)
+
+//GetBalances 获取balance信息
+func GetBalances(clusters []*entity.Cluster) (map[string]map[string]*config.BalanceConfig, error) {
+ db := database.GetConnection()
+ sql := "SELECT goku_balance.balanceName,goku_balance.static,goku_balance.staticCluster,goku_balance.serviceName,goku_balance.appName,goku_service_config.driver FROM goku_balance INNER JOIN goku_service_config ON goku_service_config.`name` = goku_balance.serviceName"
+ rows, err := db.Query(sql)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ balanceMaps := make(map[string]map[string]*config.BalanceConfig)
+ for rows.Next() {
+ var balanceName, static, staticCluster, serviceName, appName, driver string
+ err = rows.Scan(&balanceName, &static, &staticCluster, &serviceName, &appName, &driver)
+ staticMap := make(map[string]string)
+ if staticCluster != "" {
+ err := json.Unmarshal([]byte(staticCluster), &staticMap)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ for _, c := range clusters {
+ if _, ok := balanceMaps[c.Name]; !ok {
+ balanceMaps[c.Name] = make(map[string]*config.BalanceConfig)
+ }
+ if driver != "static" {
+ balanceMaps[c.Name][balanceName] = &config.BalanceConfig{
+ Name: balanceName,
+ DiscoverName: serviceName,
+ Config: appName,
+ }
+ continue
+ }
+ staticBalance := static
+ if v, ok := staticMap[c.Name]; ok {
+ staticBalance = v
+ }
+
+ balanceMaps[c.Name][balanceName] = &config.BalanceConfig{
+ Name: balanceName,
+ DiscoverName: serviceName,
+ Config: staticBalance,
+ }
+ }
+
+ }
+ return balanceMaps, nil
+}
diff --git a/server/dao/console-sqlite3/dao-version-config/discovery.go b/server/dao/console-sqlite3/dao-version-config/discovery.go
new file mode 100644
index 0000000000000000000000000000000000000000..6bd56849a881129cd9b3907119cbb3058b6c7400
--- /dev/null
+++ b/server/dao/console-sqlite3/dao-version-config/discovery.go
@@ -0,0 +1,72 @@
+package dao_version_config
+
+import (
+ "encoding/json"
+
+ entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity"
+
+ "github.com/eolinker/goku-api-gateway/common/database"
+ "github.com/eolinker/goku-api-gateway/config"
+)
+
+func GetDiscoverConfig(clusters []*entity.Cluster) (map[string]map[string]*config.DiscoverConfig, error) {
+ db := database.GetConnection()
+ sql := "SELECT `name`,`driver`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut` FROM goku_service_config"
+ rows, err := db.Query(sql)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ discoverMaps := make(map[string]map[string]*config.DiscoverConfig)
+ for rows.Next() {
+ var name, discoverConfig, clusterConfig, healthCheckPath, healthCheckCode, driver string
+ var healthCheck bool
+ var healthCheckPeriod, healthCheckTimeOut int
+ err = rows.Scan(&name, &driver, &discoverConfig, &clusterConfig, &healthCheck, &healthCheckPath, &healthCheckPeriod, &healthCheckCode, &healthCheckTimeOut)
+
+ configMap := make(map[string]string)
+ if clusterConfig != "" {
+ err := json.Unmarshal([]byte(clusterConfig), &configMap)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ for _, c := range clusters {
+ if _, ok := discoverMaps[c.Name]; !ok {
+ discoverMaps[c.Name] = make(map[string]*config.DiscoverConfig)
+ }
+ if driver == "static" {
+ discoverMaps[c.Name][name] = &config.DiscoverConfig{
+ Name: name,
+ Driver: driver,
+ HealthCheck: &config.HealthCheckConfig{
+ IsHealthCheck: healthCheck,
+ URL: healthCheckPath,
+ Second: healthCheckPeriod,
+ TimeOutMill: healthCheckTimeOut,
+ StatusCode: healthCheckCode,
+ },
+ }
+ continue
+ }
+ defaultConfig := discoverConfig
+ if v, ok := configMap[c.Name]; ok {
+ defaultConfig = v
+ }
+ discoverMaps[c.Name][name] = &config.DiscoverConfig{
+ Name: name,
+ Driver: driver,
+ Config: defaultConfig,
+ HealthCheck: &config.HealthCheckConfig{
+ IsHealthCheck: healthCheck,
+ URL: healthCheckPath,
+ Second: healthCheckPeriod,
+ TimeOutMill: healthCheckTimeOut,
+ StatusCode: healthCheckCode,
+ },
+ }
+ }
+ }
+ return discoverMaps, nil
+}
diff --git a/server/dao/console-sqlite3/dao-version-config/log.go b/server/dao/console-sqlite3/dao-version-config/log.go
new file mode 100644
index 0000000000000000000000000000000000000000..460b65c0e6f02167e5154520a1b40b3c2b1f8654
--- /dev/null
+++ b/server/dao/console-sqlite3/dao-version-config/log.go
@@ -0,0 +1,61 @@
+package dao_version_config
+
+import (
+ "encoding/json"
+
+ "github.com/eolinker/goku-api-gateway/common/database"
+ "github.com/eolinker/goku-api-gateway/config"
+)
+
+func GetLogInfo() (*config.LogConfig, *config.AccessLogConfig, error) {
+ db := database.GetConnection()
+ sql := "SELECT `name`,`enable`,`dir`,`file`,`period`,IFNULL(`level`,''),IFNULL(`fields`,''),`expire` FROM goku_config_log;"
+ rows, err := db.Query(sql)
+ if err != nil {
+ return nil, nil, err
+ }
+ defer rows.Close()
+ var logCf *config.LogConfig
+ var accessCf *config.AccessLogConfig
+ for rows.Next() {
+ var name, dir, file, level, fields, period string
+ var enable, expire int
+ err = rows.Scan(&name, &enable, &dir, &file, &period, &level, &fields, &expire)
+ if err != nil {
+ return nil, nil, err
+ }
+ if name == "console" {
+ continue
+ } else if name == "access" {
+ tmp := make([]map[string]interface{}, 0)
+ err = json.Unmarshal([]byte(fields), &tmp)
+ if err != nil {
+ return nil, nil, err
+ }
+ fields := make([]string, 0)
+ for _, t := range tmp {
+ fields = append(fields, t["name"].(string))
+ }
+ accessCf = &config.AccessLogConfig{
+ Name: name,
+ Enable: enable,
+ Dir: dir,
+ File: file,
+ Period: period,
+ Expire: expire,
+ Fields: fields,
+ }
+ } else if name == "node" {
+ logCf = &config.LogConfig{
+ Name: name,
+ Enable: enable,
+ Dir: dir,
+ File: file,
+ Period: period,
+ Level: level,
+ Expire: expire,
+ }
+ }
+ }
+ return logCf, accessCf, nil
+}
diff --git a/server/dao/console-sqlite3/dao-version-config/plugin.go b/server/dao/console-sqlite3/dao-version-config/plugin.go
new file mode 100644
index 0000000000000000000000000000000000000000..a1962695fddca27ad406e50240feb8e10b3afb3c
--- /dev/null
+++ b/server/dao/console-sqlite3/dao-version-config/plugin.go
@@ -0,0 +1,119 @@
+package dao_version_config
+
+import (
+ "strconv"
+
+ "github.com/eolinker/goku-api-gateway/common/database"
+ "github.com/eolinker/goku-api-gateway/config"
+)
+
+//GetGlobalPlugin 获取全局插件
+func GetGlobalPlugin() (*config.GatewayPluginConfig, error) {
+ db := database.GetConnection()
+ sql := "SELECT pluginName,isStop,IFNULL(pluginConfig,''),pluginType FROM goku_plugin"
+ rows, err := db.Query(sql)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ pluginConfigs := config.GatewayPluginConfig{
+ BeforePlugins: make([]*config.PluginConfig, 0, 20),
+ GlobalPlugins: make([]*config.PluginConfig, 0, 20),
+ }
+ for rows.Next() {
+ var pluginName, pluginConfig string
+ var isStop bool
+ var pluginType int
+ err = rows.Scan(&pluginName, &isStop, &pluginConfig, &pluginType)
+ if err != nil {
+ return nil, err
+ }
+ if pluginType == 0 {
+ pluginConfigs.GlobalPlugins = append(pluginConfigs.GlobalPlugins, &config.PluginConfig{
+ Name: pluginName,
+ IsStop: isStop,
+ Config: pluginConfig,
+ })
+ } else {
+ pluginConfigs.BeforePlugins = append(pluginConfigs.BeforePlugins, &config.PluginConfig{
+ Name: pluginName,
+ IsStop: isStop,
+ Config: pluginConfig,
+ })
+ }
+ }
+ return &pluginConfigs, nil
+}
+
+//GetAPIPlugins 获取接口插件
+func GetAPIPlugins() (map[string][]*config.PluginConfig, error) {
+ db := database.GetConnection()
+ sql := "SELECT goku_conn_plugin_api.apiID,goku_conn_plugin_api.strategyID,goku_conn_plugin_api.pluginName,goku_conn_plugin_api.pluginConfig,goku_plugin.isStop,goku_conn_plugin_api.updateTag FROM goku_conn_plugin_api INNER JOIN goku_plugin ON goku_conn_plugin_api.pluginName = goku_plugin.pluginName"
+ rows, err := db.Query(sql)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ pluginMaps := make(map[string][]*config.PluginConfig)
+ for rows.Next() {
+ var apiID int
+ var isStop bool
+ var pluginName, pluginConfig, updateTag, strategyID string
+ err = rows.Scan(&apiID, &strategyID, &pluginName, &pluginConfig, &isStop, &updateTag)
+ if err != nil {
+ return nil, err
+ }
+ key := strategyID + ":" + strconv.Itoa(apiID)
+ if _, ok := pluginMaps[key]; !ok {
+ pluginMaps[key] = make([]*config.PluginConfig, 0, 20)
+ }
+ pluginMaps[key] = append(pluginMaps[key], &config.PluginConfig{
+ Name: pluginName,
+ IsStop: isStop,
+ Config: pluginConfig,
+ UpdateTag: updateTag,
+ })
+ }
+ return pluginMaps, nil
+
+}
+
+//GetStrategyPlugins 获取策略插件
+func GetStrategyPlugins() (map[string][]*config.PluginConfig, map[string]map[string]string, error) {
+ db := database.GetConnection()
+ sql := "SELECT goku_conn_plugin_strategy.strategyID,goku_conn_plugin_strategy.pluginName,goku_conn_plugin_strategy.pluginConfig,goku_plugin.isStop,goku_conn_plugin_strategy.updateTag FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_conn_plugin_strategy.pluginName = goku_plugin.pluginName WHERE goku_plugin.pluginStatus = 1 AND goku_conn_plugin_strategy.pluginStatus = 1"
+ rows, err := db.Query(sql)
+ if err != nil {
+ return nil, nil, err
+ }
+ defer rows.Close()
+ pluginMaps := make(map[string][]*config.PluginConfig)
+ authMaps := make(map[string]map[string]string)
+ for rows.Next() {
+ var isStop bool
+ var pluginName, pluginConfig, updateTag, strategyID string
+ err = rows.Scan(&strategyID, &pluginName, &pluginConfig, &isStop, &updateTag)
+ if err != nil {
+ return nil, nil, err
+ }
+ key := strategyID
+ if _, ok := pluginMaps[key]; !ok {
+ pluginMaps[key] = make([]*config.PluginConfig, 0, 20)
+ }
+ if v, ok := autoAuthNames[pluginName]; ok {
+ if _, ok := authMaps[key]; !ok {
+ authMaps[key] = make(map[string]string)
+ }
+ authMaps[key][v] = pluginConfig
+ }
+
+ pluginMaps[key] = append(pluginMaps[key], &config.PluginConfig{
+ Name: pluginName,
+ IsStop: isStop,
+ Config: pluginConfig,
+ UpdateTag: updateTag,
+ })
+ }
+ return pluginMaps, authMaps, nil
+
+}
diff --git a/server/dao/console-sqlite3/dao-version-config/strategy.go b/server/dao/console-sqlite3/dao-version-config/strategy.go
new file mode 100644
index 0000000000000000000000000000000000000000..b6508b437ef5884dd7f225a532841319b6fa8fe1
--- /dev/null
+++ b/server/dao/console-sqlite3/dao-version-config/strategy.go
@@ -0,0 +1,98 @@
+package dao_version_config
+
+import (
+ "strconv"
+
+ "github.com/eolinker/goku-api-gateway/common/database"
+ "github.com/eolinker/goku-api-gateway/config"
+)
+
+var autoAuthNames = map[string]string{
+ "goku-oauth2_auth": "Oauth2",
+ "goku-apikey_auth": "Apikey",
+ "goku-basic_auth": "Basic",
+ "goku-jwt_auth": "Jwt",
+}
+
+//GetAPIsOfStrategy 获取策略内接口数据
+func GetAPIsOfStrategy() (map[string][]*config.APIOfStrategy, error) {
+ db := database.GetConnection()
+ sql := "SELECT goku_conn_strategy_api.apiID,IFNULL(goku_conn_strategy_api.target,''),goku_conn_strategy_api.strategyID FROM goku_conn_strategy_api;"
+ rows, err := db.Query(sql)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ apiPlugins, err := GetAPIPlugins()
+ if err != nil {
+ return nil, err
+ }
+ apiMaps := make(map[string][]*config.APIOfStrategy)
+ for rows.Next() {
+ var apiID int
+ var balanceName, strategyID string
+ err = rows.Scan(&apiID, &balanceName, &strategyID)
+ if err != nil {
+ return nil, err
+ }
+ if _, ok := apiMaps[strategyID]; !ok {
+ apiMaps[strategyID] = make([]*config.APIOfStrategy, 0, 20)
+ }
+ ap := make([]*config.PluginConfig, 0)
+ key := strategyID + ":" + strconv.Itoa(apiID)
+ if v, ok := apiPlugins[key]; ok {
+ ap = v
+ }
+ apiMaps[strategyID] = append(apiMaps[strategyID], &config.APIOfStrategy{
+ ID: apiID,
+ Balance: balanceName,
+ Plugins: ap,
+ })
+ }
+ return apiMaps, nil
+}
+
+//GetStrategyConfig 获取策略配置
+func GetStrategyConfig() (string, []*config.StrategyConfig, error) {
+ db := database.GetConnection()
+ sql := "SELECT strategyID,strategyName,enableStatus,strategyType FROM goku_gateway_strategy"
+
+ rows, err := db.Query(sql)
+ if err != nil {
+ return "", nil, err
+ }
+ defer rows.Close()
+ strategyConfigs := make([]*config.StrategyConfig, 0, 20)
+ strategyPlugins, authMaps, err := GetStrategyPlugins()
+ if err != nil {
+ return "", nil, err
+ }
+ apiOfStrategy, err := GetAPIsOfStrategy()
+ if err != nil {
+ return "", nil, err
+ }
+ openStrategy := ""
+ for rows.Next() {
+ var strategyConfig config.StrategyConfig
+ var strategyType int
+ err = rows.Scan(&strategyConfig.ID, &strategyConfig.Name, &strategyConfig.Enable, &strategyType)
+ if err != nil {
+ return "", nil, err
+ }
+ if _, ok := strategyPlugins[strategyConfig.ID]; ok {
+ strategyConfig.Plugins = strategyPlugins[strategyConfig.ID]
+ }
+ if _, ok := authMaps[strategyConfig.ID]; ok {
+ strategyConfig.AUTH = authMaps[strategyConfig.ID]
+ }
+ if _, ok := apiOfStrategy[strategyConfig.ID]; ok {
+ strategyConfig.APIS = apiOfStrategy[strategyConfig.ID]
+ }
+ if strategyType == 1 {
+ openStrategy = strategyConfig.ID
+ }
+ strategyConfigs = append(strategyConfigs, &strategyConfig)
+ }
+ return openStrategy, strategyConfigs, nil
+
+}
diff --git a/server/dao/console-mysql/gateway.go b/server/dao/console-sqlite3/gateway.go
similarity index 71%
rename from server/dao/console-mysql/gateway.go
rename to server/dao/console-sqlite3/gateway.go
index 16c6bf0d53810db844632242489ea5dd2d967dc2..e77ec6627734456d5ff591ce42dd18f0c71b5535 100644
--- a/server/dao/console-mysql/gateway.go
+++ b/server/dao/console-sqlite3/gateway.go
@@ -1,4 +1,4 @@
-package consolemysql
+package console_sqlite3
import (
database2 "github.com/eolinker/goku-api-gateway/common/database"
@@ -23,7 +23,7 @@ func GetGatewayConfig() (map[string]interface{}, error) {
return gatewayConfig, nil
}
-// EditGatewayBaseConfig 编辑网关基本配置
+//EditGatewayBaseConfig 编辑网关基本配置
func EditGatewayBaseConfig(successCode string, nodeUpdatePeriod, monitorUpdatePeriod, monitorTimeout int) (bool, string, error) {
db := database2.GetConnection()
sql := "SELECT successCode FROM goku_gateway WHERE id = 1;"
@@ -45,7 +45,7 @@ func EditGatewayBaseConfig(successCode string, nodeUpdatePeriod, monitorUpdatePe
return true, "", nil
}
-// EditGatewayAlarmConfig 编辑网关告警配置
+//EditGatewayAlarmConfig 编辑网关告警配置
func EditGatewayAlarmConfig(apiAlertInfo, sender, senderPassword, smtpAddress string, alertStatus, smtpPort, smtpProtocol int) (bool, string, error) {
db := database2.GetConnection()
sql := "SELECT successCode FROM goku_gateway WHERE id = 1;"
@@ -66,3 +66,39 @@ func EditGatewayAlarmConfig(apiAlertInfo, sender, senderPassword, smtpAddress st
}
return true, "", nil
}
+
+//GetGatewayInfo 获取网关信息
+func GetGatewayInfo() (nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount int, err error) {
+ db := database2.GetConnection()
+ // 获取节点启动数量
+
+ err = db.QueryRow("SELECT COUNT(0) FROM goku_node_info WHERE nodeStatus = 1;").Scan(&nodeStartCount)
+ if err != nil {
+ return
+ }
+
+ // 获取节点关闭数量
+
+ err = db.QueryRow("SELECT COUNT(0) FROM goku_node_info WHERE nodeStatus = 0;").Scan(&nodeStopCount)
+ if err != nil {
+ return
+ }
+ // 获取项目数量
+ err = db.QueryRow("SELECT COUNT(0) FROM goku_gateway_project;").Scan(&projectCount)
+ if err != nil {
+ return
+ }
+
+ // 获取api数量
+ err = db.QueryRow("SELECT COUNT(0) FROM goku_gateway_api;").Scan(&apiCount)
+ if err != nil {
+ return
+ }
+
+ // 获取策略数量
+ err = db.QueryRow("SELECT COUNT(0) FROM goku_gateway_strategy;").Scan(&strategyCount)
+ if err != nil {
+ return
+ }
+ return
+}
diff --git a/server/dao/console-mysql/guest.go b/server/dao/console-sqlite3/guest.go
similarity index 96%
rename from server/dao/console-mysql/guest.go
rename to server/dao/console-sqlite3/guest.go
index 71197d7a7f362d602fe0f163768304713bf04ce3..55547a38d9d08f13f913665f11af1bcf439ce1a8 100644
--- a/server/dao/console-mysql/guest.go
+++ b/server/dao/console-sqlite3/guest.go
@@ -1,7 +1,8 @@
-package consolemysql
+package console_sqlite3
import (
SQL "database/sql"
+
"github.com/eolinker/goku-api-gateway/common/database"
"github.com/eolinker/goku-api-gateway/utils"
)
@@ -17,7 +18,7 @@ func Login(loginCall, loginPassword string) (bool, int) {
return true, userID
}
-// CheckLogin 检查用户是否登录
+//CheckLogin 检查用户是否登录
func CheckLogin(userToken string, userID int) bool {
db := database.GetConnection()
var loginPassword, loginCall string
diff --git a/server/dao/console-sqlite3/import.go b/server/dao/console-sqlite3/import.go
new file mode 100644
index 0000000000000000000000000000000000000000..5bf1f9f53ef704ec986e098f981d875e6984fddf
--- /dev/null
+++ b/server/dao/console-sqlite3/import.go
@@ -0,0 +1,157 @@
+package console_sqlite3
+
+import (
+ SQL "database/sql"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+
+ database2 "github.com/eolinker/goku-api-gateway/common/database"
+ entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity"
+)
+
+var method = []string{"POST", "GET", "PUT", "DELETE", "HEAD", "OPTIONS", "PATCH"}
+
+// 导入接口信息
+func importAPIInfo(Tx *SQL.Tx, api entity.AmsAPIInfo, projectID, groupID, userID int, now string) bool {
+ // 新增API
+ requestURL := ""
+ host := ""
+ protocol := "http"
+ u, err := url.ParseRequestURI(api.BaseInfo.APIURI)
+ if err == nil {
+ requestURL = u.Path
+ if u.Scheme != "" {
+ protocol = strings.ToLower(u.Scheme)
+ if u.Host != "" {
+ host = strings.ToLower(u.Host)
+ }
+ }
+ } else {
+ requestURL = api.BaseInfo.APIURI
+ }
+ stripSlash := true
+ log.Debug(protocol, host, stripSlash)
+ requestMethod := method[api.BaseInfo.APIRequestType]
+ _, err = Tx.Exec("INSERT INTO goku_gateway_api (projectID,groupID,apiName,requestURL,targetURL,requestMethod,targetMethod,isFollow,stripPrefix,timeout,retryCount,createTime,updateTime,protocol,balanceName,stripSlash,responseDataType,managerID,lastUpdateUserID,createUserID) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", projectID, groupID, api.BaseInfo.APIName, requestURL, requestURL, requestMethod, requestMethod, "true", "true", 2000, 0, now, now, protocol, host, stripSlash, "origin", userID, userID, userID)
+ if err != nil {
+ log.Error(err)
+ return false
+ }
+ return true
+}
+
+func recursiveImportAPIGroupFromAms(Tx *SQL.Tx, projectID, userID int, groupInfo entity.AmsGroupInfo, groupDepth, parentGroupID int, groupPath, now string) (bool, string, error) {
+ // 插入分组信息
+ result, err := Tx.Exec("INSERT INTO goku_gateway_api_group (projectID,groupName,groupDepth,parentGroupID) VALUES (?,?,?,?);", projectID, groupInfo.GroupName, groupDepth, parentGroupID)
+ if err != nil {
+ info := err.Error()
+ log.Info(info)
+ return false, err.Error(), err
+ }
+ groupID, err := result.LastInsertId()
+ if err != nil {
+ info := err.Error()
+ log.Info(info)
+ return false, err.Error(), err
+ }
+ if groupPath == "" {
+ groupPath = strconv.Itoa(int(groupID))
+ } else {
+ groupPath = groupPath + "," + strconv.Itoa(int(groupID))
+ }
+
+ // 更新groupPath
+ _, err = Tx.Exec("UPDATE goku_gateway_api_group SET groupPath = ? WHERE groupID = ?;", groupPath, groupID)
+ if err != nil {
+ info := err.Error()
+ log.Info(info)
+ return false, err.Error(), err
+ }
+ for _, childGroup := range groupInfo.APIGroupChildList {
+ _, _, err := recursiveImportAPIGroupFromAms(Tx, projectID, userID, childGroup, groupDepth+1, int(groupID), groupPath, now)
+ if err != nil {
+ continue
+ }
+ }
+ for _, childGroup := range groupInfo.ChildGroupList {
+ _, _, err := recursiveImportAPIGroupFromAms(Tx, projectID, userID, childGroup, groupDepth+1, int(groupID), groupPath, now)
+ if err != nil {
+ continue
+ }
+ }
+ for _, api := range groupInfo.APIList {
+ flag := importAPIInfo(Tx, api, projectID, int(groupID), userID, now)
+ if !flag {
+ continue
+ }
+ }
+ return true, "", nil
+}
+
+//ImportAPIGroupFromAms 导入分组
+func ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) (bool, string, error) {
+ db := database2.GetConnection()
+ Tx, _ := db.Begin()
+ now := time.Now().Format("2006-01-02 15:04:05")
+ _, errInfo, err := recursiveImportAPIGroupFromAms(Tx, projectID, userID, groupInfo, 1, 0, "", now)
+ if err != nil {
+ Tx.Rollback()
+ return false, errInfo, err
+ }
+ // 更新项目更新时间
+ _, err = Tx.Exec("UPDATE goku_gateway_project SET updateTime = ? WHERE projectID = ?;", now, projectID)
+ if err != nil {
+ Tx.Rollback()
+ return false, "[ERROR]Fail to update data!", err
+ }
+ Tx.Commit()
+ return true, "", nil
+}
+
+//ImportProjectFromAms 导入项目
+func ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, string, error) {
+ db := database2.GetConnection()
+ Tx, _ := db.Begin()
+ now := time.Now().Format("2006-01-02 15:04:05")
+ // 插入项目信息
+ projectResult, err := Tx.Exec("INSERT INTO goku_gateway_project (projectName,updateTime,createTime) VALUES (?,?,?)", projectInfo.ProjectInfo.ProjectName, now, now)
+ if err != nil {
+ Tx.Rollback()
+ log.Info(err.Error())
+ return false, err.Error(), err
+ }
+ projectID, err := projectResult.LastInsertId()
+ if err != nil {
+ Tx.Rollback()
+ log.Info(err.Error())
+ return false, err.Error(), err
+ }
+ id := int(projectID)
+ for _, groupInfo := range projectInfo.APIGroupList {
+ _, _, err := recursiveImportAPIGroupFromAms(Tx, id, userID, groupInfo, 1, 0, "", now)
+ if err != nil {
+ continue
+ }
+ }
+ Tx.Commit()
+ return true, "", nil
+}
+
+//ImportAPIFromAms 从ams中导入接口
+func ImportAPIFromAms(projectID, groupID, userID int, apiList []entity.AmsAPIInfo) (bool, string, error) {
+ db := database2.GetConnection()
+ Tx, _ := db.Begin()
+ now := time.Now().Format("2006-01-02 15:04:05")
+ for _, a := range apiList {
+ flag := importAPIInfo(Tx, a, projectID, groupID, userID, now)
+ if !flag {
+ continue
+ }
+ }
+ Tx.Commit()
+ return true, "", nil
+}
diff --git a/server/dao/console-mysql/node.go b/server/dao/console-sqlite3/node.go
similarity index 93%
rename from server/dao/console-mysql/node.go
rename to server/dao/console-sqlite3/node.go
index c0434bcc76e3615f30dd4d2a90d7ce47120b9dcf..19aa3f6f14726d7b8666b08360684bab474d6a8e 100644
--- a/server/dao/console-mysql/node.go
+++ b/server/dao/console-sqlite3/node.go
@@ -1,16 +1,17 @@
-package consolemysql
+package console_sqlite3
import (
"fmt"
- "github.com/eolinker/goku-api-gateway/common/database"
- v "github.com/eolinker/goku-api-gateway/common/version"
- entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity"
"strconv"
"strings"
"time"
+
+ "github.com/eolinker/goku-api-gateway/common/database"
+ v "github.com/eolinker/goku-api-gateway/common/version"
+ entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity"
)
-// AddNode 新增节点信息
+//AddNode 新增节点信息
func AddNode(clusterID int, nodeName, nodeIP, nodePort, gatewayPath string, groupID int) (bool, map[string]interface{}, error) {
db := database.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
@@ -31,7 +32,7 @@ func AddNode(clusterID int, nodeName, nodeIP, nodePort, gatewayPath string, grou
return true, map[string]interface{}{"nodeID": nodeID, "version": v.Version}, nil
}
-// EditNode 修改节点信息
+//EditNode 修改节点信息
func EditNode(nodeName, nodeIP, nodePort, gatewayPath string, nodeID, groupID int) (bool, string, error) {
db := database.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
@@ -48,7 +49,7 @@ func EditNode(nodeName, nodeIP, nodePort, gatewayPath string, nodeID, groupID in
return true, "", nil
}
-// DeleteNode 删除节点信息
+//DeleteNode 删除节点信息
func DeleteNode(nodeID int) (bool, string, error) {
db := database.GetConnection()
sql := "DELETE FROM goku_node_info WHERE nodeID = ?;"
@@ -95,7 +96,6 @@ func GetNodeList(clusterID, groupID int, keyword string) (bool, []*entity.Node,
node := entity.Node{}
err = rows.Scan(&node.NodeID, &node.NodeName, &node.NodeIP, &node.NodePort, &node.UpdateTime, &node.CreateTime, &node.Version, &node.GatewayPath, &node.GroupID, &node.GroupName)
if err != nil {
- panic(err)
return false, nil, err
}
if node.Version == v.Version {
@@ -133,19 +133,18 @@ func getNodeInfo(sql string, args ...interface{}) (bool, *entity.Node, error) {
return true, node, err
}
-// GetNodeInfo 获取节点信息
+//GetNodeInfo 获取节点信息
func GetNodeInfo(nodeID int) (bool, *entity.Node, error) {
return getNodeInfo(nodeSQLID, nodeID)
}
-//GetNodeByIPPort 通过IP+端口获取节点信息
+//GetNodeByIPPort 通过IP和端口查询节点信息
func GetNodeByIPPort(ip string, port int) (bool, *entity.Node, error) {
-
return getNodeInfo(nodeSQLIPPort, ip, port)
}
-// CheckIsExistRemoteAddr 节点IP查重
+//CheckIsExistRemoteAddr 节点IP查重
func CheckIsExistRemoteAddr(nodeID int, nodeIP, nodePort string) bool {
db := database.GetConnection()
sql := `SELECT nodeID FROM goku_node_info WHERE nodeIP = ? AND nodePort = ?;`
@@ -160,7 +159,7 @@ func CheckIsExistRemoteAddr(nodeID int, nodeIP, nodePort string) bool {
return true
}
-// GetNodeIPList 获取节点IP列表
+//GetNodeIPList 获取节点IP列表
func GetNodeIPList() (bool, []map[string]interface{}, error) {
db := database.GetConnection()
sql := `SELECT nodeID,nodeIP,nodePort FROM goku_node_info WHERE nodeStatus = 1;`
@@ -189,7 +188,7 @@ func GetNodeIPList() (bool, []map[string]interface{}, error) {
return true, nodeList, nil
}
-// GetAvaliableNodeListFromNodeList 从待操作节点中获取关闭节点列表
+//GetAvaliableNodeListFromNodeList 从待操作节点中获取关闭节点列表
func GetAvaliableNodeListFromNodeList(nodeIDList string, nodeStatus int) (bool, string, error) {
db := database.GetConnection()
sql := "SELECT nodeID FROM goku_node_info WHERE nodeID IN (" + nodeIDList + ") AND nodeStatus = ?"
@@ -207,11 +206,10 @@ func GetAvaliableNodeListFromNodeList(nodeIDList string, nodeStatus int) (bool,
}
idList = append(idList, strconv.Itoa(nodeID))
}
- fmt.Println(sql, nodeStatus)
return true, strings.Join(idList, ","), nil
}
-// BatchEditNodeGroup 批量修改节点分组
+//BatchEditNodeGroup 批量修改节点分组
func BatchEditNodeGroup(nodeIDList string, groupID int) (bool, string, error) {
db := database.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
@@ -226,7 +224,7 @@ func BatchEditNodeGroup(nodeIDList string, groupID int) (bool, string, error) {
return true, "", nil
}
-// BatchDeleteNode 批量修改接口分组
+//BatchDeleteNode 批量修改接口分组
func BatchDeleteNode(nodeIDList string) (bool, string, error) {
db := database.GetConnection()
Tx, _ := db.Begin()
@@ -240,7 +238,7 @@ func BatchDeleteNode(nodeIDList string) (bool, string, error) {
return true, "", nil
}
-// UpdateAllNodeClusterID 更新节点集群ID
+//UpdateAllNodeClusterID 更新节点集群ID
func UpdateAllNodeClusterID(clusterID int) {
db := database.GetConnection()
Tx, _ := db.Begin()
diff --git a/server/dao/console-mysql/nodeGroup.go b/server/dao/console-sqlite3/nodeGroup.go
similarity index 91%
rename from server/dao/console-mysql/nodeGroup.go
rename to server/dao/console-sqlite3/nodeGroup.go
index 527b3a712800daa762ced95f7f2dbe78c995dea4..bb79d220e0212bebe3254a623beb434f62de5170 100644
--- a/server/dao/console-mysql/nodeGroup.go
+++ b/server/dao/console-sqlite3/nodeGroup.go
@@ -1,10 +1,10 @@
-package consolemysql
+package console_sqlite3
import (
database2 "github.com/eolinker/goku-api-gateway/common/database"
)
-// AddNodeGroup 新建节点分组
+//AddNodeGroup 新建节点分组
func AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) {
db := database2.GetConnection()
sql := "INSERT INTO goku_node_group (`groupName`,`clusterID`) VALUES (?,?);"
@@ -21,7 +21,7 @@ func AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) {
return true, groupID, nil
}
-// EditNodeGroup 修改节点分组信息
+//EditNodeGroup 修改节点分组信息
func EditNodeGroup(groupName string, groupID int) (bool, string, error) {
db := database2.GetConnection()
sql := "UPDATE goku_node_group SET groupName = ? WHERE groupID = ?;"
@@ -37,7 +37,7 @@ func EditNodeGroup(groupName string, groupID int) (bool, string, error) {
return true, "", nil
}
-// DeleteNodeGroup 删除节点分组
+//DeleteNodeGroup 删除节点分组
func DeleteNodeGroup(groupID int) (bool, string, error) {
db := database2.GetConnection()
Tx, _ := db.Begin()
@@ -57,7 +57,7 @@ func DeleteNodeGroup(groupID int) (bool, string, error) {
return true, "", nil
}
-// GetNodeGroupInfo 获取节点分组信息
+//GetNodeGroupInfo 获取节点分组信息
func GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) {
db := database2.GetConnection()
@@ -76,7 +76,7 @@ func GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) {
return true, groupInfo, nil
}
-// GetNodeGroupList 获取节点分组列表
+//GetNodeGroupList 获取节点分组列表
func GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) {
db := database2.GetConnection()
sql := "SELECT G.`groupID`, G.groupName,C.`name` as cluster FROM goku_node_group G left join `goku_cluster` C ON C.`id` = G.`clusterID` where G.`clusterID`=?;"
@@ -87,6 +87,7 @@ func GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) {
//延时关闭Rows
defer rows.Close()
//获取记录列
+
nodeGroupList := make([]map[string]interface{}, 0)
for rows.Next() {
var groupID int
@@ -106,7 +107,7 @@ func GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) {
return true, nodeGroupList, nil
}
-// CheckNodeGroupIsExist 检查节点分组是否存在
+//CheckNodeGroupIsExist 检查节点分组是否存在
func CheckNodeGroupIsExist(groupID int) (bool, error) {
db := database2.GetConnection()
var id int
@@ -118,7 +119,7 @@ func CheckNodeGroupIsExist(groupID int) (bool, error) {
return true, nil
}
-// GetRunningNodeCount 获取分组内启动节点数量
+//GetRunningNodeCount 获取分组内启动节点数量
func GetRunningNodeCount(groupID int) (bool, interface{}, error) {
db := database2.GetConnection()
var count int
diff --git a/server/dao/console-mysql/plugin.go b/server/dao/console-sqlite3/plugin.go
similarity index 92%
rename from server/dao/console-mysql/plugin.go
rename to server/dao/console-sqlite3/plugin.go
index fa0131d27dfd6cebc9a4293e68250d7dce7829ed..2f6c915cfc7c47769ad033141709641561ad6c21 100644
--- a/server/dao/console-mysql/plugin.go
+++ b/server/dao/console-sqlite3/plugin.go
@@ -1,11 +1,10 @@
-package consolemysql
+package console_sqlite3
import (
SQL "database/sql"
"errors"
"fmt"
"strings"
- "time"
log "github.com/eolinker/goku-api-gateway/goku-log"
@@ -64,6 +63,17 @@ func GetPluginList(keyword string, condition int) (bool, []*entity.Plugin, error
return true, pluginList, nil
}
+// GetPluginCount 获取插件数量
+func GetPluginCount() int {
+ var count int
+ sql := "SELECT COUNT(*) FROM goku_plugin;"
+ err := database2.GetConnection().QueryRow(sql).Scan(&count)
+ if err != nil {
+ return 0
+ }
+ return count
+}
+
// AddPlugin 新增插件信息
func AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) {
db := database2.GetConnection()
@@ -74,7 +84,6 @@ func AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPrior
defer stmt.Close()
_, err = stmt.Exec(pluginName, pluginConfig, pluginDesc, version, 0, pluginPriority, isStop, "false", pluginType)
if err != nil {
- panic(err)
return false, "[ERROR]Failed to insert data!", err
}
return true, "", nil
@@ -128,7 +137,7 @@ func DeletePlugin(pluginName string) (bool, string, error) {
return false, "[ERROR]The plugin is not exist!", err
}
if official == "true" {
- return false, "[error]can not delete goku plugin!", errors.New("[error]can not delete goku plugin")
+ return false, "[ERROR]Can not delete goku plugin!", errors.New("[error]can not delete goku plugin")
}
Tx, _ := db.Begin()
_, err = Tx.Exec(`DELETE FROM goku_plugin WHERE pluginName = ?`, pluginName)
@@ -221,6 +230,7 @@ func GetPluginListByPluginType(pluginType int) (bool, []map[string]interface{},
defer rows.Close()
//获取记录列
pluginList := make([]map[string]interface{}, 0)
+
for rows.Next() {
var pluginID int
var pluginName, chineseName string
@@ -289,7 +299,6 @@ func BatchStartPlugin(pluginNameList string) (bool, string, error) {
//EditPluginCache 将插件配置写进缓存表中
func EditPluginCache(pluginName string, oldPluginType, pluginType int, Tx *SQL.Tx) (bool, error) {
-
if oldPluginType == 1 {
// 获取策略ID列表
sql := "SELECT strategyID FROM goku_conn_plugin_strategy WHERE pluginName = ?;"
@@ -368,28 +377,3 @@ func EditPluginCheckStatus(pluginName string, isCheck int) (bool, string, error)
}
return true, "", nil
}
-
-//UpdatePluginTagByPluginName 更新插件标志位
-func UpdatePluginTagByPluginName(pluginList string) error {
- db := database2.GetConnection()
- plugins := strings.Split(pluginList, ",")
- code := make([]string, 0, len(plugins))
- updateTag := time.Now().Format("20060102150405")
- s := make([]interface{}, 0, len(plugins)+1)
- s = append(s, updateTag)
- for i := 0; i < len(plugins); i++ {
- code = append(code, "?")
- s = append(s, plugins[i])
- }
- sql := "UPDATE goku_conn_plugin_api SET updateTag = ? WHERE pluginName IN (" + strings.Join(code, ",") + ");"
- _, err := db.Exec(sql, s...)
- if err != nil {
- return err
- }
- sql = "UPDATE goku_conn_plugin_strategy SET updateTag = ? WHERE pluginName IN (" + strings.Join(code, ",") + ");"
- _, err = db.Exec(sql, s...)
- if err != nil {
- return err
- }
- return nil
-}
diff --git a/server/dao/console-mysql/project.go b/server/dao/console-sqlite3/project.go
similarity index 95%
rename from server/dao/console-mysql/project.go
rename to server/dao/console-sqlite3/project.go
index 1959966acdaa08fc156e548ade2000dda909904d..2287263d6c7db352b2c8d893c398e4f0389b06a4 100644
--- a/server/dao/console-mysql/project.go
+++ b/server/dao/console-sqlite3/project.go
@@ -1,4 +1,4 @@
-package consolemysql
+package console_sqlite3
import (
"fmt"
@@ -60,10 +60,7 @@ func DeleteProject(projectID int) (bool, string, error) {
defer rows.Close()
//获取记录列
groupIDList := ""
- if _, err = rows.Columns(); err != nil {
- Tx.Rollback()
- return false, "", err
- }
+
for rows.Next() {
var groupID int
err = rows.Scan(&groupID)
@@ -117,13 +114,6 @@ func DeleteProject(projectID int) (bool, string, error) {
return false, "[ERROR]Fail to excute SQL statement!", err
}
- //sql = "DELETE FROM goku_gateway_api_cache WHERE apiID IN (" + apiIDList + ");"
- //_, err = Tx.Exec(sql)
- //if err != nil {
- // Tx.Rollback()
- // return false, "[ERROR]Fail to excute SQL statement!", err
- //}
-
sql = "DELETE FROM goku_conn_strategy_api WHERE apiID IN (" + apiIDList + ");"
_, err = Tx.Exec(sql)
if err != nil {
@@ -276,7 +266,6 @@ func GetProjectList(keyword string) (bool, []*entity.Project, error) {
db := database2.GetConnection()
rows, err := db.Query(sql, arg...)
if err != nil {
- panic(err)
return false, nil, err
}
//延时关闭Rows
@@ -287,7 +276,6 @@ func GetProjectList(keyword string) (bool, []*entity.Project, error) {
var project entity.Project
err = rows.Scan(&project.ProjectID, &project.ProjectName, &project.UpdateTime)
if err != nil {
- panic(err)
return false, nil, err
}
projectList = append(projectList, &project)
@@ -320,9 +308,7 @@ func GetAPIListFromProjectNotInStrategy() (bool, []map[string]interface{}, error
defer projectRows.Close()
//获取记录列
projectList := make([]map[string]interface{}, 0, 20)
- if _, err = projectRows.Columns(); err != nil {
- return false, nil, err
- }
+
for projectRows.Next() {
var projectID int
var projectName string
@@ -361,5 +347,4 @@ func GetAPIListFromProjectNotInStrategy() (bool, []map[string]interface{}, error
projectList = append(projectList, projectInfo)
}
return true, projectList, nil
-
}
diff --git a/server/dao/console-mysql/strategy.go b/server/dao/console-sqlite3/strategy.go
similarity index 86%
rename from server/dao/console-mysql/strategy.go
rename to server/dao/console-sqlite3/strategy.go
index fc7e7b706b8e168349b64b21ba84591858be5006..485f0600c6b34b84451b09dd6645449ffad73d9d 100644
--- a/server/dao/console-mysql/strategy.go
+++ b/server/dao/console-sqlite3/strategy.go
@@ -1,4 +1,4 @@
-package consolemysql
+package console_sqlite3
import (
"fmt"
@@ -163,7 +163,7 @@ func GetStrategyInfo(strategyID string) (bool, *entity.Strategy, error) {
return true, strategy, err
}
-// CheckStrategyIsExist 检查策略组ID是否存在
+//CheckStrategyIsExist 检查策略组ID是否存在
func CheckStrategyIsExist(strategyID string) (bool, error) {
db := database2.GetConnection()
sql := "SELECT strategyID FROM goku_gateway_strategy WHERE strategyID = ?;"
@@ -175,7 +175,7 @@ func CheckStrategyIsExist(strategyID string) (bool, error) {
return true, err
}
-// BatchEditStrategyGroup 批量修改策略组分组
+//BatchEditStrategyGroup 批量修改策略组分组
func BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
@@ -198,7 +198,7 @@ func BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, e
return true, "", nil
}
-// BatchDeleteStrategy 批量修改策略组
+//BatchDeleteStrategy 批量修改策略组
func BatchDeleteStrategy(strategyIDList string) (bool, string, error) {
db := database2.GetConnection()
Tx, _ := db.Begin()
@@ -261,7 +261,7 @@ func CheckIsOpenStrategy(strategyID string) bool {
return false
}
-// BatchUpdateStrategyEnableStatus 更新策略启动状态
+//BatchUpdateStrategyEnableStatus 更新策略启动状态
func BatchUpdateStrategyEnableStatus(strategyIDList string, enableStatus int) (bool, string, error) {
db := database2.GetConnection()
now := time.Now().Format("2006-01-02 15:04:05")
@@ -341,3 +341,57 @@ func CopyStrategy(strategyID string, newStrategyID string, userID int) (string,
}
return newStrategyID, nil
}
+
+//GetOpenStrategyCount 获取开放策略数量
+func GetOpenStrategyCount() int {
+ db := database2.GetConnection()
+ var count int
+ sql := "SELECT COUNT(*) FROM goku_gateway_strategy WHERE strategyType = 1"
+ err := db.QueryRow(sql).Scan(&count)
+ if err != nil {
+ return 0
+ }
+ return count
+}
+
+//GetStrategyIDList 获取策略ID列表
+func GetStrategyIDList(groupID int, keyword string, condition int) (bool, []string, error) {
+ db := database2.GetConnection()
+ rule := make([]string, 0, 2)
+
+ rule = append(rule, fmt.Sprintf("A.strategyType != 1"))
+ if groupID > -1 {
+ groupRule := fmt.Sprintf("A.groupID = %d", groupID)
+ rule = append(rule, groupRule)
+ }
+ if keyword != "" {
+ searchRule := "(A.strategyID LIKE '%" + keyword + "%' OR A.strategyName LIKE '%" + keyword + "%')"
+ rule = append(rule, searchRule)
+ }
+ if condition > 0 {
+ filterRule := fmt.Sprintf("A.enableStatus = %d", condition-1)
+ rule = append(rule, filterRule)
+ }
+ ruleStr := ""
+ if len(rule) > 0 {
+ ruleStr += "WHERE " + strings.Join(rule, " AND ")
+ }
+ sql := fmt.Sprintf("SELECT A.strategyID FROM goku_gateway_strategy A %s ORDER BY A.updateTime DESC;", ruleStr)
+ rows, err := db.Query(sql)
+ if err != nil {
+ return false, nil, err
+ }
+ //延时关闭Rows
+ defer rows.Close()
+ //获取记录列
+ strategyList := make([]string, 0)
+ for rows.Next() {
+ var strategyID string
+ err = rows.Scan(&strategyID)
+ if err != nil {
+ return false, nil, err
+ }
+ strategyList = append(strategyList, strategyID)
+ }
+ return true, strategyList, nil
+}
diff --git a/server/dao/console-mysql/strategyGroup.go b/server/dao/console-sqlite3/strategyGroup.go
similarity index 98%
rename from server/dao/console-mysql/strategyGroup.go
rename to server/dao/console-sqlite3/strategyGroup.go
index 327a4f63998e845bea1af54fd7a0d8c038323a15..3964b49e973eca8d79c7999c89a736602a8cad36 100644
--- a/server/dao/console-mysql/strategyGroup.go
+++ b/server/dao/console-sqlite3/strategyGroup.go
@@ -1,4 +1,4 @@
-package consolemysql
+package console_sqlite3
import (
database2 "github.com/eolinker/goku-api-gateway/common/database"
@@ -136,7 +136,7 @@ func GetStrategyGroupList() (bool, []map[string]interface{}, error) {
return true, groupList, nil
}
-//CheckIsOpenGroup 检查是否是开放分组
+//CheckIsOpenGroup 判断是否是开放分组
func CheckIsOpenGroup(groupID int) bool {
db := database2.GetConnection()
var groupType int
diff --git a/server/dao/console-mysql/strategyPlugin.go b/server/dao/console-sqlite3/strategyPlugin.go
similarity index 75%
rename from server/dao/console-mysql/strategyPlugin.go
rename to server/dao/console-sqlite3/strategyPlugin.go
index 11ae0b43f490f65e422582f2e4fbd5890919d90d..f375b012d3995f9b947724512baca0c48eef78f3 100644
--- a/server/dao/console-mysql/strategyPlugin.go
+++ b/server/dao/console-sqlite3/strategyPlugin.go
@@ -1,4 +1,4 @@
-package consolemysql
+package console_sqlite3
import (
SQL "database/sql"
@@ -7,8 +7,6 @@ import (
"strings"
"time"
- log "github.com/eolinker/goku-api-gateway/goku-log"
-
database2 "github.com/eolinker/goku-api-gateway/common/database"
)
@@ -29,11 +27,13 @@ func AddPluginToStrategy(pluginName, config, strategyID string) (bool, interface
result, err := Tx.Exec("INSERT INTO goku_conn_plugin_strategy (pluginName,pluginConfig,strategyID,createTime,updateTime,pluginStatus) VALUES (?,?,?,?,?,?);", pluginName, config, strategyID, now, now, 1)
if err != nil {
Tx.Rollback()
+ panic(err)
return false, "[ERROR]Fail to insert data", errors.New("[ERROR]Fail to insert data")
}
connID, err := result.LastInsertId()
if err != nil {
Tx.Rollback()
+ panic(err)
return false, "[ERROR]Fail to insert data", errors.New("[ERROR]Fail to insert data")
}
@@ -89,14 +89,14 @@ func GetStrategyPluginList(strategyID, keyword string, condition int) (bool, []m
rule = append(rule, searchRule)
}
if condition > 0 {
- rule = append(rule, fmt.Sprintf("IF(B.pluginStatus=0,-1,A.pluginStatus) = %d", condition-1))
+ rule = append(rule, fmt.Sprintf("CASE WHEN B.pluginStatus=0 THEN -1 ELSE A.pluginStatus = %d END", condition-1))
}
ruleStr := ""
if len(rule) > 0 {
ruleStr += "WHERE " + strings.Join(rule, " AND ")
}
- sql := fmt.Sprintf(`SELECT A.connID,A.pluginName,A.pluginConfig,IFNULL(A.createTime,""),IFNULL(A.updateTime,""),B.pluginPriority,IF(B.pluginStatus=0,-1,A.pluginStatus) as pluginStatus,IFNULL(B.pluginDesc,"") FROM goku_conn_plugin_strategy A INNER JOIN goku_plugin B ON B.pluginName = A.pluginName %s ORDER BY pluginStatus DESC,A.updateTime DESC;`, ruleStr)
+ sql := fmt.Sprintf(`SELECT A.connID,A.pluginName,A.pluginConfig,IFNULL(A.createTime,""),IFNULL(A.updateTime,""),B.pluginPriority,CASE WHEN B.pluginStatus=0 THEN -1 ELSE A.pluginStatus END as pluginStatus,IFNULL(B.pluginDesc,"") FROM goku_conn_plugin_strategy A INNER JOIN goku_plugin B ON B.pluginName = A.pluginName %s ORDER BY pluginStatus DESC,A.updateTime DESC;`, ruleStr)
rows, err := db.Query(sql)
if err != nil {
return false, make([]map[string]interface{}, 0), err
@@ -138,6 +138,7 @@ func GetStrategyPluginConfig(strategyID, pluginName string) (bool, string, error
return false, "", err
}
return true, p, nil
+
}
//CheckPluginIsExistInStrategy 检查策略组是否绑定插件
@@ -167,7 +168,7 @@ func GetStrategyPluginStatus(strategyID, pluginName string) (bool, error) {
return true, nil
}
-// GetConnIDFromStrategyPlugin 获取ConnID
+//GetConnIDFromStrategyPlugin 获取Connid
func GetConnIDFromStrategyPlugin(pluginName, strategyID string) (bool, int, error) {
db := database2.GetConnection()
sql := "SELECT connID FROM goku_conn_plugin_strategy WHERE strategyID = ? AND pluginName = ?;"
@@ -236,64 +237,3 @@ func CheckStrategyPluginIsExistByConnIDList(connIDList, pluginName string) (bool
}
return true, nil
}
-
-//UpdateStrategyTagByPluginName 更新策略插件标志位
-func UpdateStrategyTagByPluginName(strategyID string, pluginNameList string) error {
- db := database2.GetConnection()
- plugins := strings.Split(pluginNameList, ",")
- code := make([]string, 0, len(plugins))
- updateTag := time.Now().Format("20060102150405")
- s := make([]interface{}, 0, len(plugins)+2)
- s = append(s, updateTag, strategyID)
- for i := 0; i < len(plugins); i++ {
- code = append(code, "?")
- s = append(s, plugins[i])
- }
- sql := "UPDATE goku_conn_plugin_strategy SET updateTag = ? WHERE strategyID = ? AND pluginName IN (" + strings.Join(code, ",") + ");"
- log.Debug("UpdateStrategyTagByPluginName:", strategyID, pluginNameList, sql, s)
- _, err := db.Exec(sql, s...)
- if err != nil {
- return err
- }
- return nil
-}
-
-//BatchUpdateStrategyPluginUpdateTag 批量更新策略插件更新标志位
-func BatchUpdateStrategyPluginUpdateTag(strategyIDList string) error {
- db := database2.GetConnection()
- strategyIDs := strings.Split(strategyIDList, ",")
- strategyCode := make([]string, 0, len(strategyIDs))
-
- code := make([]string, 0, len(strategyPlugins))
- updateTag := time.Now().Format("20060102150405")
- s := make([]interface{}, 0, len(strategyPlugins)+1+len(strategyIDs))
- s = append(s, updateTag)
- for i := 0; i < len(strategyIDs); i++ {
- strategyCode = append(strategyCode, "?")
- s = append(s, strategyIDs[i])
- }
- for i := 0; i < len(strategyPlugins); i++ {
- code = append(code, "?")
- s = append(s, strategyPlugins[i])
- }
- sql := "UPDATE goku_conn_plugin_strategy SET updateTag = ? WHERE strategyID IN (" + strings.Join(strategyCode, ",") + ") AND pluginName IN (" + strings.Join(code, ",") + ");"
- log.Debug("BatchUpdateStrategyPluginUpdateTag:", sql, " ", s)
- _, err := db.Exec(sql, s...)
- if err != nil {
- return err
- }
- return nil
-}
-
-//UpdateAllStrategyPluginUpdateTag 更新策略插件更新标志位
-func UpdateAllStrategyPluginUpdateTag() error {
- db := database2.GetConnection()
- updateTag := time.Now().Format("20060102150405")
-
- sql := "UPDATE goku_conn_plugin_strategy SET updateTag = ?;"
- _, err := db.Exec(sql, updateTag)
- if err != nil {
- return err
- }
- return nil
-}
diff --git a/server/dao/console-mysql/user.go b/server/dao/console-sqlite3/user.go
similarity index 82%
rename from server/dao/console-mysql/user.go
rename to server/dao/console-sqlite3/user.go
index 47db458b781e742e74c651cda29dcbe3ef3638bd..463e064b2e86dbd5541de13dee84dbd2174b3575 100644
--- a/server/dao/console-mysql/user.go
+++ b/server/dao/console-sqlite3/user.go
@@ -1,8 +1,9 @@
-package consolemysql
+package console_sqlite3
import (
"encoding/json"
"errors"
+
database2 "github.com/eolinker/goku-api-gateway/common/database"
"github.com/eolinker/goku-api-gateway/utils"
)
@@ -19,7 +20,7 @@ func EditPassword(oldPassword, newPassword string, userID int) (bool, string, er
sql := "SELECT loginCall,loginPassword FROM goku_admin WHERE loginPassword = ? AND userID = ?;"
err := db.QueryRow(sql, oldPassword, userID).Scan(&loginCall, &password)
if err != nil {
- return false, "[error]old password error!", err
+ return false, "[ERROR]Old password error!", err
}
sql = "UPDATE goku_admin SET loginPassword = ? WHERE loginPassword = ? AND userID = ?;"
@@ -39,7 +40,7 @@ func EditPassword(oldPassword, newPassword string, userID int) (bool, string, er
return true, loginCall, nil
}
-// GetUserInfo 获取账户信息
+//GetUserInfo 获取账户信息
func GetUserInfo(userID int) (bool, interface{}, error) {
db := database2.GetConnection()
sql := `SELECT loginCall,IFNULL(remark,""),IFNULL(permissions,""),userType FROM goku_admin WHERE userID = ?;`
@@ -47,7 +48,7 @@ func GetUserInfo(userID int) (bool, interface{}, error) {
var userType int
err := db.QueryRow(sql, userID).Scan(&loginCall, &remark, &permissions, &userType)
if err != nil {
- return false, "[error]this user does not exist!", err
+ return false, "[ERROR]This user does not exist!", err
}
var perssionMap map[string]interface{}
if permissions == "" {
@@ -67,26 +68,26 @@ func GetUserInfo(userID int) (bool, interface{}, error) {
return true, userInfo, nil
}
-// GetUserType 获取用户类型
+//GetUserType 获取用户类型
func GetUserType(userID int) (bool, interface{}, error) {
db := database2.GetConnection()
sql := "SELECT userType FROM goku_admin WHERE userID = ?;"
var userType int
err := db.QueryRow(sql, userID).Scan(&userType)
if err != nil {
- return false, "[error]this user does not exist!", err
+ return false, "[ERROR]This user does not exist!", err
}
return true, userType, nil
}
-// CheckUserIsAdmin 判断是否是管理员
+//CheckUserIsAdmin 判断是否是管理员
func CheckUserIsAdmin(userID int) (bool, string, error) {
db := database2.GetConnection()
sql := "SELECT userType FROM goku_admin WHERE userID = ? AND (userType = 0 OR userType = 1);"
var userType int
err := db.QueryRow(sql, userID).Scan(&userType)
if err != nil {
- return false, "[error]this user is not admin!", errors.New("[error]this user is not admin")
+ return false, "[ERROR]This user is not admin!", errors.New("[ERROR]This user is not admin")
}
return true, "", nil
}
@@ -98,7 +99,7 @@ func CheckUserIsSuperAdmin(userID int) (bool, string, error) {
var userType int
err := db.QueryRow(sql, userID).Scan(&userType)
if err != nil {
- return false, "[error]this user is not super admin!", errors.New("[error]this user is not super admin")
+ return false, "[ERROR]This user is not super admin!", errors.New("[ERROR]This user is not super admin")
}
return true, "", nil
}
@@ -116,7 +117,7 @@ func CheckSuperAdminCount() (int, error) {
return count, nil
}
-// CheckUserPermission 检查用户权限
+//CheckUserPermission 检查用户权限
func CheckUserPermission(operationType, operation string, userID int) (bool, string, error) {
db := database2.GetConnection()
var permissions string
@@ -124,31 +125,34 @@ func CheckUserPermission(operationType, operation string, userID int) (bool, str
sql := `SELECT userType,IFNULL(permissions,"") FROM goku_admin WHERE userID = ?;`
err := db.QueryRow(sql, userID).Scan(&userType, &permissions)
if err != nil {
- return false, "[error]this user does not exist!", err
+ return false, "[ERROR]This user does not exist!", err
}
if userType == 0 || userType == 1 {
return true, "", nil
}
if permissions == "" {
- return false, "[error]this user does not assigned permission", nil
+ return false, "[ERROR]This user does not assigned permission", nil
}
permissionsMap := make(map[string]permissionsJSON)
err = json.Unmarshal([]byte(permissions), &permissionsMap)
if err != nil {
return false, "[ERROR]Fail to parse json!!", err
}
- if value, ok := permissionsMap[operationType]; !ok {
- return false, "[error]operation type does not exist!", nil
- } else if v, temp := value[operation]; !temp {
- return false, "[error]operation does not exist!!", nil
- } else if !v {
-
+ value, ok := permissionsMap[operationType]
+ if !ok {
+ return false, "[ERROR]Operation type does not exist!", nil
+ }
+ v, temp := value[operation]
+ if !temp {
+ return false, "[ERROR]Operation does not exist!!", nil
+ }
+ if !v {
return false, "[ERROR]No permissions!", nil
}
return true, "", nil
}
-// GetUserListWithPermission 获取具有编辑权限的用户列表
+//GetUserListWithPermission 获取具有编辑权限的用户列表
func GetUserListWithPermission(operationType, operation string) (bool, []map[string]interface{}, error) {
db := database2.GetConnection()
sql := `SELECT userID,IF(remark IS NULL OR remark = "",loginCall,remark) as userName,userType,IFNULL(permissions,"") FROM goku_admin ORDER BY userType ASC;`
@@ -179,11 +183,15 @@ func GetUserListWithPermission(operationType, operation string) (bool, []map[str
if err != nil {
return false, make([]map[string]interface{}, 0), err
}
- if value, ok := permissionsMap[operationType]; !ok {
+ value, ok := permissionsMap[operationType]
+ if !ok {
return false, make([]map[string]interface{}, 0), errors.New("[error]operation type does not exist")
- } else if v, temp := value[operation]; !temp {
+ }
+ v, temp := value[operation]
+ if !temp {
return false, make([]map[string]interface{}, 0), errors.New("[error]operation does not exist")
- } else if !v {
+ }
+ if !v {
continue
}
}
diff --git a/server/dao/console-mysql/utils.go b/server/dao/console-sqlite3/utils.go
similarity index 94%
rename from server/dao/console-mysql/utils.go
rename to server/dao/console-sqlite3/utils.go
index c89bcc1c56555307d2508f2116d0b1b9574d9981..36e29ec62e448b507b6f91979899a2c3a83fcd05 100644
--- a/server/dao/console-mysql/utils.go
+++ b/server/dao/console-sqlite3/utils.go
@@ -1,4 +1,4 @@
-package consolemysql
+package console_sqlite3
import (
SQL "database/sql"
@@ -12,7 +12,7 @@ func getCountSQL(sql string, args ...interface{}) int {
countSQL := fmt.Sprintf("SELECT COUNT(*) FROM (%s) A", sql)
err := database.GetConnection().QueryRow(countSQL, args...).Scan(&count)
if err != nil {
- panic(err)
+ return 0
}
return count
}
diff --git a/server/dao/console-sqlite3/version.go b/server/dao/console-sqlite3/version.go
new file mode 100644
index 0000000000000000000000000000000000000000..ce1b4ebaa1637e36eb4fba4b84ceb6c338a0c6e6
--- /dev/null
+++ b/server/dao/console-sqlite3/version.go
@@ -0,0 +1,155 @@
+package console_sqlite3
+
+import (
+ "encoding/json"
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/eolinker/goku-api-gateway/common/database"
+
+ "github.com/eolinker/goku-api-gateway/config"
+)
+
+//GetVersionList 获取版本列表
+func GetVersionList(keyword string) ([]config.VersionConfig, error) {
+ db := database.GetConnection()
+ rule := make([]string, 0, 2)
+ if keyword != "" {
+ rule = append(rule, "V.name LIKE '%"+keyword+"%' OR V.version LIKE '%"+keyword+"%' OR V.remark LIKE '%"+keyword+"%'")
+ }
+ ruleStr := ""
+ if len(rule) > 0 {
+ ruleStr += "WHERE " + strings.Join(rule, " AND ")
+ }
+
+ sql := "SELECT V.versionID,V.name,V.version,V.remark,V.createTime,V.publishTime,CASE WHEN V.versionID = G.versionID THEN 1 ELSE 0 END AS publishStatus FROM goku_gateway_version_config V LEFT JOIN goku_gateway G ON V.versionID = G.versionID %s ORDER BY publishStatus DESC,V.createTime DESC"
+ rows, err := db.Query(fmt.Sprintf(sql, ruleStr))
+ if err != nil {
+ return make([]config.VersionConfig, 0), err
+ }
+ defer rows.Close()
+ configList := make([]config.VersionConfig, 0, 10)
+ for rows.Next() {
+ var config config.VersionConfig
+ err = rows.Scan(&config.VersionID, &config.Name, &config.Version, &config.Remark, &config.CreateTime, &config.PublishTime, &config.PublishStatus)
+ if err != nil {
+ return configList, err
+ }
+ configList = append(configList, config)
+ }
+ return configList, nil
+}
+
+//AddVersionConfig 新增版本配置
+func AddVersionConfig(name, version, remark, config, balanceConfig, discoverConfig, now string) (int, error) {
+ db := database.GetConnection()
+ sql := "INSERT INTO goku_gateway_version_config (`name`,`version`,`remark`,`createTime`,`publishTime`,`config`,`balanceConfig`,`discoverConfig`) VALUES (?,?,?,?,?,?,?,?)"
+ result, err := db.Exec(sql, name, version, remark, now, now, config, balanceConfig, discoverConfig)
+ if err != nil {
+ return 0, err
+ }
+ lastID, err := result.LastInsertId()
+ if err != nil {
+ return 0, err
+ }
+ return int(lastID), nil
+}
+
+//BatchDeleteVersionConfig 批量删除版本配置
+func BatchDeleteVersionConfig(ids []int, publishID int) error {
+ db := database.GetConnection()
+ s := ""
+ idCount := len(ids)
+ for i, id := range ids {
+ if id == publishID {
+ continue
+ }
+ s = s + strconv.Itoa(id)
+ if i < idCount-1 {
+ s = s + ","
+ }
+ }
+ sql := fmt.Sprintf("DELETE FROM goku_gateway_version_config WHERE versionID IN (%s)", s)
+ _, err := db.Exec(sql)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+//PublishVersion 发布版本
+func PublishVersion(id int, now string) error {
+ db := database.GetConnection()
+ sql := "UPDATE goku_gateway SET versionID = ?"
+ _, err := db.Exec(sql, id)
+ if err != nil {
+ return err
+ }
+ sql = "UPDATE goku_gateway_version_config SET publishTime = ? WHERE versionID = ?"
+ _, err = db.Exec(sql, now, id)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+//GetVersionConfigCount 获取版本配置数量
+func GetVersionConfigCount() int {
+ db := database.GetConnection()
+ sql := "SELECT COUNT(*) FROM goku_gateway_version_config"
+ var count int
+ err := db.QueryRow(sql).Scan(&count)
+ if err != nil {
+ return 0
+ }
+ return count
+}
+
+//GetPublishVersionID 获取发布版本ID
+func GetPublishVersionID() int {
+ db := database.GetConnection()
+ sql := "SELECT versionID FROM goku_gateway"
+ var id int
+ err := db.QueryRow(sql).Scan(&id)
+ if err != nil {
+ return 0
+ }
+ return id
+}
+
+//GetVersionConfig 获取当前版本配置
+func GetVersionConfig() (*config.GokuConfig, map[string]map[string]*config.BalanceConfig, map[string]map[string]*config.DiscoverConfig, error) {
+ db := database.GetConnection()
+ sql := "SELECT IFNULL(goku_gateway_version_config.config,'{}'),IFNULL(goku_gateway_version_config.balanceConfig,'{}'),IFNULL(goku_gateway_version_config.discoverConfig,'{}') FROM goku_gateway_version_config INNER JOIN goku_gateway ON goku_gateway.versionID = goku_gateway_version_config.versionID"
+ var cf, bf, df string
+
+ err := db.QueryRow(sql).Scan(&cf, &bf, &df)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ var c config.GokuConfig
+ b := make(map[string]map[string]*config.BalanceConfig)
+ d := make(map[string]map[string]*config.DiscoverConfig)
+ err = json.Unmarshal([]byte(cf), &c)
+ if cf != "" {
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ }
+ if bf != "" {
+ err = json.Unmarshal([]byte(bf), &b)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ }
+
+ if df != "" {
+ err = json.Unmarshal([]byte(df), &d)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ }
+
+ return &c, b, d, nil
+}
diff --git a/server/dao/node-mysql/dao-api/api.go b/server/dao/node-mysql/dao-api/api.go
deleted file mode 100644
index b09558e3959bcfea06659b24c405220324dd6afa..0000000000000000000000000000000000000000
--- a/server/dao/node-mysql/dao-api/api.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package daoapi
-
-import (
- "fmt"
- "github.com/eolinker/goku-api-gateway/common/database"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-// GetAllAPI 获取API接口列表
-func GetAllAPI() (map[int]*entity.API, error) {
-
- sql := "SELECT `apiID`,`apiName`,`requestMethod`,`requestURL`,`protocol`,`balanceName`,`targetURL`,`targetMethod`,`isFollow`,`stripPrefix`,`stripSlash`,`timeout`,`retryCount`,`alertValve` FROM `goku_gateway_api` ORDER BY `apiID` asc;"
- stmt, e := database.GetConnection().Prepare(sql)
- if e != nil {
- return nil, e
- }
- defer stmt.Close()
- rows, err := stmt.Query()
- if err != nil {
- return nil, err
- }
- defer rows.Close()
- apiList := make(map[int]*entity.API, 0)
- //获取记录列
- if _, err = rows.Columns(); err != nil {
- return nil, err
- }
- for rows.Next() {
- api := new(entity.API)
- err = rows.Scan(&api.APIID, &api.APIName, &api.RequestMethod, &api.RequestURL, &api.Protocol, &api.BalanceName, &api.TargetURL, &api.TargetMethod, &api.IsFollow, &api.StripPrefix, &api.StripSlash, &api.Timeout, &api.RetryCount, &api.AlertValve)
- if err != nil {
- continue
- }
- if len(api.RequestURL) == 0 || api.RequestURL[0] != '/' {
- api.RequestURL = fmt.Sprint("/", api.RequestURL)
- }
- if len(api.TargetURL) == 0 || api.TargetURL[0] != '/' {
- api.TargetURL = fmt.Sprint("/", api.TargetURL)
- }
-
- apiList[api.APIID] = api
- }
- return apiList, nil
-
-}
diff --git a/server/dao/node-mysql/dao-balance/balance.go b/server/dao/node-mysql/dao-balance/balance.go
deleted file mode 100644
index 312958f65618e3b419a30ec650b9d467dbc5d54a..0000000000000000000000000000000000000000
--- a/server/dao/node-mysql/dao-balance/balance.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package daobalance
-
-import (
- "github.com/eolinker/goku-api-gateway/common/database"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-//GetAllBalance 获取负载列表
-func GetAllBalance() ([]*entity.Balance, error) {
- const sql = "SELECT A.`balanceName`,A.`serviceName`,IFNULL(B.`driver`,''),A.`appName`,IFNULL(A.`static`,''),IFNULL(A.`staticCluster`,'') FROM `goku_balance` A LEFT JOIN `goku_service_config` B ON A.`serviceName` = B.`name`;"
- db := database.GetConnection()
- rows, err := db.Query(sql)
- if err != nil {
- return nil, err
- }
- defer rows.Close()
-
- r := make([]*entity.Balance, 0, 20)
- for rows.Next() {
- v := new(entity.Balance)
- err := rows.Scan(&v.Name, &v.ServiceName, &v.ServiceDriver, &v.AppName, &v.Static, &v.StaticCluster)
- if err != nil {
- return nil, err
- }
- r = append(r, v.Type())
- }
- return r, nil
-}
diff --git a/server/dao/node-mysql/dao-gateway/gateway.go b/server/dao/node-mysql/dao-gateway/gateway.go
deleted file mode 100644
index cf90e64123a682157165990855d59e461ed30faa..0000000000000000000000000000000000000000
--- a/server/dao/node-mysql/dao-gateway/gateway.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package daogateway
-
-import "github.com/eolinker/goku-api-gateway/common/database"
-
-//GetGatewayBaseInfo 获取网关成功状态码
-func GetGatewayBaseInfo() (string, int) {
- db := database.GetConnection()
- var successCode string
- var updatePeriod int
- sql := "SELECT successCode,nodeUpdatePeriod FROM goku_gateway WHERE id = 1;"
- err := db.QueryRow(sql).Scan(&successCode, &updatePeriod)
- if err != nil {
- return "200", 5
- }
- return successCode, updatePeriod
-}
-
-//GetGatewayAlertInfo 获取节点告警信息
-func GetGatewayAlertInfo() (string, int) {
- db := database.GetConnection()
- var apiAlertInfo string
- var alertStatus int
- sql := "SELECT alertStatus,apiAlertInfo FROM goku_gateway WHERE id = 1;"
- err := db.QueryRow(sql).Scan(&alertStatus, &apiAlertInfo)
- if err != nil {
- return "{\"alertAddr\":\"\",\"alertPeriodType\":0,\"logPath\":\"./log/apiAlert\",\"receiverList\":\"\"}", 0
- }
- return apiAlertInfo, alertStatus
-}
diff --git a/server/dao/node-mysql/dao-plugin/plugin.go b/server/dao/node-mysql/dao-plugin/plugin.go
deleted file mode 100644
index ea324ac7c1520d4a3f51d7698059df43f3d99322..0000000000000000000000000000000000000000
--- a/server/dao/node-mysql/dao-plugin/plugin.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package daoplugin
-
-import (
- "github.com/eolinker/goku-api-gateway/common/database"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-//GetAll 获取所有插件
-func GetAll() (map[string]*entity.PluginInfo, error) {
-
- const sql = "SELECT P.`pluginName`,P.`pluginPriority`,IFNULL(P.`pluginConfig`,''),P.`isStop`,P.`pluginType` FROM `goku_plugin` P WHERE P.`isCheck` = TRUE AND P.`pluginStatus` = 1;"
- stmt, e := database.GetConnection().Prepare(sql)
- if e != nil {
- return nil, e
- }
- defer stmt.Close()
- rows, e := stmt.Query()
- if e != nil {
- return nil, e
- }
- defer rows.Close()
-
- plugins := make(map[string]*entity.PluginInfo)
- for rows.Next() {
- p := new(entity.PluginInfo)
- err := rows.Scan(&p.Name, &p.Priority, &p.Config, &p.IsStop, &p.Type)
- if err != nil {
- continue
- }
- plugins[p.Name] = p
- }
- return plugins, nil
-
-}
diff --git a/server/dao/node-mysql/dao-service/service.go b/server/dao/node-mysql/dao-service/service.go
deleted file mode 100644
index 67e4e7bd8c8dd3e7e97613c910e2faa9f3780ad0..0000000000000000000000000000000000000000
--- a/server/dao/node-mysql/dao-service/service.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package daoservice
-
-import (
- "github.com/eolinker/goku-api-gateway/common/database"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-const sqlList = "SELECT `name`,`driver`,`default`,`desc`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut` FROM `goku_service_config`"
-
-//GetAll 获取所有服务发现配置
-func GetAll() ([]*entity.Service, error) {
-
- stmt, e := database.GetConnection().Prepare(sqlList)
- if e != nil {
- return nil, e
- }
- defer stmt.Close()
- rows, err := stmt.Query()
-
- if err != nil {
- return nil, err
- }
- defer rows.Close()
-
- vs := make([]*entity.Service, 0, 10)
-
- for rows.Next() {
-
- v := new(entity.Service)
- er := rows.Scan(&v.Name,
- &v.Driver,
- &v.IsDefault,
- &v.Desc,
- &v.Config,
- &v.ClusterConfig,
- &v.HealthCheck,
- &v.HealthCheckPath,
- &v.HealthCheckPeriod,
- &v.HealthCheckCode,
- &v.HealthCheckTimeOut,
- )
- if er != nil {
- return nil, er
- }
-
- vs = append(vs, v)
- }
- return vs, nil
-
-}
diff --git a/server/dao/node-mysql/dao-strategy/strategy-api-plugin.go b/server/dao/node-mysql/dao-strategy/strategy-api-plugin.go
deleted file mode 100644
index 7aadb138da761068c9365b5d8fa593309cbf5f43..0000000000000000000000000000000000000000
--- a/server/dao/node-mysql/dao-strategy/strategy-api-plugin.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package daostrategy
-
-import (
- "github.com/eolinker/goku-api-gateway/common/database"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-//GetAPIPlugin 获取接口插件列表
-func GetAPIPlugin() ([]*entity.StrategyAPIPlugin, error) {
- const sql = "SELECT A.`apiID`,A.`strategyID`,A.`pluginName`,A.`pluginConfig`,IFNULL(A.`updateTag`,'') FROM `goku_conn_plugin_api` A INNER JOIN `goku_conn_strategy_api` SA ON A.`strategyID` = SA.`strategyID` AND A.`apiID` = SA.`apiID` INNER JOIN `goku_gateway_strategy` S ON A.`strategyID` = S.`strategyID` INNER JOIN `goku_gateway_api` API ON API.`apiID` = A.`apiID` INNER JOIN `goku_plugin` P ON P.`isCheck` = TRUE AND P.`pluginStatus` = 1 AND A.`pluginStatus` = 1 AND A.`pluginName` = P.`pluginName` ;"
-
- stmt, e := database.GetConnection().Prepare(sql)
- if e != nil {
- return nil, e
- }
- defer stmt.Close()
-
- rows, e := stmt.Query()
- if e != nil {
- return nil, e
- }
- defer rows.Close()
-
- saps := make([]*entity.StrategyAPIPlugin, 0, 200)
-
- for rows.Next() {
- sap := new(entity.StrategyAPIPlugin)
-
- err := rows.Scan(
- &sap.APIId,
- &sap.StrategyID,
- &sap.PluginName,
- &sap.PluginConfig,
- &sap.UpdateTag,
- )
- if err != nil {
- continue
- }
- saps = append(saps, sap)
- }
-
- return saps, nil
-}
diff --git a/server/dao/node-mysql/dao-strategy/strategy-api.go b/server/dao/node-mysql/dao-strategy/strategy-api.go
deleted file mode 100644
index 63ae89e306c060b644c7987a921356b9b6abc68c..0000000000000000000000000000000000000000
--- a/server/dao/node-mysql/dao-strategy/strategy-api.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package daostrategy
-
-import (
- "github.com/eolinker/goku-api-gateway/common/database"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-//GetAllStrategyAPI 获取所有策略接口列表
-func GetAllStrategyAPI() ([]*entity.StrategyAPI, error) {
-
- const sql = "SELECT A.`strategyID`,A.`apiID`,IFNULL(A.`target`,'') FROM `goku_conn_strategy_api` A JOIN `goku_gateway_strategy` B ON A.`strategyID` = B.`strategyID` ;"
-
- stmt, e := database.GetConnection().Prepare(sql)
- if e != nil {
- return nil, e
- }
- defer stmt.Close()
- rows, e := stmt.Query()
- if e != nil {
- return nil, e
- }
- defer rows.Close()
-
- apis := make([]*entity.StrategyAPI, 0, 1000)
-
- for rows.Next() {
- api := new(entity.StrategyAPI)
- err := rows.Scan(&api.StrategyID, &api.APIID, &api.Target)
- if err != nil {
- continue
- }
- apis = append(apis, api)
- }
- return apis, nil
-
-}
diff --git a/server/dao/node-mysql/dao-strategy/strategy-plugin.go b/server/dao/node-mysql/dao-strategy/strategy-plugin.go
deleted file mode 100644
index 93f05fa5029b6bc83c538a1fb2b124f2daa0afbd..0000000000000000000000000000000000000000
--- a/server/dao/node-mysql/dao-strategy/strategy-plugin.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package daostrategy
-
-import (
- "github.com/eolinker/goku-api-gateway/common/database"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-// GetAllStrategyPluginList 获取策略组插件列表
-func GetAllStrategyPluginList() ([]*entity.StrategyPluginItem, error) {
-
- sql := "SELECT A.`strategyID`,A.`pluginName`,A.`pluginConfig`,IFNULL(A.`updateTag`,'') FROM `goku_conn_plugin_strategy` A INNER JOIN `goku_gateway_strategy` S ON A.`strategyID` = S.`strategyID` INNER JOIN `goku_plugin` P ON P.`isCheck` = TRUE AND P.`pluginStatus` = 1 AND A.`pluginName` = P.`pluginName` WHERE A.`pluginStatus` = 1;"
-
- stmt, e := database.GetConnection().Prepare(sql)
- if e != nil {
- return nil, e
- }
- defer stmt.Close()
- rows, e := stmt.Query()
- if e != nil {
- return nil, e
- }
- defer rows.Close()
-
- strategyList := make([]*entity.StrategyPluginItem, 0, 100)
- for rows.Next() {
- s := new(entity.StrategyPluginItem)
- err := rows.Scan(
- &s.StrategyID,
- &s.PluginName,
- &s.PluginConfig,
- &s.UpdateTag,
- )
- if err != nil {
- continue
- }
- strategyList = append(strategyList, s)
- }
- return strategyList, nil
-
-}
diff --git a/server/dao/node-mysql/dao-strategy/strategy.go b/server/dao/node-mysql/dao-strategy/strategy.go
deleted file mode 100644
index 4614d7addc4762e429bdbad9e8def862f8db013a..0000000000000000000000000000000000000000
--- a/server/dao/node-mysql/dao-strategy/strategy.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package daostrategy
-
-import (
- log "github.com/eolinker/goku-api-gateway/goku-log"
-
- "github.com/eolinker/goku-api-gateway/common/database"
- entity "github.com/eolinker/goku-api-gateway/server/entity/node-entity"
-)
-
-//GetAllStrategy 获取所有策略列表
-func GetAllStrategy() (map[string]*entity.Strategy, *entity.Strategy, error) {
- //const sql = "SELECT `strategyID`,`strategyName`,`auth` ,`strategyType` FROM `goku_gateway_strategy` WHERE `enableStatus` = 1;"
- const sql = "SELECT `strategyID`,`strategyName`,`auth`,`enableStatus` ,`strategyType` FROM `goku_gateway_strategy`;"
-
- stmt, e := database.GetConnection().Prepare(sql)
- if e != nil {
- return nil, nil, e
- }
- defer stmt.Close()
- rows, e := stmt.Query()
- if e != nil {
- return nil, nil, e
- }
- defer rows.Close()
- var def *entity.Strategy
- strategys := make(map[string]*entity.Strategy)
- for rows.Next() {
- s := new(entity.Strategy)
- err := rows.Scan(&s.StrategyID, &s.StrategyName, &s.Auth, &s.EnableStatus, &s.StrategyType)
- if err != nil {
- log.Warn("GetAllStrategy ", err)
- continue
- }
-
- strategys[s.StrategyID] = s
- if s.StrategyType == 1 {
- def = s
- }
- }
-
- return strategys, def, nil
-}
diff --git a/server/dao/update.go b/server/dao/update.go
deleted file mode 100644
index 30b4ea39e9aef8cba92aa6e4f8efb306eea1a0e7..0000000000000000000000000000000000000000
--- a/server/dao/update.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package dao
-
-import (
- "fmt"
- "strings"
- "time"
-
- "github.com/eolinker/goku-api-gateway/common/database"
-)
-
-//GetLastUpdateOfAPI 获取最后更新的接口记录
-func GetLastUpdateOfAPI(tables ...string) (time.Time, error) {
- t := time.Time{}
- var updateTime string
- tb := make([]string, len(tables))
- tv := make([]interface{}, len(tables))
- for i, table := range tables {
- tb[i] = "?"
- tv[i] = table
- }
- tablesStr := strings.Join(tb, ",")
- db := database.GetConnection()
-
- sql := fmt.Sprintf("SELECT updateTime FROM goku_table_update_record WHERE name IN (%s) ORDER BY updateTime desc LIMIT 1;", tablesStr)
-
- err := db.QueryRow(sql, tv...).Scan(&updateTime)
- if err != nil {
- return t, err
- }
- t, _ = time.ParseInLocation("2006-01-02 15:04:05", updateTime, time.Local)
- return t, nil
-}
-
-//UpdateTable 更新goku_table_update_record的updateTime字段
-func UpdateTable(name string) error {
- db := database.GetConnection()
- now := time.Now().Format("2006-01-02 15:04:05")
- sql := "INSERT INTO `goku_table_update_record` (`name`,`updateTime`) VALUES (?,?) ON DUPLICATE KEY UPDATE `updateTime` = VALUES(`updateTime`)"
- _, err := db.Exec(sql, name, now)
- if err != nil {
- panic(err)
- return err
- }
- return nil
-}
diff --git a/server/driver/driver.go b/server/driver/driver.go
index 0f3b41bff074f409aab7f4c9e2be65e1eadbfff9..965d74249647a69f086020e5a64ee108ef72166c 100644
--- a/server/driver/driver.go
+++ b/server/driver/driver.go
@@ -1,10 +1,13 @@
package driver
const (
- Static = "static"
+ //Static 静态服务
+ Static = "static"
+ //Discovery 服务发现
Discovery = "discovery"
)
+//Driver driver
type Driver struct {
Name string `json:"name"`
Type string `json:"type"`
@@ -57,24 +60,30 @@ func init() {
driverOfType[d.Type] = append(driverOfType[d.Type], d)
}
}
+
+//All all
func All() []*Driver {
return all
}
+//GetByType 根据类型获取驱动列表
func GetByType(t string) []*Driver {
return driverOfType[t]
}
+//Get get
func Get(name string) (*Driver, bool) {
d, has := drivers[name]
return d, has
}
+//TypeName typeName
func TypeName(t string) (string, bool) {
n, has := typeNames[t]
return n, has
}
+//Types types
func Types() map[string]string {
return typeNames
}
diff --git a/server/entity/alert.go b/server/entity/alert.go
deleted file mode 100644
index dcf9434f1665a765706267c86e7d8314bb238b94..0000000000000000000000000000000000000000
--- a/server/entity/alert.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package entity
-
-//AlertInfo 告警信息
-type AlertInfo struct {
- ReceiverList string `json:"receiverList"`
- AlertAddr string `json:"alertAddr"`
-}
diff --git a/server/entity/balance-entity/balance.go b/server/entity/balance-entity/balance.go
index 5a66bc118522ccd7c9116c477c6533f5ed3a6a1f..c6f621e8cb343959e9daab30da1ee4db54334f38 100644
--- a/server/entity/balance-entity/balance.go
+++ b/server/entity/balance-entity/balance.go
@@ -9,7 +9,7 @@ import (
jsoniter "github.com/json-iterator/go"
)
-//BalanceInfoEntity 负载信息结构体
+//BalanceInfoEntity 负载信息实体
type BalanceInfoEntity struct {
Name string
Desc string
@@ -42,7 +42,7 @@ type BalanceConfig struct {
ServersConfigOrg string `json:"staticOrg"`
}
-//BalanceServerConfig 负载服务器配置
+//BalanceServerConfig 负载服务配置
type BalanceServerConfig struct {
Server string `json:"server"`
Weight int `json:"weight"`
@@ -66,7 +66,7 @@ type _OldVersionBalanceInfo struct {
//
//}
-//Decode 解码
+//Decode decode
func (ent *BalanceInfoEntity) Decode() (*BalanceInfo, error) {
info := new(BalanceInfo)
info.Name = ent.Name
@@ -109,7 +109,7 @@ func (ent *BalanceInfoEntity) Decode() (*BalanceInfo, error) {
}
-//TryOld try old config
+//TryOld 解析旧配置
func TryOld(oldversionConfig string) ([]*BalanceServerConfig, error) {
if oldversionConfig == "" {
return nil, nil
@@ -139,7 +139,7 @@ func (info *BalanceInfo) GetConfig(clusterName string) *BalanceConfig {
return c
}
-//FormatServers 格式化
+//FormatServers 格式化服务
func FormatServers(servers []*BalanceServerConfig) []string {
if len(servers) == 0 {
return nil
@@ -175,7 +175,7 @@ func fields(str string) []string {
return words
}
-//Decode 解析配置
+//Decode decode配置
func (c *BalanceConfig) Decode() error {
words := fields(c.ServersConfigOrg)
diff --git a/server/entity/cluster.go b/server/entity/cluster.go
index e8d70f943d68707cec53ed1a8912ca723e709fcc..e79d25d1be76f66a718e59283527276c79fd6afc 100644
--- a/server/entity/cluster.go
+++ b/server/entity/cluster.go
@@ -2,9 +2,7 @@ package entity
import "fmt"
-//const ClusterDefaultName = "default"
-
-//Cluster cluster
+//Cluster 集群配置
type Cluster struct {
ID int `json:"-" yaml:"-"`
Name string `json:"name" yaml:"name"`
@@ -21,7 +19,7 @@ type ClusterInfo struct {
Redis CLusterRedis `json:"redis" yaml:"redis"`
}
-//ClusterDB cluster db
+//ClusterDB 集群DB配置
type ClusterDB struct {
Driver string `json:"driver" yaml:"driver"`
Host string `json:"host" yaml:"host"`
@@ -29,9 +27,10 @@ type ClusterDB struct {
UserName string `json:"userName" yaml:"userName"`
Password string `json:"password" yaml:"password"`
Database string `json:"database" yaml:"database"`
+ Path string `json:"path" yaml:"path"`
}
-//CLusterRedis cluster redis
+//CLusterRedis 集群redis配置
type CLusterRedis struct {
Mode string `json:"mode" yaml:"mode"`
Addrs string `json:"addrs" yaml:"addrs"`
@@ -40,17 +39,17 @@ type CLusterRedis struct {
Password string `json:"password" yaml:"password"`
}
-//GetDriver 获取驱动
+//GetDriver 获取驱动名称
func (c *ClusterDB) GetDriver() string {
return c.Driver
}
-//GetSource 获取源字符串
+//GetSource 获取连接字符串
func (c *ClusterDB) GetSource() string {
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", c.UserName, c.Password, c.Host, c.Port, c.Database)
}
-//Cluster 获取cluster
+//Cluster 获取集群
func (c *ClusterInfo) Cluster() *Cluster {
return &Cluster{
ID: c.ID,
diff --git a/server/entity/console-entity/api.go b/server/entity/console-entity/api.go
index 8449285d496dff3d8a70efd1d26e50ad0368c9c6..1f341cdecd5338d8e679217b4cf444c4224d0f8f 100644
--- a/server/entity/console-entity/api.go
+++ b/server/entity/console-entity/api.go
@@ -1,33 +1,39 @@
package entity
+import "github.com/eolinker/goku-api-gateway/config"
+
//API 接口
type API struct {
- APIID int `json:"apiID"`
- APIName string `json:"apiName"`
- GroupID int `json:"groupID,omitempty"`
- ProjectID int `json:"projectID,omitempty"`
- RequestURL string `json:"requestURL"`
- ProxyURL string `json:"targetURL"`
- RequestMethod string `json:"requestMethod"`
- TargetServer string `json:"targetServer"`
- TargetMethod string `json:"targetMethod"`
- RequestParamList []*RequestParam `json:"requestParamList,omitempty"`
- ResultParamList []string `json:"resultParamList,omitempty"`
- IsFollow bool `json:"isFollow"`
- StripPrefix bool `json:"stripPrefix"`
- Timeout int `json:"timeout"`
- RetryConut int `json:"retryCount"`
- UpdateTime string `json:"updateTime"`
- CreateTime string `json:"createTime"`
- Valve int `json:"alertValve"`
- BalanceName string `json:"balanceName"`
- Protocol string `json:"protocol"`
- StripSlash bool `json:"stripSlash"`
- GroupPath string `json:"groupPath"`
+ APIID int `json:"apiID"`
+ APIName string `json:"apiName"`
+ GroupID int `json:"groupID,omitempty"`
+ ProjectID int `json:"projectID,omitempty"`
+ RequestURL string `json:"requestURL"`
+ ProxyURL string `json:"targetURL"`
+ RequestMethod string `json:"requestMethod"`
+ TargetServer string `json:"targetServer"`
+ TargetMethod string `json:"targetMethod"`
+ RequestParamList []*RequestParam `json:"requestParamList,omitempty"`
+ ResultParamList []string `json:"resultParamList,omitempty"`
+ IsFollow bool `json:"isFollow"`
+ StripPrefix bool `json:"stripPrefix"`
+ Timeout int `json:"timeout"`
+ RetryConut int `json:"retryCount"`
+ UpdateTime string `json:"updateTime"`
+ CreateTime string `json:"createTime"`
+ Valve int `json:"alertValve"`
+ BalanceName string `json:"balanceName"`
+ Protocol string `json:"protocol"`
+ StripSlash bool `json:"stripSlash"`
+ GroupPath string `json:"groupPath"`
+ APIType int `json:"apiType"`
+ LinkAPIs []config.APIStepUIConfig `json:"linkApis"`
+ StaticResponse string `json:"staticResponse"`
+ ResponseDataType string `json:"responseDataType"`
*ManagerInfo
}
-//ManagerInfo 管理者信息
+//ManagerInfo 用户管理者信息
type ManagerInfo struct {
ManagerID int `json:"managerID"`
UpdaterID int `json:"updaterID"`
diff --git a/server/entity/console-entity/cluster.go b/server/entity/console-entity/cluster.go
new file mode 100644
index 0000000000000000000000000000000000000000..7dd4f54d477f69c9a1bbb7f2e698cbaf334a184c
--- /dev/null
+++ b/server/entity/console-entity/cluster.go
@@ -0,0 +1,10 @@
+package entity
+
+//Cluster 集群配置
+type Cluster struct {
+ ID int `json:"id"`
+ Name string `json:"name"`
+ Title string `json:"title"`
+ Note string `json:"note"`
+ NodeCount int `json:"nodeCount"`
+}
diff --git a/server/entity/console-entity/message.go b/server/entity/console-entity/message.go
deleted file mode 100644
index c1b16340b39cb79f9425018c641469baf041db09..0000000000000000000000000000000000000000
--- a/server/entity/console-entity/message.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package entity
-
-//Message 消息
-type Message struct {
- MsgID int `json:"msgID"`
- Msg string `json:"msg"`
- UpdateTime string `json:"updateTime"`
- MsgType int `json:"msgType"`
-}
diff --git a/server/entity/console-entity/node.go b/server/entity/console-entity/node.go
index c9f7e1f70a1622735bd336662786ef0ed15b9da9..0b47eb41aa598ccb33c97191c24ca04815805ee9 100644
--- a/server/entity/console-entity/node.go
+++ b/server/entity/console-entity/node.go
@@ -1,6 +1,6 @@
package entity
-//Node 节点
+//Node 节点信息
type Node struct {
NodeID int `json:"nodeID"`
NodeName string `json:"nodeName"`
diff --git a/server/entity/console-entity/plugin.go b/server/entity/console-entity/plugin.go
index 28347a5e30c9ea9b8d426dd708b02362af53b3f5..3dda37131df171ad0319a61fcefdf32849def0c3 100644
--- a/server/entity/console-entity/plugin.go
+++ b/server/entity/console-entity/plugin.go
@@ -1,9 +1,6 @@
package entity
-//GlobalPlugin 全局插件
-var GlobalPlugin = make(map[string]*Plugin)
-
-// Plugin 插件
+//Plugin 插件
type Plugin struct {
PluginID int `json:"pluginID"`
PluginName string `json:"pluginName"`
@@ -46,7 +43,7 @@ func (p PluginSlice) Less(i, j int) bool { // 重写 Less() 方法, 从小到
return p[i].PluginIndex < p[j].PluginIndex
}
-//ProxyCachingConf 转发缓存配置
+//ProxyCachingConf 代理缓存配置
type ProxyCachingConf struct {
ResponseCodes string `json:"responseCodes"` //缓存条件:返回的HTTP状态码在该状态码列表中
RequestMethods string `json:"requestMethods"` //缓存条件:请求的Method在该列表中
diff --git a/server/entity/console-entity/redis.go b/server/entity/console-entity/redis.go
index aa2fd6d2db1343b6362b09721df5ea12de0f6ffe..dfc7959f7ffb2473e0707799af98f22e3fb3be21 100644
--- a/server/entity/console-entity/redis.go
+++ b/server/entity/console-entity/redis.go
@@ -1,6 +1,6 @@
package entity
-//RedisNode redis节点信息
+//RedisNode redis节点
type RedisNode struct {
Server string
Password string
diff --git a/server/entity/console-entity/service.go b/server/entity/console-entity/service.go
index 409f4027fb1a66cf8919b2a8a20faba1c602db90..6d20ec7521203ebe0906ba84b4726061bbf6c06e 100644
--- a/server/entity/console-entity/service.go
+++ b/server/entity/console-entity/service.go
@@ -1,6 +1,6 @@
package entity
-//Service service
+//Service 服务发现
type Service struct {
Name string
Driver string
diff --git a/server/entity/console-entity/sql.go b/server/entity/console-entity/sql.go
index d8c6fe57c81c4b174f889cdffec6666e5dfb990c..56c854c6803c14a55d1d45b570f1c215e30d80a0 100644
--- a/server/entity/console-entity/sql.go
+++ b/server/entity/console-entity/sql.go
@@ -1,17 +1,17 @@
package entity
-//Table table
+//Table 表结构
type Table struct {
TableName string `json:"tableName"`
TableColumn []string `json:"tableColumn"`
}
-//TableData tableData
+//TableData 表数据
type TableData struct {
Data []map[string]interface{}
}
-//ColumnInfo column info
+//ColumnInfo 列信息
type ColumnInfo struct {
FieldName string
Type interface{}
@@ -21,7 +21,7 @@ type ColumnInfo struct {
Extra interface{}
}
-//GokuAdmin 网关超级管理员信息
+//GokuAdmin admin信息
type GokuAdmin struct {
UserID int `json:"userID"`
LoginCall string `json:"loginCall"`
@@ -29,7 +29,7 @@ type GokuAdmin struct {
UserType int `json:"userType"`
}
-//GokuBalance 网关负载
+//GokuBalance 负载信息
type GokuBalance struct {
BalanceID int `json:"balanceID"`
BalanceName string `json:"balanceName"`
@@ -38,13 +38,13 @@ type GokuBalance struct {
UpdateTime string `json:"updateTime"`
}
-//GokuConnPluginAPI goku conn plgin api
+//GokuConnPluginAPI 接口和插件绑定信息
type GokuConnPluginAPI struct {
ConnID int `json:"connID"`
APIID int `json:"apiID"`
}
-//ColumnValue column value
+//ColumnValue 列值
type ColumnValue struct {
Value interface{}
}
diff --git a/server/entity/node-entity/api.go b/server/entity/node-entity/api.go
index 384b131e97a1950b84a79f15e47a7352343a2556..d3d36ac4717da9d97234f89270e95fe611f4b6d6 100644
--- a/server/entity/node-entity/api.go
+++ b/server/entity/node-entity/api.go
@@ -1,6 +1,6 @@
package entity
-//API api
+//API api信息
type API struct {
APIID int
APIName string
@@ -18,7 +18,7 @@ type API struct {
StripSlash bool // 是否过滤斜杠
}
-//APIExtend api extend
+//APIExtend 接口额外信息
type APIExtend struct {
*API
Target string
diff --git a/server/entity/node-entity/balance.go b/server/entity/node-entity/balance.go
index a3f3cf2c9c89e1b5a98f7fd25439993c835dad96..dd4c5d35a29a8b36a49cd4ef62776aef16aebb7f 100644
--- a/server/entity/node-entity/balance.go
+++ b/server/entity/node-entity/balance.go
@@ -2,7 +2,7 @@ package entity
import "github.com/eolinker/goku-api-gateway/server/driver"
-//Balance balance
+//Balance 负载
type Balance struct {
Name string
ServiceName string
@@ -13,7 +13,7 @@ type Balance struct {
StaticCluster string
}
-//Type type
+//Type 负载类型
func (e *Balance) Type() *Balance {
if e != nil {
diff --git a/server/entity/node-entity/monitor.go b/server/entity/node-entity/monitor.go
deleted file mode 100644
index 4817b484d0cf8f57d25fdc4b52172ac527c5d719..0000000000000000000000000000000000000000
--- a/server/entity/node-entity/monitor.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package entity
-
-//MonitorConfig 监控配置
-type MonitorConfig struct {
- APIMonitorStatus int
- StrategyMonitorStatus int
- StrategyMonitorStatusInAPI int
- APIMonitorStatusInStrategy int
-}
diff --git a/server/entity/node-entity/plugin.go b/server/entity/node-entity/plugin.go
index 1818a441cc2fa8f010f7486f7ed043812d0a35d9..3c91f267c643a706deef1fb9781c9c4363148809 100644
--- a/server/entity/node-entity/plugin.go
+++ b/server/entity/node-entity/plugin.go
@@ -5,7 +5,7 @@ import (
)
const (
- //PluginTypeGateway 全局插件
+ //PluginTypeGateway 网关插件
PluginTypeGateway = 0
//PluginTypeStrategy 策略插件
PluginTypeStrategy = 1
@@ -26,16 +26,13 @@ type PluginInfo struct {
//MapString map string
type MapString map[string]string
-//PluginFactoryHandler 插件处理factory
+//PluginFactoryHandler 插件工厂类
type PluginFactoryHandler struct {
Info *PluginInfo
Factory goku_plugin.PluginFactory
-
- //Config string
- //UpdateTag string
}
-//PluginHandlerExce plugin handler exec
+//PluginHandlerExce 插件处理类
type PluginHandlerExce struct {
PluginObj *goku_plugin.PluginObj
Name string
diff --git a/server/entity/node-entity/service.go b/server/entity/node-entity/service.go
deleted file mode 100644
index 5f7b63db34cff9bd8ee9a33bb2b94cb653d187cc..0000000000000000000000000000000000000000
--- a/server/entity/node-entity/service.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package entity
-
-//Service service
-type Service struct {
- Name string
- Driver string
- Desc string
- IsDefault bool
- Config string
- ClusterConfig string
- HealthCheck bool
- HealthCheckPath string
- HealthCheckPeriod int
- HealthCheckCode string
- HealthCheckTimeOut int
-}
diff --git a/server/entity/node-entity/strategy.go b/server/entity/node-entity/strategy.go
deleted file mode 100644
index e7feb3352ce4bcb2532f63ce40db7c83a9228459..0000000000000000000000000000000000000000
--- a/server/entity/node-entity/strategy.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package entity
-
-//Strategy strategy
-type Strategy struct {
- StrategyID string
- StrategyName string
- Auth string
- EnableStatus int
- StrategyType int
-}
-
-//
-//func (s *Strategy)Enable()bool {
-// return s.EnableStatus ==1
-//}
-
-//StrategyPluginItem strategy plugin item
-type StrategyPluginItem struct {
- StrategyID string
- PluginName string
- PluginConfig string
- UpdateTag string
- //PluginInfo string
- //PluginStatus int
-}
-
-//StrategyAPIPlugin 策略接口插件
-type StrategyAPIPlugin struct {
- APIId string
- StrategyID string
- PluginName string
- PluginConfig string
- UpdateTag string
-}
-
-//StrategyAPI 策略接口
-type StrategyAPI struct {
- APIID int
- StrategyID string
- Target string
-}
diff --git a/server/entity/plugin-entity/plugin.go b/server/entity/plugin-entity/plugin.go
index 3eda0f6e2756b3635ea128147e67517d7a91c10e..4e57e2f999c5996429be4c528216865154bd8787 100644
--- a/server/entity/plugin-entity/plugin.go
+++ b/server/entity/plugin-entity/plugin.go
@@ -1,7 +1,4 @@
-package pluginentity
-
-//GlobalPlugin 全局插件
-var GlobalPlugin = make(map[string]*Plugin)
+package plugin_entity
//Plugin 插件
type Plugin struct {
@@ -14,15 +11,6 @@ type Plugin struct {
IsStop int `json:"isStop"`
}
-//PluginParams pluginParams
-type PluginParams struct {
- PluginName string `json:"pluginName"`
- PluginConfig string `json:"pluginConfig"`
- PluginIndex int `json:"pluginPriority"`
- //PluginInfo string `json:"pluginInfo"`
- IsStop int `json:"isStop"`
-}
-
//PluginSlice 插件切片
type PluginSlice []*Plugin
diff --git a/server/entity/redis_config.go b/server/entity/redis_config.go
index 2ba704321acadf0998fb78628bf83e0d870fd30c..cf8388be32637a27ffe41fb8d4969817f9b162b7 100644
--- a/server/entity/redis_config.go
+++ b/server/entity/redis_config.go
@@ -4,7 +4,7 @@ import (
"strings"
)
-//GetMode 获取redis模式
+//GetMode 获取redis使用模式
func (c CLusterRedis) GetMode() string {
return c.Mode
}
@@ -14,12 +14,12 @@ func (c CLusterRedis) GetAddrs() []string {
return strings.Split(c.Addrs, ",")
}
-//GetMasters getMasters
+//GetMasters 获取master
func (c CLusterRedis) GetMasters() []string {
return strings.Split(c.Masters, ",")
}
-//GetDbIndex 获取数据序号
+//GetDbIndex 获取数据库序号
func (c CLusterRedis) GetDbIndex() int {
return c.DbIndex
}
diff --git a/server/entity/result_info.go b/server/entity/result_info.go
deleted file mode 100644
index 8d50f90ef2067ff0a9f72564e17d53c35314a5a6..0000000000000000000000000000000000000000
--- a/server/entity/result_info.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package entity
-
-import (
- "encoding/json"
-)
-
-//ResultInfo 结果信息
-type ResultInfo struct {
- ResultType string `json:"type"`
- StatusCode string `json:"statusCode"`
- ResultKey string `json:"resultKey"`
- Result interface{} `json:"result,omitempty"`
- ResultDesc string `json:"resultDesc,omitempty"`
-}
-
-//String string
-func String(info interface{}) string {
- resultInfo, err := json.Marshal(info)
- if err != nil {
- return ""
- }
- return string(resultInfo)
-}
-
-//GetResultInfo 获取结果信息
-func GetResultInfo(statusCode string, resultType string, resultKey string, resultDesc string, result interface{}, successCount string) map[string]interface{} {
- if resultKey == "" {
- return map[string]interface{}{
- "type": resultType,
- "statusCode": statusCode,
- "resultDesc": resultDesc,
- }
- }
- if result != nil {
- return map[string]interface{}{
- "type": resultType,
- "statusCode": statusCode,
- resultKey: result,
- "resultDesc": resultDesc,
- }
- }
- return map[string]interface{}{
- "type": resultType,
- "statusCode": statusCode,
- "resultDesc": resultDesc,
- }
-}
diff --git a/server/monitor/monitor-key/key.go b/server/monitor/monitor-key/key.go
deleted file mode 100644
index dcc63598429d9e4357a8428d728f62ef5b321e03..0000000000000000000000000000000000000000
--- a/server/monitor/monitor-key/key.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package monitorkey
-
-//MonitorKeyType 监控Key类型
-type MonitorKeyType int
-
-const (
- // GatewayRequestCount 请求次数信息
- GatewayRequestCount MonitorKeyType = iota
- GatewaySuccessCount
- GatewayStatus2xxCount
- GatewayStatus4xxCount
- GatewayStatus5xxCount
- ProxyRequestCount
- ProxySuccessCount
- ProxyStatus2xxCount
- ProxyStatus4xxCount
- ProxyStatus5xxCount
- ProxyTimeoutCount
-
- MonitorKeyTypeSize = int(ProxyTimeoutCount) + 1
-)
-
-var (
- keys []MonitorKeyType
-)
-
-func init() {
- ks := make([]MonitorKeyType, MonitorKeyTypeSize)
-
- for i := range ks {
- ks[i] = MonitorKeyType(i)
- }
- keys = ks
-}
-
-//Keys
-func Keys() []MonitorKeyType {
- return keys
-}
-
-//ToString toString
-func ToString(key int) string {
- return MonitorKeyType(key).String()
-}
-func (t MonitorKeyType) String() string {
- switch t {
- case GatewayRequestCount:
- return "gatewayRequestCount"
- case GatewaySuccessCount:
- return "gatewaySuccessCount"
- case GatewayStatus2xxCount:
- return "gatewayStatus2xxCount"
- case GatewayStatus4xxCount:
- return "gatewayStatus4xxCount"
- case GatewayStatus5xxCount:
- return "gatewayStatus5xxCount"
- case ProxyRequestCount:
- return "proxyRequestCount"
- case ProxySuccessCount:
- return "proxySuccessCount"
- case ProxyStatus2xxCount:
- return "proxyStatus2xxCount"
- case ProxyStatus4xxCount:
- return "proxyStatus4xxCount"
- case ProxyStatus5xxCount:
- return "proxyStatus5xxCount"
- case ProxyTimeoutCount:
- return "proxyTimeoutCount"
- }
- return ""
-
-}
diff --git a/server/monitor/monitor-key/redis.go b/server/monitor/monitor-key/redis.go
deleted file mode 100644
index d7b6ea9ac83db27aa49820761fcc94fb3c698bcf..0000000000000000000000000000000000000000
--- a/server/monitor/monitor-key/redis.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package monitorkey
-
-import (
- "bytes"
-)
-
-//StrategyMapKey 策略字典Key
-func StrategyMapKey(cluster, now string) string {
- key := splicing("monitor-strategy:", cluster, ":", now)
- //fmt.Println("StrategyMapKey:",key)
- return key
-}
-
-//APIMapKey 接口字典key
-func APIMapKey(cluster, strategyID, now string) string {
- key := splicing("monitor-api:", cluster, ":", strategyID, ":", now)
- //fmt.Println("APIMapKey:",key)
- return key
-}
-
-//APIValueKey api value key
-func APIValueKey(cluster, strategyID string, apiID string, now string) string {
- key := splicing("monitor-value:", cluster, ":", strategyID, ":", apiID, ":", now)
- //fmt.Println("APIValueKey:",key)
- return key
-}
-
-func splicing(args ...string) string {
-
- l := 0
- for _, arg := range args {
-
- l += len(arg)
- }
- buf := make([]byte, 0, l)
- b := bytes.NewBuffer(buf)
-
- for _, arg := range args {
- b.WriteString(arg)
- }
- return b.String()
-}
diff --git a/server/monitor/monitor-key/value.go b/server/monitor/monitor-key/value.go
deleted file mode 100644
index ddc460cd7175ebc5c94ddb8b2f13e56de51e0a49..0000000000000000000000000000000000000000
--- a/server/monitor/monitor-key/value.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package monitorkey
-
-//MonitorValues monitorValues
-type MonitorValues []int64
-
-//Add add
-func (a MonitorValues) Add(key MonitorKeyType) {
- index := int(key)
- if index < len(a) {
- a[index]++
- }
-}
-
-//Get get
-func (a MonitorValues) Get(key MonitorKeyType) int64 {
- if a == nil {
- return 0
- }
- index := int(key)
- if index < len(a) {
- return a[index]
- }
- return 0
-}
-
-//Append append
-func (a MonitorValues) Append(args ...MonitorValues) {
- if len(args) == 0 {
- return
- }
-
- for _, arg := range args {
-
- for i := range arg {
- a[i] += arg[i]
- }
- }
- return
-}
-
-//MakeValue make value
-func MakeValue() MonitorValues {
- return make(MonitorValues, MonitorKeyTypeSize)
-}
diff --git a/server/monitor/monitor-read/monitor.go b/server/monitor/monitor-read/monitor.go
deleted file mode 100644
index 7f21f84d9d912a863a64c7ed65b2bb2212b2b363..0000000000000000000000000000000000000000
--- a/server/monitor/monitor-read/monitor.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package monitorread
-
-import (
- "fmt"
- redis_manager "github.com/eolinker/goku-api-gateway/common/redis-manager"
- "github.com/eolinker/goku-api-gateway/server/dao/console-mysql/dao-monitor"
- "github.com/eolinker/goku-api-gateway/server/entity"
- "github.com/eolinker/goku-api-gateway/server/monitor/monitor-key"
- "strconv"
- "time"
-)
-
-var (
- period = 30 * time.Second
-)
-
-//SetPeriod 设置更新周期
-func SetPeriod(sec int) {
- period = time.Duration(sec) * time.Second
-}
-
-//InitMonitorRead init monitor read
-func InitMonitorRead(clusters []*entity.Cluster) error {
- for _, c := range clusters {
- _, has := redis_manager.Get(c.Name)
- if !has {
- return fmt.Errorf("no redis for cluster:%s", c.Name)
- }
- }
- for _, c := range clusters {
- go doLoopForCluster(c.Name, c.ID)
- }
- return nil
-}
-
-func doLoopForCluster(clusterName string, clusterID int) {
-
- t := time.NewTimer(period)
-
- for {
- select {
- case <-t.C:
- {
- read(clusterName, clusterID, time.Now())
- }
- }
- t.Reset(period)
- }
-
-}
-func read(clusterName string, clusterID int, t time.Time) {
- hour := t.Format("2006010215")
- now := t.Format("2006-01-02 15:04:05")
-
- hourValue, _ := strconv.Atoi(hour)
-
- // 包含 strate == ""
- strategyIds, err := readStrategyID(hour, clusterName)
- if err != nil {
- return
- }
- for _, strategyID := range strategyIds {
-
- apiIds, err := readAPIId(hour, clusterName, strategyID)
- if err != nil {
- continue
- }
-
- for _, apiID := range apiIds {
-
- valus, err := readValue(hour, clusterName, strategyID, apiID)
- if err != nil {
- continue
- }
- apiID, _ := strconv.Atoi(apiID)
-
- dao_monitor.Save(strategyID, apiID, clusterID, hourValue, now, valus)
- }
- }
-
-}
-func readStrategyID(now, cluster string) ([]string, error) {
- key := monitorkey.StrategyMapKey(cluster, now)
- conn, _ := redis_manager.Get(cluster)
- return conn.HKeys(key).Result()
-
-}
-func readAPIId(now, cluster, strategyID string) ([]string, error) {
- key := monitorkey.APIMapKey(cluster, strategyID, now)
- conn, _ := redis_manager.Get(cluster)
- return conn.HKeys(key).Result()
-}
-func readValue(now, cluster, strategyID string, apiID string) (map[string]string, error) {
- conn, _ := redis_manager.Get(cluster)
- key := monitorkey.APIValueKey(cluster, strategyID, apiID, now)
- return conn.HGetAll(key).Result()
-}
diff --git a/server/monitor/monitor-write/monitor.go b/server/monitor/monitor-write/monitor.go
deleted file mode 100644
index 9359d26d788aa010107259b1a69d058b0063ffa0..0000000000000000000000000000000000000000
--- a/server/monitor/monitor-write/monitor.go
+++ /dev/null
@@ -1,176 +0,0 @@
-package monitorwrite
-
-import (
- "time"
-
- redis_manager "github.com/eolinker/goku-api-gateway/common/redis-manager"
- gateway_manager "github.com/eolinker/goku-api-gateway/goku-node/manager/gateway-manager"
- monitor_key "github.com/eolinker/goku-api-gateway/server/monitor/monitor-key"
-)
-
-var (
- cluster string
- saveCH = make(chan *_Action, 100)
- writeCH = make(chan *_MonitorMap, 1)
-
- writeProid = 5
-)
-
-type _Action struct {
- StrategyID string
- APIID string
- Keys []monitor_key.MonitorKeyType
-}
-type _MonitorMap struct {
- now time.Time
- strategys map[string]*_StrategyInfo
-}
-type _StrategyInfo struct {
- values map[string]monitor_key.MonitorValues
-}
-
-//InitMonitorWrite 初始化监控写入器
-func InitMonitorWrite(clusterName string) {
- cluster = clusterName
- go saveLoop()
- go temporaryStorage()
-
-}
-func add(action *_Action) {
- saveCH <- action
-}
-func saveLoop() {
- for {
- select {
- case m := <-writeCH:
- {
- conn := redis_manager.GetConnection()
- pipeline := conn.Pipeline()
- tnow := m.now.Format("2006010215")
-
- strategyMapKey := monitor_key.StrategyMapKey(cluster, tnow)
- for strategyID, strategy := range m.strategys {
- pipeline.HSetNX(strategyMapKey, strategyID, 1)
-
- apisOfStrategyKey := monitor_key.APIMapKey(cluster, strategyID, tnow)
-
- for apiID, values := range strategy.values {
-
- pipeline.HSetNX(apisOfStrategyKey, apiID, 1)
-
- key := monitor_key.APIValueKey(cluster, strategyID, apiID, tnow)
- for k, v := range values {
- if v > 0 {
- pipeline.HIncrBy(key, monitor_key.ToString(k), v)
- }
- }
- }
- }
- pipeline.Exec()
- pipeline.Close()
- }
- }
- }
-}
-func temporaryStorage() {
- t := time.NewTicker(time.Duration(writeProid) * time.Second)
- defer t.Stop()
-
- ts := &_MonitorMap{
- strategys: make(map[string]*_StrategyInfo),
- }
-
- for {
- select {
- case <-t.C:
-
- if len(ts.strategys) > 0 {
- o := ts
- ts = &_MonitorMap{
- strategys: make(map[string]*_StrategyInfo),
- }
- o.now = time.Now()
- writeCH <- o
- }
- case action, ok := <-saveCH:
- if !ok {
- return
- }
-
- strategy, has := ts.strategys[action.StrategyID]
- if !has {
- strategy = &_StrategyInfo{
- values: make(map[string]monitor_key.MonitorValues),
- }
- ts.strategys[action.StrategyID] = strategy
- }
-
- apivalue, has := strategy.values[action.APIID]
- if !has {
- apivalue = monitor_key.MakeValue()
- strategy.values[action.APIID] = apivalue
- }
-
- for _, i := range action.Keys {
- apivalue.Add(i)
- }
- }
- }
-}
-
-//AddMonitor 新增监控
-func AddMonitor(strategyID string, apiID string, proxyStatusCode int, gatewayStatusCode int) {
-
- keys := createField(proxyStatusCode, gatewayStatusCode)
-
- add(&_Action{
- StrategyID: strategyID,
- APIID: apiID,
- Keys: keys,
- })
- // proxyStatusCode == 0 没有进行转发
-
-}
-
-func createField(proxyStatusCode int, gatewayStatusCode int) []monitor_key.MonitorKeyType {
- fieldkeys := make([]monitor_key.MonitorKeyType, 0, 7)
-
- fieldkeys = append(fieldkeys, monitor_key.GatewayRequestCount)
- if proxyStatusCode != 0 {
- fieldkeys = append(fieldkeys, monitor_key.ProxyRequestCount)
- // 超时
- if proxyStatusCode == -1 {
- fieldkeys = append(fieldkeys, monitor_key.ProxyTimeoutCount)
- fieldkeys = append(fieldkeys, monitor_key.ProxyStatus5xxCount)
- } else {
-
- if proxyStatusCode > 199 && proxyStatusCode < 300 {
- fieldkeys = append(fieldkeys, monitor_key.ProxyStatus2xxCount)
- } else if proxyStatusCode > 399 && proxyStatusCode < 500 {
- fieldkeys = append(fieldkeys, monitor_key.ProxyStatus4xxCount)
- } else if proxyStatusCode > 499 && proxyStatusCode < 600 {
- fieldkeys = append(fieldkeys, monitor_key.ProxyStatus5xxCount)
- }
- if gateway_manager.IsSucess(proxyStatusCode) {
- fieldkeys = append(fieldkeys, monitor_key.ProxySuccessCount)
- }
- }
- }
-
- if gatewayStatusCode != 0 {
-
- if gatewayStatusCode > 199 && gatewayStatusCode < 300 {
- fieldkeys = append(fieldkeys, monitor_key.GatewayStatus2xxCount)
-
- } else if gatewayStatusCode > 399 && gatewayStatusCode < 500 {
- fieldkeys = append(fieldkeys, monitor_key.GatewayStatus4xxCount)
-
- } else if gatewayStatusCode > 499 && gatewayStatusCode < 600 {
- fieldkeys = append(fieldkeys, monitor_key.GatewayStatus5xxCount)
- }
- if gateway_manager.IsSucess(gatewayStatusCode) {
- fieldkeys = append(fieldkeys, monitor_key.GatewaySuccessCount)
- }
- }
- return fieldkeys
-}
diff --git a/utils/alert.go b/utils/alert.go
deleted file mode 100644
index 16ff2d9f0eaf62570de6ed2ae250afd5bf1c1758..0000000000000000000000000000000000000000
--- a/utils/alert.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package utils
-
-import (
- log "github.com/eolinker/goku-api-gateway/goku-log"
- "io/ioutil"
- "net"
- "strings"
- "time"
-)
-
-var (
- currentAlertBody string
-)
-
-func init() {
- body, err := ioutil.ReadFile("html/currentAlert.html")
- if err != nil {
- log.Panic(err)
- }
- currentAlertBody = string(body)
-}
-
-//SendAlertMail 发送告警邮件
-func SendAlertMail(sender, senderPassword, smtpAddress, smtpPort, smtpProtocol, receiverMail, requestURL, alertLogPath, alertPeriod, alertCount, apiName, apiID, targetServer, proxyURL string) (bool, error) {
- alertTime := time.Now().Format("2006-01-02 15:04:05")
-
- bodyStr := currentAlertBody
- bodyStr = strings.Replace(bodyStr, "$requestURL", requestURL, -1)
- bodyStr = strings.Replace(bodyStr, "$alertTime", alertTime, -1)
- bodyStr = strings.Replace(bodyStr, "$alertLogPath", alertLogPath, -1)
- bodyStr = strings.Replace(bodyStr, "$alertPeriod", period[alertPeriod], -1)
- bodyStr = strings.Replace(bodyStr, "$alertCount", alertCount, -1)
- bodyStr = strings.Replace(bodyStr, "$apiID", apiID, -1)
- bodyStr = strings.Replace(bodyStr, "$targetServer", targetServer, -1)
- bodyStr = strings.Replace(bodyStr, "$proxyURL", proxyURL, -1)
- bodyStr = strings.Replace(bodyStr, "$apiName", apiName, -1)
- host := net.JoinHostPort(smtpAddress, smtpPort)
- subject := "GoKu告警:" + requestURL + "接口在" + period[alertPeriod] + "分钟内转发失败" + alertCount + "次"
- err := SendToMail(sender, senderPassword, host, receiverMail, subject, bodyStr, "html", smtpProtocol)
- if err != nil {
- log.Warn("SendAlertMail:", err)
- return false, err
- }
- return true, nil
-}
diff --git a/utils/function.go b/utils/function.go
index 6429ffa7f0cf6e4cdc3bd5d62199098461252ac3..37b6d4a9af220adcecfb14e609c1ed6742a3dbcf 100644
--- a/utils/function.go
+++ b/utils/function.go
@@ -3,7 +3,9 @@ package utils
import (
"crypto/md5"
"encoding/hex"
+ "fmt"
"math/rand"
+ "net"
"os"
"os/exec"
"regexp"
@@ -12,15 +14,6 @@ import (
"time"
)
-//ConvertString 将string转为int类型
-func ConvertString(params string) (int, bool) {
- id, err := strconv.Atoi(params)
- if err != nil {
- return 0, false
- }
- return id, true
-}
-
//ValidateRemoteAddr 判断ip端口是否合法
func ValidateRemoteAddr(ip string) bool {
match, err := regexp.MatchString(`^(?:(?:1[0-9][0-9]\.)|(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5])|(?:[1-9][0-9])|(?:[0-9]))\:(([0-9])|([1-9][0-9]{1,3})|([1-6][0-9]{0,4}))$`, ip)
@@ -30,7 +23,7 @@ func ValidateRemoteAddr(ip string) bool {
return match
}
-//InterceptIP 过滤IP
+//InterceptIP 获取IP
func InterceptIP(str, substr string) string {
result := strings.Index(str, substr)
var rs string
@@ -42,7 +35,7 @@ func InterceptIP(str, substr string) string {
return rs
}
-//Md5 md5
+//Md5 md5加密
func Md5(encodeString string) string {
h := md5.New()
h.Write([]byte(encodeString))
@@ -61,7 +54,7 @@ func GetRandomString(num int) string {
return string(result)
}
-// CheckFileIsExist 判断文件是否存在 存在返回 true 不存在返回false
+//CheckFileIsExist 判断文件是否存在 存在返回 true 不存在返回false
func CheckFileIsExist(filename string) bool {
if _, err := os.Stat(filename); os.IsNotExist(err) {
return false
@@ -69,7 +62,7 @@ func CheckFileIsExist(filename string) bool {
return true
}
-// Stop 关闭网关服务,重启读取配置文件
+//Stop 关闭网关服务,重启读取配置文件
func Stop() bool {
id := os.Getpid()
cmd := exec.Command("/bin/bash", "-c", "kill -HUP "+strconv.Itoa(id))
@@ -78,3 +71,23 @@ func Stop() bool {
}
return true
}
+
+//GetMac 获取MAC地址
+func GetMac() (bool, string) {
+ interfaces, err := net.Interfaces()
+ if err != nil {
+ return false, "Poor soul, here is what you got: " + err.Error()
+ }
+ for _, inter := range interfaces {
+ mac := inter.HardwareAddr //获取本机MAC地址
+ m := fmt.Sprintf("%s", mac)
+ match, err := regexp.MatchString(`[0-9a-f][0-9a-f][:-][0-9a-f][0-9a-f][:-][0-9a-f][0-9a-f][:-][0-9a-f][0-9a-f][:-][0-9a-f][0-9a-f][:-][0-9a-f][0-9a-f]`, m)
+ if err != nil {
+ return false, ""
+ }
+ if match {
+ return true, string(m)
+ }
+ }
+ return false, ""
+}
diff --git a/utils/mail.go b/utils/mail.go
index a5d8af3c6acc5cb659753bdc48768fffa8a7fc62..05ae12f5c92a69fcf12dc3a18c65887d29eda8f0 100644
--- a/utils/mail.go
+++ b/utils/mail.go
@@ -2,27 +2,20 @@ package utils
import (
"crypto/tls"
- log "github.com/eolinker/goku-api-gateway/goku-log"
"net"
"net/smtp"
"strings"
-)
-var period = map[string]string{
- "0": "1",
- "1": "5",
- "2": "15",
- "3": "30",
- "4": "60",
-}
+ log "github.com/eolinker/goku-api-gateway/goku-log"
+)
//SendToMail 发送邮件
func SendToMail(user, password, host, to, subject, body, mailtype, smtpProtocol string) error {
hp := strings.Split(host, ":")
auth := smtp.PlainAuth("", user, password, hp[0])
- sendTo := strings.Split(to, ",")
- if len(sendTo) < 2 {
- if sendTo[0] == "" {
+ sendTO := strings.Split(to, ",")
+ if len(sendTO) < 2 {
+ if sendTO[0] == "" {
return nil
}
}
@@ -41,7 +34,7 @@ func SendToMail(user, password, host, to, subject, body, mailtype, smtpProtocol
host,
auth,
user,
- sendTo,
+ sendTO,
msg,
)
if err != nil {
@@ -50,15 +43,15 @@ func SendToMail(user, password, host, to, subject, body, mailtype, smtpProtocol
host,
nil,
user,
- sendTo,
+ sendTO,
msg,
)
}
} else {
- err = smtp.SendMail(host, auth, user, sendTo, msg)
+ err = smtp.SendMail(host, auth, user, sendTO, msg)
if err != nil {
- err = smtp.SendMail(host, nil, user, sendTo, msg)
+ err = smtp.SendMail(host, nil, user, sendTO, msg)
}
}
return err
diff --git a/utils/request.go b/utils/request.go
index cbd164fc28e7c12cde89775984fac6f84dc393d2..fd49ff52eb8dff06846c57c9ebe1063b9ef3d96f 100644
--- a/utils/request.go
+++ b/utils/request.go
@@ -9,7 +9,7 @@ import (
"time"
)
-//CheckPluginIsAvailiable 检查插件是否可用
+//CheckPluginIsAvailiable 检查插件是否可用
func CheckPluginIsAvailiable(pluginName string, nodeList []map[string]interface{}) (bool, []map[string]interface{}) {
errNodeList := make([]map[string]interface{}, 0)
for _, v := range nodeList {
diff --git a/utils/ssh.go b/utils/ssh.go
index fd0ff3c66ea296fa940a3971fd0ecce7a22e91a0..09a463bad31d5122ae9d4d3e70a54f733958e005 100644
--- a/utils/ssh.go
+++ b/utils/ssh.go
@@ -2,13 +2,14 @@ package utils
import (
"fmt"
- "golang.org/x/crypto/ssh"
"net"
"time"
+
+ "golang.org/x/crypto/ssh"
// "io/ioutil"
)
-//Connect ssh连接
+//Connect SSH连接
func Connect(user, password, host, key string, port int, cipherList []string) (*ssh.Session, error) {
var (
auth []ssh.AuthMethod
diff --git a/utils/string.go b/utils/string.go
index 52892a19c8edd1a03172c00aa7fa359d1aa28887..4d6c2ae700832196bda4a9a74b11871e71079aaa 100644
--- a/utils/string.go
+++ b/utils/string.go
@@ -2,7 +2,7 @@ package utils
import "strings"
-//TrimPrefixAll trimPerfixAll
+//TrimPrefixAll 删除所有前缀
func TrimPrefixAll(s string, r string) string {
for strings.HasPrefix(s, r) {
@@ -11,7 +11,7 @@ func TrimPrefixAll(s string, r string) string {
return s
}
-//TrimSuffixAll trimSuffixAll
+//TrimSuffixAll 删除所有后缀
func TrimSuffixAll(s string, r string) string {
for strings.HasSuffix(s, r) {
diff --git a/utils/uuid.go b/utils/uuid.go
index 9ca6f5dec6f358afe5b4c128b37d5eec6678d9f8..8e6deca280e6005813d0e4b50cac410b908efcf3 100644
--- a/utils/uuid.go
+++ b/utils/uuid.go
@@ -6,7 +6,7 @@ import (
"strings"
)
-//TimeUUID uuid
+//TimeUUID 获取uuid
func TimeUUID() string {
out, err := exec.Command("uuidgen").Output()
if err != nil {