Commit 2c23a183 authored by lihailei's avatar lihailei

Build the basic beego framework to implement the getPeers interface.

parent 90aaa500
package common
import (
"encoding/json"
"fmt"
"os"
jsonrpc "gitlab.33.cn/chain33/chain33/rpc"
)
var (
chain33_jrpcIP = "http://localhost:8801"
)
//func init() {
//
//}
func GetJrpcIp() string {
return chain33_jrpcIP
}
// TODO: SetPostRunCb()
type RpcCtx struct {
Addr string
Method string
Params interface{}
Res interface{}
cb Callback
}
type Callback func(res interface{}) (interface{}, error)
func NewRpcCtx(laddr, methed string, params, res interface{}) *RpcCtx {
return &RpcCtx{
Addr: laddr,
Method: methed,
Params: params,
Res: res,
}
}
func (c *RpcCtx) SetResultCb(cb Callback) {
c.cb = cb
}
func (c *RpcCtx) Run() {
rpc, err := jsonrpc.NewJsonClient(c.Addr)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
err = rpc.Call(c.Method, c.Params, c.Res)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
// maybe format rpc result
var result interface{}
if c.cb != nil {
result, err = c.cb(c.Res)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
} else {
result = c.Res
}
data, err := json.MarshalIndent(result, "", " ")
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println(string(data))
}
func (c *RpcCtx) ResponData() ([]byte, error) {
rpc, err := jsonrpc.NewJsonClient(c.Addr)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return nil, err
}
err = rpc.Call(c.Method, c.Params, c.Res)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return nil, err
}
// maybe format rpc result
var result interface{}
if c.cb != nil {
result, err = c.cb(c.Res)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return nil, err
}
} else {
result = c.Res
}
data, err := json.MarshalIndent(result, "", " ")
if err != nil {
fmt.Fprintln(os.Stderr, err)
return nil, err
}
return data, nil
//fmt.Println(string(data))
}
appname = chain33_sdk
httpport = 8080
runmode = dev
autorender = false
copyrequestbody = false
EnableDocs = true
package controllers
import (
"github.com/astaxie/beego"
)
// BlockController operations for Block
type BlockController struct {
beego.Controller
}
// URLMapping ...
func (c *BlockController) URLMapping() {
c.Mapping("Post", c.Post)
c.Mapping("GetOne", c.GetOne)
c.Mapping("GetAll", c.GetAll)
c.Mapping("Put", c.Put)
c.Mapping("Delete", c.Delete)
}
// Post ...
// @Title Create
// @Description create Block
// @Param body body models.Block true "body for Block content"
// @Success 201 {object} models.Block
// @Failure 403 body is empty
// @router / [post]
func (c *BlockController) Post() {
}
// GetOne ...
// @Title GetOne
// @Description get Block by id
// @Param id path string true "The key for staticblock"
// @Success 200 {object} models.Block
// @Failure 403 :id is empty
// @router /:id [get]
func (c *BlockController) GetOne() {
}
// GetAll ...
// @Title GetAll
// @Description get Block
// @Param query query string false "Filter. e.g. col1:v1,col2:v2 ..."
// @Param fields query string false "Fields returned. e.g. col1,col2 ..."
// @Param sortby query string false "Sorted-by fields. e.g. col1,col2 ..."
// @Param order query string false "Order corresponding to each sortby field, if single value, apply to all sortby fields. e.g. desc,asc ..."
// @Param limit query string false "Limit the size of result set. Must be an integer"
// @Param offset query string false "Start position of result set. Must be an integer"
// @Success 200 {object} models.Block
// @Failure 403
// @router / [get]
func (c *BlockController) GetAll() {
}
// Put ...
// @Title Put
// @Description update the Block
// @Param id path string true "The id you want to update"
// @Param body body models.Block true "body for Block content"
// @Success 200 {object} models.Block
// @Failure 403 :id is not int
// @router /:id [put]
func (c *BlockController) Put() {
}
// Delete ...
// @Title Delete
// @Description delete the Block
// @Param id path string true "The id you want to delete"
// @Success 200 {string} delete success!
// @Failure 403 id is empty
// @router /:id [delete]
func (c *BlockController) Delete() {
}
package controllers
import (
"encoding/json"
"gitlab.33.cn/lihailei/chain33_sdk/models"
"github.com/astaxie/beego"
)
// Operations about object
type ObjectController struct {
beego.Controller
}
// @Title Create
// @Description create object
// @Param body body models.Object true "The object content"
// @Success 200 {string} models.Object.Id
// @Failure 403 body is empty
// @router / [post]
func (o *ObjectController) Post() {
var ob models.Object
json.Unmarshal(o.Ctx.Input.RequestBody, &ob)
objectid := models.AddOne(ob)
o.Data["json"] = map[string]string{"ObjectId": objectid}
o.ServeJSON()
}
// @Title Get
// @Description find object by objectid
// @Param objectId path string true "the objectid you want to get"
// @Success 200 {object} models.Object
// @Failure 403 :objectId is empty
// @router /:objectId [get]
func (o *ObjectController) Get() {
objectId := o.Ctx.Input.Param(":objectId")
if objectId != "" {
ob, err := models.GetOne(objectId)
if err != nil {
o.Data["json"] = err.Error()
} else {
o.Data["json"] = ob
}
}
o.ServeJSON()
}
// @Title GetAll
// @Description get all objects
// @Success 200 {object} models.Object
// @Failure 403 :objectId is empty
// @router / [get]
func (o *ObjectController) GetAll() {
obs := models.GetAll()
o.Data["json"] = obs
o.ServeJSON()
}
// @Title Update
// @Description update the object
// @Param objectId path string true "The objectid you want to update"
// @Param body body models.Object true "The body"
// @Success 200 {object} models.Object
// @Failure 403 :objectId is empty
// @router /:objectId [put]
func (o *ObjectController) Put() {
objectId := o.Ctx.Input.Param(":objectId")
var ob models.Object
json.Unmarshal(o.Ctx.Input.RequestBody, &ob)
err := models.Update(objectId, ob.Score)
if err != nil {
o.Data["json"] = err.Error()
} else {
o.Data["json"] = "update success!"
}
o.ServeJSON()
}
// @Title Delete
// @Description delete the object
// @Param objectId path string true "The objectId you want to delete"
// @Success 200 {string} delete success!
// @Failure 403 objectId is empty
// @router /:objectId [delete]
func (o *ObjectController) Delete() {
objectId := o.Ctx.Input.Param(":objectId")
models.Delete(objectId)
o.Data["json"] = "delete success!"
o.ServeJSON()
}
package controllers
import (
"github.com/astaxie/beego"
jsonrpc "gitlab.33.cn/chain33/chain33/rpc"
"gitlab.33.cn/lihailei/chain33_sdk/common"
)
// PeerController operations for Peer
type PeerController struct {
beego.Controller
}
// URLMapping ...
func (c *PeerController) URLMapping() {
c.Mapping("getPeers", c.GetPeers)
}
// GetOne ...
// @Title GetPeers
// @Description get Peers
// @Param id path string true "The key for staticblock"
// @Success 200 {object} models.Peer
// @Failure 403 :id is empty
// @router /:id [get]
func (c *PeerController) GetPeers() {
rpcLaddr := common.GetJrpcIp()
var res jsonrpc.PeerList
ctx := common.NewRpcCtx(rpcLaddr, "Chain33.GetPeerInfo", nil, &res)
data, err := ctx.ResponData()
if err != nil {
c.Data["json"] = err.Error()
c.ServeJSON()
} else {
c.Ctx.ResponseWriter.Write(data)
}
}
package controllers
import (
"github.com/astaxie/beego"
)
// TxController operations for Tx
type TxController struct {
beego.Controller
}
// URLMapping ...
func (c *TxController) URLMapping() {
c.Mapping("Post", c.Post)
c.Mapping("GetOne", c.GetOne)
c.Mapping("GetAll", c.GetAll)
c.Mapping("Put", c.Put)
c.Mapping("Delete", c.Delete)
}
// Post ...
// @Title Create
// @Description create Tx
// @Param body body models.Tx true "body for Tx content"
// @Success 201 {object} models.Tx
// @Failure 403 body is empty
// @router / [post]
func (c *TxController) Post() {
}
// GetOne ...
// @Title GetOne
// @Description get Tx by id
// @Param id path string true "The key for staticblock"
// @Success 200 {object} models.Tx
// @Failure 403 :id is empty
// @router /:id [get]
func (c *TxController) GetOne() {
}
// GetAll ...
// @Title GetAll
// @Description get Tx
// @Param query query string false "Filter. e.g. col1:v1,col2:v2 ..."
// @Param fields query string false "Fields returned. e.g. col1,col2 ..."
// @Param sortby query string false "Sorted-by fields. e.g. col1,col2 ..."
// @Param order query string false "Order corresponding to each sortby field, if single value, apply to all sortby fields. e.g. desc,asc ..."
// @Param limit query string false "Limit the size of result set. Must be an integer"
// @Param offset query string false "Start position of result set. Must be an integer"
// @Success 200 {object} models.Tx
// @Failure 403
// @router / [get]
func (c *TxController) GetAll() {
}
// Put ...
// @Title Put
// @Description update the Tx
// @Param id path string true "The id you want to update"
// @Param body body models.Tx true "body for Tx content"
// @Success 200 {object} models.Tx
// @Failure 403 :id is not int
// @router /:id [put]
func (c *TxController) Put() {
}
// Delete ...
// @Title Delete
// @Description delete the Tx
// @Param id path string true "The id you want to delete"
// @Success 200 {string} delete success!
// @Failure 403 id is empty
// @router /:id [delete]
func (c *TxController) Delete() {
}
package controllers
import (
"encoding/json"
"gitlab.33.cn/lihailei/chain33_sdk/models"
"github.com/astaxie/beego"
)
// Operations about Users
type UserController struct {
beego.Controller
}
// @Title CreateUser
// @Description create users
// @Param body body models.User true "body for user content"
// @Success 200 {int} models.User.Id
// @Failure 403 body is empty
// @router / [post]
func (u *UserController) Post() {
var user models.User
json.Unmarshal(u.Ctx.Input.RequestBody, &user)
uid := models.AddUser(user)
u.Data["json"] = map[string]string{"uid": uid}
u.ServeJSON()
}
// @Title GetAll
// @Description get all Users
// @Success 200 {object} models.User
// @router / [get]
func (u *UserController) GetAll() {
users := models.GetAllUsers()
u.Data["json"] = users
u.ServeJSON()
}
// @Title Get
// @Description get user by uid
// @Param uid path string true "The key for staticblock"
// @Success 200 {object} models.User
// @Failure 403 :uid is empty
// @router /:uid [get]
func (u *UserController) Get() {
uid := u.GetString(":uid")
if uid != "" {
user, err := models.GetUser(uid)
if err != nil {
u.Data["json"] = err.Error()
} else {
u.Data["json"] = user
}
}
u.ServeJSON()
}
// @Title Update
// @Description update the user
// @Param uid path string true "The uid you want to update"
// @Param body body models.User true "body for user content"
// @Success 200 {object} models.User
// @Failure 403 :uid is not int
// @router /:uid [put]
func (u *UserController) Put() {
uid := u.GetString(":uid")
if uid != "" {
var user models.User
json.Unmarshal(u.Ctx.Input.RequestBody, &user)
uu, err := models.UpdateUser(uid, &user)
if err != nil {
u.Data["json"] = err.Error()
} else {
u.Data["json"] = uu
}
}
u.ServeJSON()
}
// @Title Delete
// @Description delete the user
// @Param uid path string true "The uid you want to delete"
// @Success 200 {string} delete success!
// @Failure 403 uid is empty
// @router /:uid [delete]
func (u *UserController) Delete() {
uid := u.GetString(":uid")
models.DeleteUser(uid)
u.Data["json"] = "delete success!"
u.ServeJSON()
}
// @Title Login
// @Description Logs user into the system
// @Param username query string true "The username for login"
// @Param password query string true "The password for login"
// @Success 200 {string} login success
// @Failure 403 user not exist
// @router /login [get]
func (u *UserController) Login() {
username := u.GetString("username")
password := u.GetString("password")
if models.Login(username, password) {
u.Data["json"] = "login success"
} else {
u.Data["json"] = "user not exist"
}
u.ServeJSON()
}
// @Title logout
// @Description Logs out current logged in user session
// @Success 200 {string} logout success
// @router /logout [get]
func (u *UserController) Logout() {
u.Data["json"] = "logout success"
u.ServeJSON()
}
package main
import (
_ "gitlab.33.cn/lihailei/chain33_sdk/routers"
"github.com/astaxie/beego"
)
func main() {
if beego.BConfig.RunMode == "dev" {
beego.BConfig.WebConfig.DirectoryIndex = true
beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
}
beego.Run()
}
package models
import (
"errors"
"strconv"
"time"
)
var (
Objects map[string]*Object
)
type Object struct {
ObjectId string
Score int64
PlayerName string
}
func init() {
Objects = make(map[string]*Object)
Objects["hjkhsbnmn123"] = &Object{"hjkhsbnmn123", 100, "astaxie"}
Objects["mjjkxsxsaa23"] = &Object{"mjjkxsxsaa23", 101, "someone"}
}
func AddOne(object Object) (ObjectId string) {
object.ObjectId = "astaxie" + strconv.FormatInt(time.Now().UnixNano(), 10)
Objects[object.ObjectId] = &object
return object.ObjectId
}
func GetOne(ObjectId string) (object *Object, err error) {
if v, ok := Objects[ObjectId]; ok {
return v, nil
}
return nil, errors.New("ObjectId Not Exist")
}
func GetAll() map[string]*Object {
return Objects
}
func Update(ObjectId string, Score int64) (err error) {
if v, ok := Objects[ObjectId]; ok {
v.Score = Score
return nil
}
return errors.New("ObjectId Not Exist")
}
func Delete(ObjectId string) {
delete(Objects, ObjectId)
}
package models
import (
"errors"
"strconv"
"time"
)
var (
UserList map[string]*User
)
func init() {
UserList = make(map[string]*User)
u := User{"user_11111", "astaxie", "11111", Profile{"male", 20, "Singapore", "astaxie@gmail.com"}}
UserList["user_11111"] = &u
}
type User struct {
Id string
Username string
Password string
Profile Profile
}
type Profile struct {
Gender string
Age int
Address string
Email string
}
func AddUser(u User) string {
u.Id = "user_" + strconv.FormatInt(time.Now().UnixNano(), 10)
UserList[u.Id] = &u
return u.Id
}
func GetUser(uid string) (u *User, err error) {
if u, ok := UserList[uid]; ok {
return u, nil
}
return nil, errors.New("User not exists")
}
func GetAllUsers() map[string]*User {
return UserList
}
func UpdateUser(uid string, uu *User) (a *User, err error) {
if u, ok := UserList[uid]; ok {
if uu.Username != "" {
u.Username = uu.Username
}
if uu.Password != "" {
u.Password = uu.Password
}
if uu.Profile.Age != 0 {
u.Profile.Age = uu.Profile.Age
}
if uu.Profile.Address != "" {
u.Profile.Address = uu.Profile.Address
}
if uu.Profile.Gender != "" {
u.Profile.Gender = uu.Profile.Gender
}
if uu.Profile.Email != "" {
u.Profile.Email = uu.Profile.Email
}
return u, nil
}
return nil, errors.New("User Not Exist")
}
func Login(username, password string) bool {
for _, u := range UserList {
if u.Username == username && u.Password == password {
return true
}
}
return false
}
func DeleteUser(uid string) {
delete(UserList, uid)
}
package routers
import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/context/param"
)
func init() {
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:BlockController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:BlockController"],
beego.ControllerComments{
Method: "Post",
Router: `/`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:BlockController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:BlockController"],
beego.ControllerComments{
Method: "GetAll",
Router: `/`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:BlockController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:BlockController"],
beego.ControllerComments{
Method: "GetOne",
Router: `/:id`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:BlockController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:BlockController"],
beego.ControllerComments{
Method: "Put",
Router: `/:id`,
AllowHTTPMethods: []string{"put"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:BlockController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:BlockController"],
beego.ControllerComments{
Method: "Delete",
Router: `/:id`,
AllowHTTPMethods: []string{"delete"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:ObjectController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:ObjectController"],
beego.ControllerComments{
Method: "Post",
Router: `/`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:ObjectController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:ObjectController"],
beego.ControllerComments{
Method: "GetAll",
Router: `/`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:ObjectController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:ObjectController"],
beego.ControllerComments{
Method: "Get",
Router: `/:objectId`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:ObjectController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:ObjectController"],
beego.ControllerComments{
Method: "Put",
Router: `/:objectId`,
AllowHTTPMethods: []string{"put"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:ObjectController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:ObjectController"],
beego.ControllerComments{
Method: "Delete",
Router: `/:objectId`,
AllowHTTPMethods: []string{"delete"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:PeerController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:PeerController"],
beego.ControllerComments{
Method: "GetPeers",
Router: `/:id`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:TxController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:TxController"],
beego.ControllerComments{
Method: "Post",
Router: `/`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:TxController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:TxController"],
beego.ControllerComments{
Method: "GetAll",
Router: `/`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:TxController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:TxController"],
beego.ControllerComments{
Method: "GetOne",
Router: `/:id`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:TxController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:TxController"],
beego.ControllerComments{
Method: "Put",
Router: `/:id`,
AllowHTTPMethods: []string{"put"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:TxController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:TxController"],
beego.ControllerComments{
Method: "Delete",
Router: `/:id`,
AllowHTTPMethods: []string{"delete"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"],
beego.ControllerComments{
Method: "Post",
Router: `/`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"],
beego.ControllerComments{
Method: "GetAll",
Router: `/`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"],
beego.ControllerComments{
Method: "Get",
Router: `/:uid`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"],
beego.ControllerComments{
Method: "Put",
Router: `/:uid`,
AllowHTTPMethods: []string{"put"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"],
beego.ControllerComments{
Method: "Delete",
Router: `/:uid`,
AllowHTTPMethods: []string{"delete"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"],
beego.ControllerComments{
Method: "Login",
Router: `/login`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"] = append(beego.GlobalControllerRouter["gitlab.33.cn/lihailei/chain33_sdk/controllers:UserController"],
beego.ControllerComments{
Method: "Logout",
Router: `/logout`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})
}
// @APIVersion 1.0.0
// @Title beego Test API
// @Description beego has a very cool tools to autogenerate documents for your API
// @Contact astaxie@gmail.com
// @TermsOfServiceUrl http://beego.me/
// @License Apache 2.0
// @LicenseUrl http://www.apache.org/licenses/LICENSE-2.0.html
package routers
import (
"gitlab.33.cn/lihailei/chain33_sdk/controllers"
"github.com/astaxie/beego"
"github.com/astaxie/beego/context"
)
func init() {
ns := beego.NewNamespace("/v1",
beego.NSNamespace("/object",
beego.NSInclude(
&controllers.ObjectController{},
),
),
beego.NSNamespace("/user",
beego.NSInclude(
&controllers.UserController{},
),
),
beego.NSNamespace("/peer",
beego.NSInclude(
&controllers.PeerController{},
),
),
beego.NSNamespace("/block",
beego.NSInclude(
&controllers.BlockController{},
),
),
beego.NSNamespace("/tx",
beego.NSInclude(
&controllers.TxController{},
),
),
)
ns.Filter("before", func(ctx *context.Context) {
//_, ok := ctx.Input.Session("uid").(int)
//if !ok && ctx.Request.RequestURI != "/login" {
// ctx.Redirect(302, "/login")
// }
ctx.Request.Header.Set("privateKey", "CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944")
})
beego.AddNamespace(ns)
}
package test
import (
_ "gitlab.33.cn/lihailei/chain33_sdk/routers"
"net/http"
"net/http/httptest"
"path/filepath"
"runtime"
"testing"
"github.com/astaxie/beego"
. "github.com/smartystreets/goconvey/convey"
)
func init() {
_, file, _, _ := runtime.Caller(1)
apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator))))
beego.TestBeegoInit(apppath)
}
// TestGet is a sample to run an endpoint test
func TestGet(t *testing.T) {
r, _ := http.NewRequest("GET", "/v1/object", nil)
w := httptest.NewRecorder()
beego.BeeApp.Handlers.ServeHTTP(w, r)
beego.Trace("testing", "TestGet", "Code[%d]\n%s", w.Code, w.Body.String())
Convey("Subject: Test Station Endpoint\n", t, func() {
Convey("Status Code Should Be 200", func() {
So(w.Code, ShouldEqual, 200)
})
Convey("The Result Should Not Be Empty", func() {
So(w.Body.Len(), ShouldBeGreaterThan, 0)
})
})
}
Compatible with TOML version
[v0.4.0](https://github.com/toml-lang/toml/blob/v0.4.0/versions/en/toml-v0.4.0.md)
The MIT License (MIT)
Copyright (c) 2013 TOML authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
install:
go install ./...
test: install
go test -v
toml-test toml-test-decoder
toml-test -encoder toml-test-encoder
fmt:
gofmt -w *.go */*.go
colcheck *.go */*.go
tags:
find ./ -name '*.go' -print0 | xargs -0 gotags > TAGS
push:
git push origin master
git push github master
## TOML parser and encoder for Go with reflection
TOML stands for Tom's Obvious, Minimal Language. This Go package provides a
reflection interface similar to Go's standard library `json` and `xml`
packages. This package also supports the `encoding.TextUnmarshaler` and
`encoding.TextMarshaler` interfaces so that you can define custom data
representations. (There is an example of this below.)
Spec: https://github.com/toml-lang/toml
Compatible with TOML version
[v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md)
Documentation: https://godoc.org/github.com/BurntSushi/toml
Installation:
```bash
go get github.com/BurntSushi/toml
```
Try the toml validator:
```bash
go get github.com/BurntSushi/toml/cmd/tomlv
tomlv some-toml-file.toml
```
[![Build Status](https://travis-ci.org/BurntSushi/toml.svg?branch=master)](https://travis-ci.org/BurntSushi/toml) [![GoDoc](https://godoc.org/github.com/BurntSushi/toml?status.svg)](https://godoc.org/github.com/BurntSushi/toml)
### Testing
This package passes all tests in
[toml-test](https://github.com/BurntSushi/toml-test) for both the decoder
and the encoder.
### Examples
This package works similarly to how the Go standard library handles `XML`
and `JSON`. Namely, data is loaded into Go values via reflection.
For the simplest example, consider some TOML file as just a list of keys
and values:
```toml
Age = 25
Cats = [ "Cauchy", "Plato" ]
Pi = 3.14
Perfection = [ 6, 28, 496, 8128 ]
DOB = 1987-07-05T05:45:00Z
```
Which could be defined in Go as:
```go
type Config struct {
Age int
Cats []string
Pi float64
Perfection []int
DOB time.Time // requires `import time`
}
```
And then decoded with:
```go
var conf Config
if _, err := toml.Decode(tomlData, &conf); err != nil {
// handle error
}
```
You can also use struct tags if your struct field name doesn't map to a TOML
key value directly:
```toml
some_key_NAME = "wat"
```
```go
type TOML struct {
ObscureKey string `toml:"some_key_NAME"`
}
```
### Using the `encoding.TextUnmarshaler` interface
Here's an example that automatically parses duration strings into
`time.Duration` values:
```toml
[[song]]
name = "Thunder Road"
duration = "4m49s"
[[song]]
name = "Stairway to Heaven"
duration = "8m03s"
```
Which can be decoded with:
```go
type song struct {
Name string
Duration duration
}
type songs struct {
Song []song
}
var favorites songs
if _, err := toml.Decode(blob, &favorites); err != nil {
log.Fatal(err)
}
for _, s := range favorites.Song {
fmt.Printf("%s (%s)\n", s.Name, s.Duration)
}
```
And you'll also need a `duration` type that satisfies the
`encoding.TextUnmarshaler` interface:
```go
type duration struct {
time.Duration
}
func (d *duration) UnmarshalText(text []byte) error {
var err error
d.Duration, err = time.ParseDuration(string(text))
return err
}
```
### More complex usage
Here's an example of how to load the example from the official spec page:
```toml
# This is a TOML document. Boom.
title = "TOML Example"
[owner]
name = "Tom Preston-Werner"
organization = "GitHub"
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
dob = 1979-05-27T07:32:00Z # First class dates? Why not?
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true
[servers]
# You can indent as you please. Tabs or spaces. TOML don't care.
[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"
[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"
[clients]
data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
# Line breaks are OK when inside arrays
hosts = [
"alpha",
"omega"
]
```
And the corresponding Go types are:
```go
type tomlConfig struct {
Title string
Owner ownerInfo
DB database `toml:"database"`
Servers map[string]server
Clients clients
}
type ownerInfo struct {
Name string
Org string `toml:"organization"`
Bio string
DOB time.Time
}
type database struct {
Server string
Ports []int
ConnMax int `toml:"connection_max"`
Enabled bool
}
type server struct {
IP string
DC string
}
type clients struct {
Data [][]interface{}
Hosts []string
}
```
Note that a case insensitive match will be tried if an exact match can't be
found.
A working example of the above can be found in `_examples/example.{go,toml}`.
This diff is collapsed.
package toml
import "strings"
// MetaData allows access to meta information about TOML data that may not
// be inferrable via reflection. In particular, whether a key has been defined
// and the TOML type of a key.
type MetaData struct {
mapping map[string]interface{}
types map[string]tomlType
keys []Key
decoded map[string]bool
context Key // Used only during decoding.
}
// IsDefined returns true if the key given exists in the TOML data. The key
// should be specified hierarchially. e.g.,
//
// // access the TOML key 'a.b.c'
// IsDefined("a", "b", "c")
//
// IsDefined will return false if an empty key given. Keys are case sensitive.
func (md *MetaData) IsDefined(key ...string) bool {
if len(key) == 0 {
return false
}
var hash map[string]interface{}
var ok bool
var hashOrVal interface{} = md.mapping
for _, k := range key {
if hash, ok = hashOrVal.(map[string]interface{}); !ok {
return false
}
if hashOrVal, ok = hash[k]; !ok {
return false
}
}
return true
}
// Type returns a string representation of the type of the key specified.
//
// Type will return the empty string if given an empty key or a key that
// does not exist. Keys are case sensitive.
func (md *MetaData) Type(key ...string) string {
fullkey := strings.Join(key, ".")
if typ, ok := md.types[fullkey]; ok {
return typ.typeString()
}
return ""
}
// Key is the type of any TOML key, including key groups. Use (MetaData).Keys
// to get values of this type.
type Key []string
func (k Key) String() string {
return strings.Join(k, ".")
}
func (k Key) maybeQuotedAll() string {
var ss []string
for i := range k {
ss = append(ss, k.maybeQuoted(i))
}
return strings.Join(ss, ".")
}
func (k Key) maybeQuoted(i int) string {
quote := false
for _, c := range k[i] {
if !isBareKeyChar(c) {
quote = true
break
}
}
if quote {
return "\"" + strings.Replace(k[i], "\"", "\\\"", -1) + "\""
}
return k[i]
}
func (k Key) add(piece string) Key {
newKey := make(Key, len(k)+1)
copy(newKey, k)
newKey[len(k)] = piece
return newKey
}
// Keys returns a slice of every key in the TOML data, including key groups.
// Each key is itself a slice, where the first element is the top of the
// hierarchy and the last is the most specific.
//
// The list will have the same order as the keys appeared in the TOML data.
//
// All keys returned are non-empty.
func (md *MetaData) Keys() []Key {
return md.keys
}
// Undecoded returns all keys that have not been decoded in the order in which
// they appear in the original TOML document.
//
// This includes keys that haven't been decoded because of a Primitive value.
// Once the Primitive value is decoded, the keys will be considered decoded.
//
// Also note that decoding into an empty interface will result in no decoding,
// and so no keys will be considered decoded.
//
// In this sense, the Undecoded keys correspond to keys in the TOML document
// that do not have a concrete type in your representation.
func (md *MetaData) Undecoded() []Key {
undecoded := make([]Key, 0, len(md.keys))
for _, key := range md.keys {
if !md.decoded[key.String()] {
undecoded = append(undecoded, key)
}
}
return undecoded
}
/*
Package toml provides facilities for decoding and encoding TOML configuration
files via reflection. There is also support for delaying decoding with
the Primitive type, and querying the set of keys in a TOML document with the
MetaData type.
The specification implemented: https://github.com/toml-lang/toml
The sub-command github.com/BurntSushi/toml/cmd/tomlv can be used to verify
whether a file is a valid TOML document. It can also be used to print the
type of each key in a TOML document.
Testing
There are two important types of tests used for this package. The first is
contained inside '*_test.go' files and uses the standard Go unit testing
framework. These tests are primarily devoted to holistically testing the
decoder and encoder.
The second type of testing is used to verify the implementation's adherence
to the TOML specification. These tests have been factored into their own
project: https://github.com/BurntSushi/toml-test
The reason the tests are in a separate project is so that they can be used by
any implementation of TOML. Namely, it is language agnostic.
*/
package toml
This diff is collapsed.
// +build go1.2
package toml
// In order to support Go 1.1, we define our own TextMarshaler and
// TextUnmarshaler types. For Go 1.2+, we just alias them with the
// standard library interfaces.
import (
"encoding"
)
// TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here
// so that Go 1.1 can be supported.
type TextMarshaler encoding.TextMarshaler
// TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined
// here so that Go 1.1 can be supported.
type TextUnmarshaler encoding.TextUnmarshaler
// +build !go1.2
package toml
// These interfaces were introduced in Go 1.2, so we add them manually when
// compiling for Go 1.1.
// TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here
// so that Go 1.1 can be supported.
type TextMarshaler interface {
MarshalText() (text []byte, err error)
}
// TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined
// here so that Go 1.1 can be supported.
type TextUnmarshaler interface {
UnmarshalText(text []byte) error
}
This diff is collapsed.
This diff is collapsed.
au BufWritePost *.go silent!make tags > /dev/null 2>&1
package toml
// tomlType represents any Go type that corresponds to a TOML type.
// While the first draft of the TOML spec has a simplistic type system that
// probably doesn't need this level of sophistication, we seem to be militating
// toward adding real composite types.
type tomlType interface {
typeString() string
}
// typeEqual accepts any two types and returns true if they are equal.
func typeEqual(t1, t2 tomlType) bool {
if t1 == nil || t2 == nil {
return false
}
return t1.typeString() == t2.typeString()
}
func typeIsHash(t tomlType) bool {
return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash)
}
type tomlBaseType string
func (btype tomlBaseType) typeString() string {
return string(btype)
}
func (btype tomlBaseType) String() string {
return btype.typeString()
}
var (
tomlInteger tomlBaseType = "Integer"
tomlFloat tomlBaseType = "Float"
tomlDatetime tomlBaseType = "Datetime"
tomlString tomlBaseType = "String"
tomlBool tomlBaseType = "Bool"
tomlArray tomlBaseType = "Array"
tomlHash tomlBaseType = "Hash"
tomlArrayHash tomlBaseType = "ArrayHash"
)
// typeOfPrimitive returns a tomlType of any primitive value in TOML.
// Primitive values are: Integer, Float, Datetime, String and Bool.
//
// Passing a lexer item other than the following will cause a BUG message
// to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime.
func (p *parser) typeOfPrimitive(lexItem item) tomlType {
switch lexItem.typ {
case itemInteger:
return tomlInteger
case itemFloat:
return tomlFloat
case itemDatetime:
return tomlDatetime
case itemString:
return tomlString
case itemMultilineString:
return tomlString
case itemRawString:
return tomlString
case itemRawMultilineString:
return tomlString
case itemBool:
return tomlBool
}
p.bug("Cannot infer primitive type of lex item '%s'.", lexItem)
panic("unreachable")
}
// typeOfArray returns a tomlType for an array given a list of types of its
// values.
//
// In the current spec, if an array is homogeneous, then its type is always
// "Array". If the array is not homogeneous, an error is generated.
func (p *parser) typeOfArray(types []tomlType) tomlType {
// Empty arrays are cool.
if len(types) == 0 {
return tomlArray
}
theType := types[0]
for _, t := range types[1:] {
if !typeEqual(theType, t) {
p.panicf("Array contains values of type '%s' and '%s', but "+
"arrays must be homogeneous.", theType, t)
}
}
return tomlArray
}
package toml
// Struct field handling is adapted from code in encoding/json:
//
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the Go distribution.
import (
"reflect"
"sort"
"sync"
)
// A field represents a single field found in a struct.
type field struct {
name string // the name of the field (`toml` tag included)
tag bool // whether field has a `toml` tag
index []int // represents the depth of an anonymous field
typ reflect.Type // the type of the field
}
// byName sorts field by name, breaking ties with depth,
// then breaking ties with "name came from toml tag", then
// breaking ties with index sequence.
type byName []field
func (x byName) Len() int { return len(x) }
func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x byName) Less(i, j int) bool {
if x[i].name != x[j].name {
return x[i].name < x[j].name
}
if len(x[i].index) != len(x[j].index) {
return len(x[i].index) < len(x[j].index)
}
if x[i].tag != x[j].tag {
return x[i].tag
}
return byIndex(x).Less(i, j)
}
// byIndex sorts field by index sequence.
type byIndex []field
func (x byIndex) Len() int { return len(x) }
func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x byIndex) Less(i, j int) bool {
for k, xik := range x[i].index {
if k >= len(x[j].index) {
return false
}
if xik != x[j].index[k] {
return xik < x[j].index[k]
}
}
return len(x[i].index) < len(x[j].index)
}
// typeFields returns a list of fields that TOML should recognize for the given
// type. The algorithm is breadth-first search over the set of structs to
// include - the top struct and then any reachable anonymous structs.
func typeFields(t reflect.Type) []field {
// Anonymous fields to explore at the current level and the next.
current := []field{}
next := []field{{typ: t}}
// Count of queued names for current level and the next.
count := map[reflect.Type]int{}
nextCount := map[reflect.Type]int{}
// Types already visited at an earlier level.
visited := map[reflect.Type]bool{}
// Fields found.
var fields []field
for len(next) > 0 {
current, next = next, current[:0]
count, nextCount = nextCount, map[reflect.Type]int{}
for _, f := range current {
if visited[f.typ] {
continue
}
visited[f.typ] = true
// Scan f.typ for fields to include.
for i := 0; i < f.typ.NumField(); i++ {
sf := f.typ.Field(i)
if sf.PkgPath != "" && !sf.Anonymous { // unexported
continue
}
opts := getOptions(sf.Tag)
if opts.skip {
continue
}
index := make([]int, len(f.index)+1)
copy(index, f.index)
index[len(f.index)] = i
ft := sf.Type
if ft.Name() == "" && ft.Kind() == reflect.Ptr {
// Follow pointer.
ft = ft.Elem()
}
// Record found field and index sequence.
if opts.name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
tagged := opts.name != ""
name := opts.name
if name == "" {
name = sf.Name
}
fields = append(fields, field{name, tagged, index, ft})
if count[f.typ] > 1 {
// If there were multiple instances, add a second,
// so that the annihilation code will see a duplicate.
// It only cares about the distinction between 1 or 2,
// so don't bother generating any more copies.
fields = append(fields, fields[len(fields)-1])
}
continue
}
// Record new anonymous struct to explore in next round.
nextCount[ft]++
if nextCount[ft] == 1 {
f := field{name: ft.Name(), index: index, typ: ft}
next = append(next, f)
}
}
}
}
sort.Sort(byName(fields))
// Delete all fields that are hidden by the Go rules for embedded fields,
// except that fields with TOML tags are promoted.
// The fields are sorted in primary order of name, secondary order
// of field index length. Loop over names; for each name, delete
// hidden fields by choosing the one dominant field that survives.
out := fields[:0]
for advance, i := 0, 0; i < len(fields); i += advance {
// One iteration per name.
// Find the sequence of fields with the name of this first field.
fi := fields[i]
name := fi.name
for advance = 1; i+advance < len(fields); advance++ {
fj := fields[i+advance]
if fj.name != name {
break
}
}
if advance == 1 { // Only one field with this name
out = append(out, fi)
continue
}
dominant, ok := dominantField(fields[i : i+advance])
if ok {
out = append(out, dominant)
}
}
fields = out
sort.Sort(byIndex(fields))
return fields
}
// dominantField looks through the fields, all of which are known to
// have the same name, to find the single field that dominates the
// others using Go's embedding rules, modified by the presence of
// TOML tags. If there are multiple top-level fields, the boolean
// will be false: This condition is an error in Go and we skip all
// the fields.
func dominantField(fields []field) (field, bool) {
// The fields are sorted in increasing index-length order. The winner
// must therefore be one with the shortest index length. Drop all
// longer entries, which is easy: just truncate the slice.
length := len(fields[0].index)
tagged := -1 // Index of first tagged field.
for i, f := range fields {
if len(f.index) > length {
fields = fields[:i]
break
}
if f.tag {
if tagged >= 0 {
// Multiple tagged fields at the same level: conflict.
// Return no field.
return field{}, false
}
tagged = i
}
}
if tagged >= 0 {
return fields[tagged], true
}
// All remaining fields have the same length. If there's more than one,
// we have a conflict (two fields named "X" at the same level) and we
// return no field.
if len(fields) > 1 {
return field{}, false
}
return fields[0], true
}
var fieldCache struct {
sync.RWMutex
m map[reflect.Type][]field
}
// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
func cachedTypeFields(t reflect.Type) []field {
fieldCache.RLock()
f := fieldCache.m[t]
fieldCache.RUnlock()
if f != nil {
return f
}
// Compute fields without lock.
// Might duplicate effort but won't hold other computations back.
f = typeFields(t)
if f == nil {
f = []field{}
}
fieldCache.Lock()
if fieldCache.m == nil {
fieldCache.m = map[reflect.Type][]field{}
}
fieldCache.m[t] = f
fieldCache.Unlock()
return f
}
beego @ f1668881
Subproject commit f16688817aa428d10361394015b40d096b680542
bee @ e90da8f7
Subproject commit e90da8f77bba1050b32ce1c7b9b2461d44252546
assertions @ 7678a545
Subproject commit 7678a5452ebea5b7090a6b163f844c133f523da2
goconvey @ ef6db91d
Subproject commit ef6db91d284a0e7badaa1f0c404c30aa7dee3aed
This diff is collapsed.
This diff is collapsed.
package rpc
import (
"io"
"net"
"net/http"
"net/rpc"
"net/rpc/jsonrpc"
"strings"
"github.com/rs/cors"
pb "gitlab.33.cn/chain33/chain33/types"
"google.golang.org/grpc"
)
// adapt HTTP connection to ReadWriteCloser
type HttpConn struct {
in io.Reader
out io.Writer
}
func (c *HttpConn) Read(p []byte) (n int, err error) { return c.in.Read(p) }
func (c *HttpConn) Write(d []byte) (n int, err error) { return c.out.Write(d) }
func (c *HttpConn) Close() error { return nil }
func (j *JsonRpcServer) Listen() {
listener, err := net.Listen("tcp", rpcCfg.GetJrpcBindAddr())
if err != nil {
log.Crit("listen:", "err", err)
panic(err)
}
server := rpc.NewServer()
server.Register(&j.jrpc)
co := cors.New(cors.Options{})
// Insert the middleware
var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if checkWhitlist(strings.Split(r.RemoteAddr, ":")[0]) == false {
w.Write([]byte(`{"errcode":"-1","result":null,"msg":"reject"}`))
return
}
if r.URL.Path == "/" {
serverCodec := jsonrpc.NewServerCodec(&HttpConn{in: r.Body, out: w})
w.Header().Set("Content-type", "application/json")
w.WriteHeader(200)
err := server.ServeRequest(serverCodec)
if err != nil {
log.Debug("Error while serving JSON request: %v", err)
return
}
}
})
handler = co.Handler(handler)
http.Serve(listener, handler)
}
func (g *Grpcserver) Listen() {
listener, err := net.Listen("tcp", rpcCfg.GetGrpcBindAddr())
if err != nil {
log.Crit("failed to listen:", "err", err)
panic(err)
}
s := grpc.NewServer()
pb.RegisterGrpcserviceServer(s, &g.grpc)
s.Serve(listener)
}
This diff is collapsed.
package rpc
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type JsonClient struct {
url string
}
func NewJsonClient(url string) (*JsonClient, error) {
return &JsonClient{url}, nil
}
type clientRequest struct {
Method string `json:"method"`
Params [1]interface{} `json:"params"`
Id uint64 `json:"id"`
}
type clientResponse struct {
Id uint64 `json:"id"`
Result *json.RawMessage `json:"result"`
Error interface{} `json:"error"`
}
func (client *JsonClient) Call(method string, params, resp interface{}) error {
req := &clientRequest{}
req.Method = method
req.Params[0] = params
data, err := json.Marshal(req)
if err != nil {
return err
}
log.Debug("request JsonStr", string(data), "")
postresp, err := http.Post(client.url, "application/json", bytes.NewBuffer(data))
if err != nil {
return err
}
defer postresp.Body.Close()
b, err := ioutil.ReadAll(postresp.Body)
if err != nil {
return err
}
log.Debug("response", string(b), "")
cresp := &clientResponse{}
err = json.Unmarshal(b, &cresp)
if err != nil {
return err
}
if cresp.Error != nil || cresp.Result == nil {
x, ok := cresp.Error.(string)
if !ok {
return fmt.Errorf("invalid error %v", cresp.Error)
}
if x == "" {
x = "unspecified error"
}
return fmt.Errorf(x)
}
return json.Unmarshal(*cresp.Result, resp)
}
package rpc
import (
"encoding/json"
"fmt"
"github.com/golang/protobuf/proto"
"gitlab.33.cn/chain33/chain33/types"
)
func tokenPayloadType(funcname string) (proto.Message, error) {
var req proto.Message
switch funcname {
case "GetTokens":
req = &types.ReqTokens{}
case "GetTokenInfo":
req = &types.ReqString{}
case "GetAddrReceiverforTokens":
req = &types.ReqAddrTokens{}
case "GetAccountTokenAssets":
req = &types.ReqAccountTokenAssets{}
default:
return nil, types.ErrInputPara
}
return req, nil
}
func coinsPayloadType(funcname string) (proto.Message, error) {
var req proto.Message
switch funcname {
case "GetAddrReciver":
req = &types.ReqAddr{}
case "GetTxsByAddr":
req = &types.ReqAddr{}
default:
return nil, types.ErrInputPara
}
return req, nil
}
func managePayloadType(funcname string) (proto.Message, error) {
var req proto.Message
switch funcname {
case "GetConfigItem":
req = &types.ReqString{}
default:
return nil, types.ErrInputPara
}
return req, nil
}
func retrievePayloadType(funcname string) (proto.Message, error) {
var req proto.Message
switch funcname {
case "GetRetrieveInfo":
req = &types.ReqRetrieveInfo{}
default:
return nil, types.ErrInputPara
}
return req, nil
}
func ticketPayloadType(funcname string) (proto.Message, error) {
var req proto.Message
switch funcname {
case "TicketInfos":
req = &types.TicketInfos{}
case "TicketList":
req = &types.TicketList{}
case "MinerAddress":
req = &types.ReqString{}
case "MinerSourceList":
req = &types.ReqString{}
default:
return nil, types.ErrInputPara
}
return req, nil
}
func tradePayloadType(funcname string) (proto.Message, error) {
var req proto.Message
switch funcname {
case "GetOnesSellOrder":
req = &types.ReqAddrTokens{}
case "GetOnesBuyOrder":
req = &types.ReqAddrTokens{}
case "GetAllSellOrdersWithStatus":
req = &types.ReqAddrTokens{}
case "GetTokenSellOrderByStatus":
req = &types.ReqTokenSellOrder{}
default:
return nil, types.ErrInputPara
}
return req, nil
}
func payloadType(execer, funcname string) (proto.Message, error) {
switch execer {
case "token":
return tokenPayloadType(funcname)
case "coins":
return coinsPayloadType(funcname)
case "manage":
return managePayloadType(funcname)
case "retrieve":
return retrievePayloadType(funcname)
case "ticket":
return ticketPayloadType(funcname)
case "trade":
return tradePayloadType(funcname)
}
return nil, types.ErrInputPara
}
func protoPayload(execer, funcname string, payload *json.RawMessage) ([]byte, error) {
req, err := payloadType(execer, funcname)
if err != nil {
return nil, err
}
err = json.Unmarshal(*payload, &req)
if err != nil {
return nil, types.ErrInputPara
}
fmt.Println("req: ", req)
fmt.Println("req: ", types.Encode(req))
return types.Encode(req), nil
}
package rpc
import (
"gitlab.33.cn/chain33/chain33/queue"
"gitlab.33.cn/chain33/chain33/types"
_ "google.golang.org/grpc/encoding/gzip"
)
var (
whitlist = make(map[string]bool)
rpcCfg *types.Rpc
)
type server struct {
cli channelClient
}
type Chain33 server
type Grpc server
type Grpcserver struct {
grpc Grpc
addr string
}
type JsonRpcServer struct {
jrpc Chain33
addr string
}
func (s *JsonRpcServer) Close() {
s.jrpc.cli.Close()
}
func checkWhitlist(addr string) bool {
if _, ok := whitlist["0.0.0.0"]; ok {
return true
}
if _, ok := whitlist[addr]; ok {
return true
}
return false
}
func (j *Grpcserver) Close() {
j.grpc.cli.Close()
}
func NewGRpcServer(client queue.Client) *Grpcserver {
s := &Grpcserver{}
s.grpc.cli.Client = client
return s
}
func NewJsonRpcServer(client queue.Client) *JsonRpcServer {
j := &JsonRpcServer{}
j.jrpc.cli.Client = client
return j
}
func Init(cfg *types.Rpc) {
rpcCfg = cfg
if len(cfg.Whitlist) == 1 && cfg.Whitlist[0] == "*" {
whitlist["0.0.0.0"] = true
return
}
for _, addr := range cfg.Whitlist {
whitlist[addr] = true
}
}
package rpc
import (
"encoding/json"
l "github.com/inconshreveable/log15"
)
var log = l.New("module", "rpc")
type TransParm struct {
Execer string `json:"execer"`
Payload string `json:"payload"`
Signature *Signature `json:"signature"`
Fee int64 `json:"fee"`
}
type SignedTx struct {
Unsign string `json:"unsigntx"`
Sign string `json:"sign"`
Pubkey string `json:"pubkey"`
Ty int32 `json:"ty"`
}
type RawParm struct {
Data string `json:"data"`
}
type QueryParm struct {
Hash string `json:"hash"`
}
type BlockParam struct {
Start int64 `json:"start"`
End int64 `json:"end"`
Isdetail bool `json:"isdetail"`
}
type Header struct {
Version int64 `json:"version"`
ParentHash string `json:"parenthash"`
TxHash string `json:"txhash"`
StateHash string `json:"statehash"`
Height int64 `json:"height"`
BlockTime int64 `json:"blocktime"`
TxCount int64 `json:"txcount"`
Hash string `json:"hash"`
}
type Signature struct {
Ty int32 `json:"ty"`
Pubkey string `json:"pubkey"`
Signature string `json:"signature"`
}
type Transaction struct {
Execer string `json:"execer"`
Payload interface{} `json:"payload"`
RawPayload string `json:"rawpayload"`
Signature *Signature `json:"signature"`
Fee int64 `json:"fee"`
Expire int64 `json:"expire"`
Nonce int64 `json:"nonce"`
From string `json:"from,omitempty"`
To string `json:"to"`
Amount int64 `json:"amount,omitempty"`
}
type ReceiptLog struct {
Ty int32 `json:"ty"`
Log string `json:"log"`
}
type ReceiptData struct {
Ty int32 `json:"ty"`
Logs []*ReceiptLog `json:"logs"`
}
type ReceiptDataResult struct {
Ty int32 `json:"ty"`
TyName string `json:"tyname"`
Logs []*ReceiptLogResult `json:"logs"`
}
type ReceiptLogResult struct {
Ty int32 `json:"ty"`
TyName string `json:"tyname"`
Log interface{} `json:"log"`
RawLog string `json:"rawlog"`
}
type Block struct {
Version int64 `json:"version"`
ParentHash string `json:"parenthash"`
TxHash string `json:"txhash"`
StateHash string `json:"statehash"`
Height int64 `json:"height"`
BlockTime int64 `json:"blocktime"`
Txs []*Transaction `json:"txs"`
}
type BlockDetail struct {
Block *Block `json:"block"`
Receipts []*ReceiptDataResult `json:"recipts"`
}
type BlockDetails struct {
Items []*BlockDetail `json:"items"`
}
type TransactionDetail struct {
Tx *Transaction `json:"tx"`
Receipt *ReceiptDataResult `json:"receipt"`
Proofs []string `json:"proofs"`
Height int64 `json:"height"`
Index int64 `json:"index"`
Blocktime int64 `json:"blocktime"`
Amount int64 `json:"amount"`
Fromaddr string `json:"fromaddr"`
ActionName string `json:"actionname"`
}
type ReplyTxInfos struct {
TxInfos []*ReplyTxInfo `protobuf:"bytes,1,rep,name=txInfos" json:"txinfos"`
}
type ReplyTxInfo struct {
Hash string `json:"hash"`
Height int64 `json:"height"`
Index int64 `json:"index"`
}
type TransactionDetails struct {
//Txs []*Transaction `json:"txs"`
Txs []*TransactionDetail `protobuf:"bytes,1,rep,name=txs" json:"txs"`
}
type ReplyTxList struct {
Txs []*Transaction `json:"txs"`
}
type ReplyHash struct {
Hash string `json:"hash"`
}
type ReplyHashes struct {
Hashes []string `json:"hashes"`
}
type PeerList struct {
Peers []*Peer `json:"peers"`
}
type Peer struct {
Addr string `json:"addr"`
Port int32 `json:"port"`
Name string `json:"name"`
MempoolSize int32 `json:"mempoolsize"`
Self bool `json:"self"`
Header *Header `json:"header"`
}
// Wallet Module
type WalletAccounts struct {
Wallets []*WalletAccount `protobuf:"bytes,1,rep,name=wallets" json:"wallets"`
}
type WalletAccount struct {
Acc *Account `protobuf:"bytes,1,opt,name=acc" json:"acc"`
Label string `protobuf:"bytes,2,opt,name=label" json:"label"`
}
type Account struct {
Currency int32 `protobuf:"varint,1,opt,name=currency" json:"currency"`
Balance int64 `protobuf:"varint,2,opt,name=balance" json:"balance"`
Frozen int64 `protobuf:"varint,3,opt,name=frozen" json:"frozen"`
Addr string `protobuf:"bytes,4,opt,name=addr" json:"addr"`
}
type Reply struct {
IsOk bool `protobuf:"varint,1,opt,name=isOk" json:"isok"`
Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg"`
}
type Headers struct {
Items []*Header `protobuf:"bytes,1,rep,name=items" json:"items"`
}
type ReqAddr struct {
Addr string `json:"addr"`
}
type ReqHashes struct {
Hashes []string `json:"hashes"`
}
type ReqWalletTransactionList struct {
FromTx string `json:"fromtx"`
Count int32 `json:"count"`
Direction int32 `json:"direction"`
}
type WalletTxDetails struct {
TxDetails []*WalletTxDetail `protobuf:"bytes,1,rep,name=txDetails" json:"txdetails"`
}
type WalletTxDetail struct {
Tx *Transaction `protobuf:"bytes,1,opt,name=tx" json:"tx"`
Receipt *ReceiptDataResult `protobuf:"bytes,2,opt,name=receipt" json:"receipt"`
Height int64 `protobuf:"varint,3,opt,name=height" json:"height"`
Index int64 `protobuf:"varint,4,opt,name=index" json:"index"`
Blocktime int64 `json:"blocktime"`
Amount int64 `json:"amount"`
Fromaddr string `json:"fromaddr"`
Txhash string `json:"txhash"`
ActionName string `json:"actionname"`
}
type BlockOverview struct {
Head *Header `protobuf:"bytes,1,opt,name=head" json:"head"`
TxCount int64 `protobuf:"varint,2,opt,name=txCount" json:"txcount"`
TxHashes []string `protobuf:"bytes,3,rep,name=txHashes,proto3" json:"txhashes"`
}
type Query4Cli struct {
Execer string `protobuf:"bytes,1,opt,name=execer,proto3" json:"execer"`
FuncName string `protobuf:"bytes,2,opt,name=funcName" json:"funcName"`
Payload interface{} `protobuf:"bytes,3,opt,name=payload" json:"payload"`
}
type Query4Jrpc struct {
Execer string `protobuf:"bytes,1,opt,name=execer,proto3" json:"execer"`
FuncName string `protobuf:"bytes,2,opt,name=funcName" json:"funcName"`
Payload json.RawMessage `protobuf:"bytes,3,opt,name=payload" json:"payload"`
}
type WalletStatus struct {
IsWalletLock bool `json:"iswalletlock"`
IsAutoMining bool `json:"isautomining"`
IsHasSeed bool `json:"ishasseed"`
IsTicketLock bool `json:"isticketlock"`
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment