Skip to content

Commit

Permalink
#79 add get interface for polling data (#98)
Browse files Browse the repository at this point in the history
* add get interface for polling data

* change header

* db modify

* fix update failed

* modify as comment

* modify as comment

* go checker

* add handler to test

* modify

* when header is empty don't record
  • Loading branch information
GuoYL123 authored Mar 20, 2020
1 parent 360d9b5 commit c898a7e
Show file tree
Hide file tree
Showing 12 changed files with 209 additions and 41 deletions.
16 changes: 6 additions & 10 deletions deployments/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,39 +98,35 @@ db.createCollection( "view", {
} );

db.createCollection( "polling_detail", {
capped: true,
max: 100,
validator: { $jsonSchema: {
bsonType: "object",
required: [ "id","params","session_id","url_path" ],
required: [ "id","session_id","domain","url_path" ],
properties: {
id: {
bsonType: "string",
},
session_id: {
bsonType: "string",
},
domain: {
bsonType: "string",
},
params: {
bsonType: "string"
bsonType: "object"
},
ip: {
bsonType: "string"
},
user_agent: {
bsonType: "string"
},
url_path: {
bsonType: "string"
},
response_body: {
bsonType: "object"
},
response_header: {
bsonType: "object"
},
response_code: {
bsonType: "string"
bsonType: "number"
}
}
} }
Expand All @@ -142,7 +138,7 @@ db.kv.createIndex({key: 1, label_id: 1,domain:1,project:1},{ unique: true });
db.label.createIndex({"id": 1}, { unique: true } );
db.label.createIndex({format: 1,domain:1,project:1},{ unique: true });
db.polling_detail.createIndex({"id": 1}, { unique: true } );
db.polling_detail.createIndex({session:1,domain:1}, { unique: true } );
db.polling_detail.createIndex({session_id:1,domain:1}, { unique: true } );
db.view.createIndex({"id": 1}, { unique: true } );
db.view.createIndex({display:1,domain:1,project:1},{ unique: true });
//db config
Expand Down
5 changes: 5 additions & 0 deletions pkg/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ const (
QueryParamStatus = "status"
QueryParamOffset = "offset"
QueryParamLimit = "limit"
//polling data
QueryParamSessionID = "sessionId"
QueryParamIP = "ip"
QueryParamURLPath = "urlPath"
QueryParamUserAgent = "userAgent"
)

//http headers
Expand Down
14 changes: 14 additions & 0 deletions pkg/model/db_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,17 @@ type ViewDoc struct {
Domain string `json:"domain,omitempty" yaml:"domain,omitempty"`
Criteria string `json:"criteria,omitempty" yaml:"criteria,omitempty"`
}

//PollingDetail is db struct, it record operation history
type PollingDetail struct {
ID string `json:"id,omitempty" yaml:"id,omitempty"`
SessionID string `json:"session_id,omitempty" bson:"session_id," yaml:"session_id,omitempty"`
Domain string `json:"domain,omitempty" yaml:"domain,omitempty"`
PollingData map[string]interface{} `json:"params,omitempty" yaml:"params,omitempty"`
IP string `json:"ip,omitempty" yaml:"ip,omitempty"`
UserAgent string `json:"user_agent,omitempty" bson:"user_agent," yaml:"user_agent,omitempty"`
URLPath string `json:"url_path,omitempty" bson:"url_path," yaml:"url_path,omitempty"`
ResponseBody interface{} `json:"response_body,omitempty" bson:"response_body," yaml:"response_body,omitempty"`
ResponseHeader map[string][]string `json:"response_header,omitempty" bson:"response_header," yaml:"response_header,omitempty"`
ResponseCode int `json:"response_code,omitempty" bson:"response_code," yaml:"response_code,omitempty"`
}
20 changes: 6 additions & 14 deletions pkg/model/kv.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,6 @@ type ViewResponse struct {
Data []*ViewDoc `json:"data,omitempty"`
}

//PollingDetail record operation history
type PollingDetail struct {
ID string `json:"id,omitempty" yaml:"id,omitempty"`
SessionID string `json:"session_id,omitempty" yaml:"session_id,omitempty"`
Domain string `json:"domain,omitempty" yaml:"domain,omitempty"`
PollingData map[string]interface{} `json:"params,omitempty" yaml:"params,omitempty"`
IP string `json:"ip,omitempty" yaml:"ip,omitempty"`
UserAgent string `json:"user_agent,omitempty" yaml:"user_agent,omitempty"`
URLPath string `json:"url_path,omitempty" yaml:"url_path,omitempty"`
ResponseBody interface{} `json:"response_body,omitempty" yaml:"response_body,omitempty"`
ResponseHeader map[string][]string `json:"response_header,omitempty" yaml:"response_header,omitempty"`
ResponseCode int `json:"response_code,omitempty" yaml:"response_code,omitempty"`
}

//DocResponseSingleKey is response doc
type DocResponseSingleKey struct {
CreateRevision int64 `json:"create_revision"`
Expand All @@ -87,6 +73,12 @@ type DocResponseGetKey struct {
Total int64 `json:"total"`
}

//PollingDataResponse is response doc
type PollingDataResponse struct {
Data []*PollingDetail `json:"data"`
Total int `json:"total"`
}

//DocHealthCheck is response doc
type DocHealthCheck struct {
Version string `json:"version"`
Expand Down
17 changes: 6 additions & 11 deletions server/handler/track_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/apache/servicecomb-kie/pkg/iputil"
"github.com/apache/servicecomb-kie/pkg/model"
"github.com/apache/servicecomb-kie/server/resource/v1"
"github.com/apache/servicecomb-kie/server/service/mongo/record"
"github.com/apache/servicecomb-kie/server/service/mongo/track"
"github.com/emicklei/go-restful"
"github.com/go-chassis/go-chassis/core/handler"
"github.com/go-chassis/go-chassis/core/invocation"
Expand Down Expand Up @@ -60,14 +60,7 @@ func (h *TrackHandler) Handle(chain *handler.Chain, inv *invocation.Invocation,
return
}
chain.Next(inv, func(ir *invocation.Response) error {
resp, ok := ir.Result.(*restful.Response)
if !ok {
err := cb(ir)
if err != nil {
return err
}
return nil
}
resp, _ := ir.Result.(*restful.Response)
revStr := req.QueryParameter(common.QueryParamRev)
wait := req.QueryParameter(common.QueryParamWait)
data := &model.PollingDetail{}
Expand All @@ -78,14 +71,16 @@ func (h *TrackHandler) Handle(chain *handler.Chain, inv *invocation.Invocation,
data.IP = iputil.ClientIP(req.Request)
data.ResponseBody = inv.Ctx.Value(common.RespBodyContextKey)
data.ResponseCode = ir.Status
data.ResponseHeader = resp.Header()
if resp != nil {
data.ResponseHeader = resp.Header()
}
data.PollingData = map[string]interface{}{
"revStr": revStr,
"wait": wait,
"project": req.HeaderParameter(v1.PathParameterProject),
"labels": req.QueryParameter("label"),
}
_, err := record.CreateOrUpdate(inv.Ctx, data)
_, err := track.CreateOrUpdate(inv.Ctx, data)
if err != nil {
openlogging.Warn("record polling detail failed" + err.Error())
err := cb(ir)
Expand Down
2 changes: 1 addition & 1 deletion server/resource/v1/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import (
//const of server
const (
HeaderUserAgent = "User-Agent"
HeaderSessionID = "sessionID"
HeaderSessionID = "X-Session-Id"
PathParameterProject = "project"
PathParameterKey = "key"
AttributeDomainKey = "domain"
Expand Down
25 changes: 25 additions & 0 deletions server/resource/v1/doc_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,31 @@ var (
ParamType: goRestful.QueryParameterKind,
Desc: "pagination",
}
//polling data
DocQuerySessionIDParameters = &restful.Parameters{
DataType: "string",
Name: common.QueryParamSessionID,
ParamType: goRestful.QueryParameterKind,
Desc: "sessionId is the Unique identification of the client",
}
DocQueryIPParameters = &restful.Parameters{
DataType: "string",
Name: common.QueryParamIP,
ParamType: goRestful.QueryParameterKind,
Desc: "client ip",
}
DocQueryURLPathParameters = &restful.Parameters{
DataType: "string",
Name: common.QueryParamURLPath,
ParamType: goRestful.QueryParameterKind,
Desc: "address of the call",
}
DocQueryUserAgentParameters = &restful.Parameters{
DataType: "string",
Name: common.QueryParamUserAgent,
ParamType: goRestful.QueryParameterKind,
Desc: "user agent of the call",
}
)

//swagger doc path params
Expand Down
62 changes: 62 additions & 0 deletions server/resource/v1/history_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package v1

import (
"github.com/apache/servicecomb-kie/pkg/model"
"github.com/apache/servicecomb-kie/server/service/mongo/track"
"github.com/go-chassis/go-chassis/pkg/runtime"
"net/http"
"strconv"
Expand Down Expand Up @@ -75,6 +76,49 @@ func (r *HistoryResource) GetRevisions(context *restful.Context) {
}
}

//GetPollingData get the record of the get or list history
func (r *HistoryResource) GetPollingData(context *restful.Context) {
query := &model.PollingDetail{}
sessionID := context.ReadQueryParameter(common.QueryParamSessionID)
if sessionID != "" {
query.SessionID = sessionID
}
ip := context.ReadQueryParameter(common.QueryParamIP)
if ip != "" {
query.IP = ip
}
urlPath := context.ReadQueryParameter(common.QueryParamURLPath)
if urlPath != "" {
query.URLPath = urlPath
}
userAgent := context.ReadQueryParameter(common.QueryParamUserAgent)
if userAgent != "" {
query.UserAgent = userAgent
}
domain := ReadDomain(context)
if domain == nil {
WriteErrResponse(context, http.StatusInternalServerError, common.MsgDomainMustNotBeEmpty, common.ContentTypeText)
return
}
query.Domain = domain.(string)
records, err := track.Get(context.Ctx, query)
if err != nil {
if err == service.ErrRecordNotExists {
WriteErrResponse(context, http.StatusNotFound, err.Error(), common.ContentTypeText)
return
}
WriteErrResponse(context, http.StatusInternalServerError, err.Error(), common.ContentTypeText)
return
}
resp := &model.PollingDataResponse{}
resp.Data = records
resp.Total = len(records)
err = writeResponse(context, resp)
if err != nil {
openlogging.Error(err.Error())
}
}

//HealthCheck provider version info and time info
func (r *HistoryResource) HealthCheck(context *restful.Context) {
domain := ReadDomain(context)
Expand Down Expand Up @@ -128,5 +172,23 @@ func (r *HistoryResource) URLPatterns() []restful.Route {
Consumes: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
Produces: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
},
{
Method: http.MethodGet,
Path: "/v1/{project}/kie/track",
ResourceFunc: r.GetPollingData,
FuncDesc: "get polling tracks of clients of kie server",
Parameters: []*restful.Parameters{
DocPathProject, DocQuerySessionIDParameters, DocQueryIPParameters, DocQueryURLPathParameters, DocQueryUserAgentParameters,
},
Returns: []*restful.Returns{
{
Code: http.StatusOK,
Message: "true",
Model: []model.PollingDataResponse{},
},
},
Consumes: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
Produces: []string{goRestful.MIME_JSON, common.ContentTypeYaml},
},
}
}
39 changes: 39 additions & 0 deletions server/resource/v1/history_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,45 @@ func TestHistoryResource_GetRevisions(t *testing.T) {

}

func TestHistoryResource_GetPollingData(t *testing.T) {
t.Run("list kv by service label, to create a polling data", func(t *testing.T) {
r, _ := http.NewRequest("GET", "/v1/test/kie/kv", nil)
noopH := &handler2.NoopAuthHandler{}
noopH2 := &handler2.TrackHandler{}
chain, _ := handler.CreateChain(common.Provider, "testchain3", noopH.Name(), noopH2.Name())
r.Header.Set("Content-Type", "application/json")
r.Header.Set("X-Session-Id", "test")
kvr := &v1.KVResource{}
c, err := restfultest.New(kvr, chain)
assert.NoError(t, err)
resp := httptest.NewRecorder()
c.ServeHTTP(resp, r)
body, err := ioutil.ReadAll(resp.Body)
assert.NoError(t, err)
result := &model.KVResponse{}
err = json.Unmarshal(body, result)
assert.NoError(t, err)
})
t.Run("get polling data", func(t *testing.T) {
r, _ := http.NewRequest("GET", "/v1/test/kie/track?sessionId=test", nil)
noopH := &handler2.NoopAuthHandler{}
chain, _ := handler.CreateChain(common.Provider, "testchain3", noopH.Name())
r.Header.Set("Content-Type", "application/json")
revision := &v1.HistoryResource{}
c, err := restfultest.New(revision, chain)
assert.NoError(t, err)
resp := httptest.NewRecorder()
c.ServeHTTP(resp, r)
body, err := ioutil.ReadAll(resp.Body)
assert.NoError(t, err)
result := &model.PollingDataResponse{}
err = json.Unmarshal(body, result)
assert.NoError(t, err)
assert.NotEmpty(t, result.Data)
})

}

func Test_HeathCheck(t *testing.T) {
path := fmt.Sprintf("/v1/health")
r, _ := http.NewRequest("GET", path, nil)
Expand Down
3 changes: 0 additions & 3 deletions server/resource/v1/kv_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ func TestKVResource_Put(t *testing.T) {
noopH := &handler2.NoopAuthHandler{}
chain, _ := handler.CreateChain(common.Provider, "testchain1", noopH.Name())
r.Header.Set("Content-Type", "application/json")
r.Header.Set("sessionID", "test")
kvr := &v1.KVResource{}
c, _ := restfultest.New(kvr, chain)
resp := httptest.NewRecorder()
Expand All @@ -101,7 +100,6 @@ func TestKVResource_Put(t *testing.T) {
noopH := &handler2.NoopAuthHandler{}
chain, _ := handler.CreateChain(common.Provider, "testchain1", noopH.Name())
r.Header.Set("Content-Type", "application/json")
r.Header.Set("sessionID", "test")
kvr := &v1.KVResource{}
c, _ := restfultest.New(kvr, chain)
resp := httptest.NewRecorder()
Expand All @@ -127,7 +125,6 @@ func TestKVResource_Put(t *testing.T) {
noopH := &handler2.NoopAuthHandler{}
chain, _ := handler.CreateChain(common.Provider, "testchain1", noopH.Name())
r.Header.Set("Content-Type", "application/json")
r.Header.Set("sessionID", "test")
kvr := &v1.KVResource{}
c, _ := restfultest.New(kvr, chain)
resp := httptest.NewRecorder()
Expand Down
Loading

0 comments on commit c898a7e

Please sign in to comment.