Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
二次元的罪恶王冠
beego
提交
28d3f624
B
beego
项目概览
二次元的罪恶王冠
/
beego
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
B
beego
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
28d3f624
编写于
7月 08, 2020
作者:
M
Ming Deng
提交者:
GitHub
7月 08, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #4055 from tayoogunbiyi/develop
Allow Healthcheck endpoint return JSON for Kubernetes
上级
926b80d1
d7b0d553
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
212 addition
and
12 deletion
+212
-12
admin.go
admin.go
+50
-12
admin_test.go
admin_test.go
+162
-0
未找到文件。
admin.go
浏览文件 @
28d3f624
...
...
@@ -21,6 +21,7 @@ import (
"net/http"
"os"
"reflect"
"strconv"
"text/template"
"time"
...
...
@@ -71,7 +72,7 @@ func init() {
// AdminIndex is the default http.Handler for admin module.
// it matches url pattern "/".
func
adminIndex
(
rw
http
.
ResponseWriter
,
_
*
http
.
Request
)
{
execTpl
(
rw
,
map
[
interface
{}]
interface
{}{},
indexTpl
,
defaultScriptsTpl
)
writeTemplate
(
rw
,
map
[
interface
{}]
interface
{}{},
indexTpl
,
defaultScriptsTpl
)
}
// QpsIndex is the http.Handler for writing qps statistics map result info in http.ResponseWriter.
...
...
@@ -91,7 +92,7 @@ func qpsIndex(rw http.ResponseWriter, _ *http.Request) {
}
}
execTpl
(
rw
,
data
,
qpsTpl
,
defaultScriptsTpl
)
writeTemplate
(
rw
,
data
,
qpsTpl
,
defaultScriptsTpl
)
}
// ListConf is the http.Handler of displaying all beego configuration values as key/value pair.
...
...
@@ -128,7 +129,7 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
}
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Routers"
execTpl
(
rw
,
data
,
routerAndFilterTpl
,
defaultScriptsTpl
)
writeTemplate
(
rw
,
data
,
routerAndFilterTpl
,
defaultScriptsTpl
)
case
"filter"
:
var
(
content
=
M
{
...
...
@@ -171,7 +172,7 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Filters"
execTpl
(
rw
,
data
,
routerAndFilterTpl
,
defaultScriptsTpl
)
writeTemplate
(
rw
,
data
,
routerAndFilterTpl
,
defaultScriptsTpl
)
default
:
rw
.
Write
([]
byte
(
"command not support"
))
}
...
...
@@ -279,9 +280,7 @@ func profIndex(rw http.ResponseWriter, r *http.Request) {
http
.
Error
(
rw
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
}
rw
.
Header
()
.
Set
(
"Content-Type"
,
"application/json"
)
rw
.
Write
(
dataJSON
)
writeJSON
(
rw
,
dataJSON
)
return
}
...
...
@@ -290,12 +289,12 @@ func profIndex(rw http.ResponseWriter, r *http.Request) {
if
command
==
"gc summary"
{
defaultTpl
=
gcAjaxTpl
}
execTpl
(
rw
,
data
,
profillingTpl
,
defaultTpl
)
writeTemplate
(
rw
,
data
,
profillingTpl
,
defaultTpl
)
}
// Healthcheck is a http.Handler calling health checking and showing the result.
// it's in "/healthcheck" pattern in admin module.
func
healthcheck
(
rw
http
.
ResponseWriter
,
_
*
http
.
Request
)
{
func
healthcheck
(
rw
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
var
(
result
[]
string
data
=
make
(
map
[
interface
{}]
interface
{})
...
...
@@ -322,10 +321,49 @@ func healthcheck(rw http.ResponseWriter, _ *http.Request) {
*
resultList
=
append
(
*
resultList
,
result
)
}
queryParams
:=
r
.
URL
.
Query
()
jsonFlag
:=
queryParams
.
Get
(
"json"
)
shouldReturnJSON
,
_
:=
strconv
.
ParseBool
(
jsonFlag
)
if
shouldReturnJSON
{
response
:=
buildHealthCheckResponseList
(
resultList
)
jsonResponse
,
err
:=
json
.
Marshal
(
response
)
if
err
!=
nil
{
http
.
Error
(
rw
,
err
.
Error
(),
http
.
StatusInternalServerError
)
}
else
{
writeJSON
(
rw
,
jsonResponse
)
}
return
}
content
[
"Data"
]
=
resultList
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Health Check"
execTpl
(
rw
,
data
,
healthCheckTpl
,
defaultScriptsTpl
)
writeTemplate
(
rw
,
data
,
healthCheckTpl
,
defaultScriptsTpl
)
}
func
buildHealthCheckResponseList
(
healthCheckResults
*
[][]
string
)
[]
map
[
string
]
interface
{}
{
response
:=
make
([]
map
[
string
]
interface
{},
len
(
*
healthCheckResults
))
for
i
,
healthCheckResult
:=
range
*
healthCheckResults
{
currentResultMap
:=
make
(
map
[
string
]
interface
{})
currentResultMap
[
"name"
]
=
healthCheckResult
[
0
]
currentResultMap
[
"message"
]
=
healthCheckResult
[
1
]
currentResultMap
[
"status"
]
=
healthCheckResult
[
2
]
response
[
i
]
=
currentResultMap
}
return
response
}
func
writeJSON
(
rw
http
.
ResponseWriter
,
jsonData
[]
byte
)
{
rw
.
Header
()
.
Set
(
"Content-Type"
,
"application/json"
)
rw
.
Write
(
jsonData
)
}
// TaskStatus is a http.Handler with running task status (task name, status and the last execution).
...
...
@@ -371,10 +409,10 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
content
[
"Data"
]
=
resultList
data
[
"Content"
]
=
content
data
[
"Title"
]
=
"Tasks"
execTpl
(
rw
,
data
,
tasksTpl
,
defaultScriptsTpl
)
writeTemplate
(
rw
,
data
,
tasksTpl
,
defaultScriptsTpl
)
}
func
execTpl
(
rw
http
.
ResponseWriter
,
data
map
[
interface
{}]
interface
{},
tpls
...
string
)
{
func
writeTemplate
(
rw
http
.
ResponseWriter
,
data
map
[
interface
{}]
interface
{},
tpls
...
string
)
{
tmpl
:=
template
.
Must
(
template
.
New
(
"dashboard"
)
.
Parse
(
dashboardTpl
))
for
_
,
tpl
:=
range
tpls
{
tmpl
=
template
.
Must
(
tmpl
.
Parse
(
tpl
))
...
...
admin_test.go
浏览文件 @
28d3f624
package
beego
import
(
"encoding/json"
"errors"
"fmt"
"net/http"
"net/http/httptest"
"reflect"
"strings"
"testing"
"github.com/astaxie/beego/toolbox"
)
type
SampleDatabaseCheck
struct
{
}
type
SampleCacheCheck
struct
{
}
func
(
dc
*
SampleDatabaseCheck
)
Check
()
error
{
return
nil
}
func
(
cc
*
SampleCacheCheck
)
Check
()
error
{
return
errors
.
New
(
"no cache detected"
)
}
func
TestList_01
(
t
*
testing
.
T
)
{
m
:=
make
(
M
)
list
(
"BConfig"
,
BConfig
,
m
)
...
...
@@ -75,3 +97,143 @@ func oldMap() M {
m
[
"BConfig.Log.Outputs"
]
=
BConfig
.
Log
.
Outputs
return
m
}
func
TestWriteJSON
(
t
*
testing
.
T
)
{
t
.
Log
(
"Testing the adding of JSON to the response"
)
w
:=
httptest
.
NewRecorder
()
originalBody
:=
[]
int
{
1
,
2
,
3
}
res
,
_
:=
json
.
Marshal
(
originalBody
)
writeJSON
(
w
,
res
)
decodedBody
:=
[]
int
{}
err
:=
json
.
NewDecoder
(
w
.
Body
)
.
Decode
(
&
decodedBody
)
if
err
!=
nil
{
t
.
Fatal
(
"Could not decode response body into slice."
)
}
for
i
:=
range
decodedBody
{
if
decodedBody
[
i
]
!=
originalBody
[
i
]
{
t
.
Fatalf
(
"Expected %d but got %d in decoded body slice"
,
originalBody
[
i
],
decodedBody
[
i
])
}
}
}
func
TestHealthCheckHandlerDefault
(
t
*
testing
.
T
)
{
endpointPath
:=
"/healthcheck"
toolbox
.
AddHealthCheck
(
"database"
,
&
SampleDatabaseCheck
{})
toolbox
.
AddHealthCheck
(
"cache"
,
&
SampleCacheCheck
{})
req
,
err
:=
http
.
NewRequest
(
"GET"
,
endpointPath
,
nil
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
w
:=
httptest
.
NewRecorder
()
handler
:=
http
.
HandlerFunc
(
healthcheck
)
handler
.
ServeHTTP
(
w
,
req
)
if
status
:=
w
.
Code
;
status
!=
http
.
StatusOK
{
t
.
Errorf
(
"handler returned wrong status code: got %v want %v"
,
status
,
http
.
StatusOK
)
}
if
!
strings
.
Contains
(
w
.
Body
.
String
(),
"database"
)
{
t
.
Errorf
(
"Expected 'database' in generated template."
)
}
}
func
TestBuildHealthCheckResponseList
(
t
*
testing
.
T
)
{
healthCheckResults
:=
[][]
string
{
[]
string
{
"error"
,
"Database"
,
"Error occured whie starting the db"
,
},
[]
string
{
"success"
,
"Cache"
,
"Cache started successfully"
,
},
}
responseList
:=
buildHealthCheckResponseList
(
&
healthCheckResults
)
if
len
(
responseList
)
!=
len
(
healthCheckResults
)
{
t
.
Errorf
(
"invalid response map length: got %d want %d"
,
len
(
responseList
),
len
(
healthCheckResults
))
}
responseFields
:=
[]
string
{
"name"
,
"message"
,
"status"
}
for
_
,
response
:=
range
responseList
{
for
_
,
field
:=
range
responseFields
{
_
,
ok
:=
response
[
field
]
if
!
ok
{
t
.
Errorf
(
"expected %s to be in the response %v"
,
field
,
response
)
}
}
}
}
func
TestHealthCheckHandlerReturnsJSON
(
t
*
testing
.
T
)
{
toolbox
.
AddHealthCheck
(
"database"
,
&
SampleDatabaseCheck
{})
toolbox
.
AddHealthCheck
(
"cache"
,
&
SampleCacheCheck
{})
req
,
err
:=
http
.
NewRequest
(
"GET"
,
"/healthcheck?json=true"
,
nil
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
w
:=
httptest
.
NewRecorder
()
handler
:=
http
.
HandlerFunc
(
healthcheck
)
handler
.
ServeHTTP
(
w
,
req
)
if
status
:=
w
.
Code
;
status
!=
http
.
StatusOK
{
t
.
Errorf
(
"handler returned wrong status code: got %v want %v"
,
status
,
http
.
StatusOK
)
}
decodedResponseBody
:=
[]
map
[
string
]
interface
{}{}
expectedResponseBody
:=
[]
map
[
string
]
interface
{}{}
expectedJSONString
:=
[]
byte
(
`
[
{
"message":"database",
"name":"success",
"status":"OK"
},
{
"message":"cache",
"name":"error",
"status":"no cache detected"
}
]
`
)
json
.
Unmarshal
(
expectedJSONString
,
&
expectedResponseBody
)
json
.
Unmarshal
(
w
.
Body
.
Bytes
(),
&
decodedResponseBody
)
if
len
(
expectedResponseBody
)
!=
len
(
decodedResponseBody
)
{
t
.
Errorf
(
"invalid response map length: got %d want %d"
,
len
(
decodedResponseBody
),
len
(
expectedResponseBody
))
}
if
!
reflect
.
DeepEqual
(
decodedResponseBody
,
expectedResponseBody
)
{
t
.
Errorf
(
"handler returned unexpected body: got %v want %v"
,
decodedResponseBody
,
expectedResponseBody
)
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录