作者 yangfu

1. 区块链数据查询

package dto
import "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
type BlockChain struct {
PrimaryId string `json:"primaryId"`
// 数据块hash
BlockHash string `json:"blockHash"`
}
type BlockChains []*BlockChain
func (b *BlockChain) LoadDto(upChain *domain.UpChain) {
b.PrimaryId = upChain.PrimaryId
b.BlockHash = upChain.Hash
}
func NewBlockChains(upChains []*domain.UpChain) BlockChains {
var rsp = make([]*BlockChain, 0)
for i := range upChains {
item := new(BlockChain)
item.LoadDto(upChains[i])
rsp = append(rsp, item)
}
return rsp
}
... ...
package query
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type GetBlockChainTokenQuery struct {
// 操作类型:
//1-交易哈希溯源
//2-溯源ID溯源
//3-验真
Type int `cname:"操作类型" json:"type" valid:"Required"`
// 参数
UpChainId int64 `cname:"上链Id" json:"upChainId,omitempty" valid:"Required"`
}
func (listBlockChain *GetBlockChainTokenQuery) Valid(validation *validation.Validation) {
//validation.SetError("CustomValid", "未实现的自定义认证")
}
func (listBlockChain *GetBlockChainTokenQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(listBlockChain)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(listBlockChain).Elem()
for _, validErr := range valid.Errors {
field, isExist := elem.FieldByName(validErr.Field)
if isExist {
return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
} else {
return fmt.Errorf(validErr.Message)
}
}
}
return nil
}
... ...
package query
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type ListBlockChainQuery struct {
OperateInfo *domain.OperateInfo `json:"-"`
// 查询偏离量
Offset int `cname:"查询偏离量" json:"offset,omitempty"`
// 查询限制
Limit int `cname:"查询限制" json:"limit,omitempty"`
// 数据来源 例如:app.model
Source string `cname:"数据来源 例如:app.model" json:"source" valid:"Required"`
// 来源数据唯一ID列表
PrimaryIdList []string `cname:"来源数据唯一ID列表" json:"primaryIdList"`
// 过滤重复的primaryId
EnableDistinctPrimaryId bool `cname:"过滤重复的primaryId" json:"enableDistinctPrimaryId"`
// 关闭查询限制
DisableLimit bool `cname:"关闭查询限制" json:"disableLimit,omitempty"`
}
func (listBlockChain *ListBlockChainQuery) Valid(validation *validation.Validation) {
//validation.SetError("CustomValid", "未实现的自定义认证")
}
func (listBlockChain *ListBlockChainQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(listBlockChain)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(listBlockChain).Elem()
for _, validErr := range valid.Errors {
field, isExist := elem.FieldByName(validErr.Field)
if isExist {
return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
} else {
return fmt.Errorf(validErr.Message)
}
}
}
return nil
}
... ...
... ... @@ -4,10 +4,14 @@ import (
"fmt"
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/command"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/dto"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/query"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/blockchain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/utils"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
"strconv"
"time"
)
... ... @@ -79,6 +83,97 @@ func (blockChainService *BlockChainService) UpChain(upChainCommand *command.UpCh
return upChain, nil
}
// 区块链列表
func (blockChainService *BlockChainService) ListBlockChain(listBlockChain *query.ListBlockChainQuery) (interface{}, error) {
if err := listBlockChain.ValidateQuery(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
upChainRepository, _, _ := factory.FastPgUpChain(transactionContext, 0)
queryOptions := utils.ObjectToMap(listBlockChain)
_, upChains, err := upChainRepository.Find(queryOptions)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
response := dto.NewBlockChains(upChains)
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return response, nil
}
func (blockChainService *BlockChainService) GetBlockChainToken(listBlockChain *query.GetBlockChainTokenQuery) (interface{}, error) {
if err := listBlockChain.ValidateQuery(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
upChainRepository, _, _ := factory.FastPgUpChain(transactionContext, 0)
upChain, err := upChainRepository.FindOne(map[string]interface{}{"upChainId": listBlockChain.UpChainId})
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
var request = blockchain.GetTokenRequest{
Type: listBlockChain.Type,
ShowValue: true,
}
bsn := newBSNBlockChain()
switch listBlockChain.Type {
case blockchain.QueryByHashId:
request.TsTxId = upChain.Hash
case blockchain.QueryByIssueId:
request.TsTxId = upChain.Hash
request.IssueId = upChain.IssueId
default:
return nil, application.ThrowError(application.ARG_ERROR, "unknown type "+strconv.Itoa(listBlockChain.Type))
}
getTokenResponse, err := bsn.GetToken(&request)
if err != nil {
log.Logger.Error(err.Error())
return nil, application.ThrowError(application.BUSINESS_ERROR, "不存在")
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return map[string]interface{}{
"token": getTokenResponse.Token,
"browseUrl": fmt.Sprintf("%v?token=%v", blockchain.BlockBrowserAddress, getTokenResponse.Token),
}, nil
}
func newBSNBlockChain() *blockchain.BSNBlockChain {
// 2.上链
bc := &blockchain.BSNBlockChain{
PublicPem: []byte(blockchain.PubPem),
Host: blockchain.Host,
PublicKey: blockchain.PubKey,
PrivatePem: blockchain.PriK,
EnableDebugLog: true,
}
return bc
}
func NewBlockChainService(options map[string]interface{}) *BlockChainService {
newBlockChainService := &BlockChainService{}
return newBlockChainService
... ...
... ... @@ -17,3 +17,5 @@ yiAKchKkbMi6nt7EUndRIflaipUPUBSPHWnt7dFElpVZsnyAzNJcvOUCAwEAAQ==
var PubKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANh+sdA9ZoOUG131OzGSpbcqUY/nmZLTyiAKchKkbMi6nt7EUndRIflaipUPUBSPHWnt7dFElpVZsnyAzNJcvOUCAwEAAQ=="
var Host = "http://101.34.29.149:9092/test"
var BlockBrowserAddress = "http://101.34.29.149/browser"
... ...
... ... @@ -55,3 +55,8 @@ func (o *UpToChainOptions) WithNeedHash() *UpToChainOptions {
o.NeedHash = true
return o
}
const (
QueryByHashId = iota + 1
QueryByIssueId
)
... ...
... ... @@ -132,7 +132,21 @@ func (repository *UpChainRepository) Find(queryOptions map[string]interface{}) (
var upChainModels []*models.UpChain
upChains := make([]*domain.UpChain, 0)
query := sqlbuilder.BuildQuery(tx.Model(&upChainModels), queryOptions)
query.SetOffsetAndLimit(20)
if v, ok := queryOptions["disableLimit"]; !(ok && v.(bool)) {
query.SetOffsetAndLimit(20)
}
if v, ok := queryOptions["source"]; ok && len(v.(string)) > 0 {
query.Where(`source = ?`, v)
}
if v, ok := queryOptions["primaryIdList"]; ok && len(v.([]string)) > 0 {
query.Where(`primary_id in (?)`, pg.In(v.([]string)))
}
if v, ok := queryOptions["enableDistinctPrimaryId"]; ok && v.(bool) {
query.DistinctOn(`primary_id`)
query.SetOrderDirect("primary_id", "DESC")
}
query.SetOrderDirect("up_chain_id", "DESC")
if count, err := query.SelectAndCount(); err != nil {
return 0, upChains, err
... ...
package controllers
import (
"github.com/linmadan/egglib-go/web/beego"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/query"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/blockChain/service"
)
type BlockChainController struct {
beego.BaseController
}
//func (controller *BlockChainController) CreateBlockChain() {
// blockChainService := service.NewBlockChainService(nil)
// createBlockChainCommand := &command.CreateBlockChainCommand{}
// controller.Unmarshal(createBlockChainCommand)
// data, err := blockChainService.CreateBlockChain(createBlockChainCommand)
// controller.Response(data, err)
//}
//
//func (controller *BlockChainController) UpdateBlockChain() {
// blockChainService := service.NewBlockChainService(nil)
// updateBlockChainCommand := &command.UpdateBlockChainCommand{}
// controller.Unmarshal(updateBlockChainCommand)
// blockChainId, _ := controller.GetString(":blockChainId")
// updateBlockChainCommand.BlockChainId = blockChainId
// data, err := blockChainService.UpdateBlockChain(updateBlockChainCommand)
// controller.Response(data, err)
//}
//
//func (controller *BlockChainController) GetBlockChain() {
// blockChainService := service.NewBlockChainService(nil)
// getBlockChainQuery := &query.GetBlockChainQuery{}
// blockChainId, _ := controller.GetString(":blockChainId")
// getBlockChainQuery.BlockChainId = blockChainId
// data, err := blockChainService.GetBlockChain(getBlockChainQuery)
// controller.Response(data, err)
//}
//
//func (controller *BlockChainController) RemoveBlockChain() {
// blockChainService := service.NewBlockChainService(nil)
// removeBlockChainCommand := &command.RemoveBlockChainCommand{}
// controller.Unmarshal(removeBlockChainCommand)
// blockChainId, _ := controller.GetString(":blockChainId")
// removeBlockChainCommand.BlockChainId = blockChainId
// data, err := blockChainService.RemoveBlockChain(removeBlockChainCommand)
// controller.Response(data, err)
//}
func (controller *BlockChainController) ListBlockChain() {
blockChainService := service.NewBlockChainService(nil)
listBlockChainQuery := &query.ListBlockChainQuery{}
Must(controller.Unmarshal(listBlockChainQuery))
listBlockChainQuery.OperateInfo = ParseOperateInfo(controller.BaseController)
data, err := blockChainService.ListBlockChain(listBlockChainQuery)
controller.Response(data, err)
}
func (controller *BlockChainController) GetBlockChainToken() {
blockChainService := service.NewBlockChainService(nil)
listBlockChainQuery := &query.GetBlockChainTokenQuery{}
Must(controller.Unmarshal(listBlockChainQuery))
//listBlockChainQuery.OperateInfo = ParseOperateInfo(controller.BaseController)
data, err := blockChainService.GetBlockChainToken(listBlockChainQuery)
controller.Response(data, err)
}
... ...
package routers
import (
"github.com/beego/beego/v2/server/web"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/port/beego/controllers"
)
func init() {
//web.Router("/block-chains/", &controllers.BlockChainController{}, "Post:CreateBlockChain")
//web.Router("/block-chains/:blockChainId", &controllers.BlockChainController{}, "Put:UpdateBlockChain")
//web.Router("/block-chains/:blockChainId", &controllers.BlockChainController{}, "Get:GetBlockChain")
//web.Router("/block-chains/:blockChainId", &controllers.BlockChainController{}, "Delete:RemoveBlockChain")
web.Router("/block-chains/", &controllers.BlockChainController{}, "Post:ListBlockChain")
web.Router("/block-chains/token", &controllers.BlockChainController{}, "Post:GetBlockChainToken")
}
... ...
package block_chain
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/beego/beego/v2/server/web"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
_ "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
_ "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/port/beego"
)
func TestBlockChain(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Beego Port BlockChain Correlations Test Case Suite")
}
var handler http.Handler
var server *httptest.Server
var _ = BeforeSuite(func() {
handler = web.BeeApp.Handlers
server = httptest.NewServer(handler)
})
var _ = AfterSuite(func() {
server.Close()
})
... ...
package block_chain
import (
"net/http"
"github.com/gavv/httpexpect"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
)
var _ = Describe("创建", func() {
Describe("提交数据创建", func() {
Context("提交正确的新上链数据数据", func() {
It("返回上链数据数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{
"upChainId": "int64",
}
httpExpect.POST("/block-chains/").
WithJSON(body).
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object().
ContainsKey("upChainId").ValueNotEqual("upChainId", BeZero())
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM up_chains WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package block_chain
import (
"github.com/go-pg/pg/v10"
"net/http"
"github.com/gavv/httpexpect"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
)
var _ = Describe("返回", func() {
var upChainId int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&upChainId),
"INSERT INTO up_chains (up_chain_id, source, primary_id, issue_id, data, hash, up_chain_status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING up_chain_id",
"testUpChainId", "testSource", "testPrimaryId", "testIssueId", "testData", "testHash", "testUpChainStatus", "testCreatedAt")
Expect(err).NotTo(HaveOccurred())
})
Describe("根据upChainId参数返回上链数据", func() {
Context("传入有效的upChainId", func() {
It("返回上链数据数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
httpExpect.GET("/block-chains/{blockChainId}").
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object()
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM up_chains WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package block_chain
import (
"github.com/go-pg/pg/v10"
"net/http"
"github.com/gavv/httpexpect"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
)
var _ = Describe("返回列表", func() {
var upChainId int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&upChainId),
"INSERT INTO up_chains (up_chain_id, source, primary_id, issue_id, data, hash, up_chain_status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING up_chain_id",
"testUpChainId", "testSource", "testPrimaryId", "testIssueId", "testData", "testHash", "testUpChainStatus", "testCreatedAt")
Expect(err).NotTo(HaveOccurred())
})
Describe("根据参数返回上链数据列表", func() {
Context("传入有效的参数", func() {
It("返回上链数据数据列表", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
httpExpect.GET("/block-chains/").
WithQuery("offset", "int").
WithQuery("limit", "int").
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object().
ContainsKey("count").ValueEqual("count", 1).
ContainsKey("upChains").Value("upChains").Array()
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM up_chains WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package block_chain
import (
"github.com/go-pg/pg/v10"
"net/http"
"github.com/gavv/httpexpect"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
)
var _ = Describe("移除", func() {
var upChainId int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&upChainId),
"INSERT INTO up_chains (up_chain_id, source, primary_id, issue_id, data, hash, up_chain_status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING up_chain_id",
"testUpChainId", "testSource", "testPrimaryId", "testIssueId", "testData", "testHash", "testUpChainStatus", "testCreatedAt")
Expect(err).NotTo(HaveOccurred())
})
Describe("根据参数移除", func() {
Context("传入有效的upChainId", func() {
It("返回被移除上链数据的数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
httpExpect.DELETE("/block-chains/{blockChainId}").
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object()
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM up_chains WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...
package block_chain
import (
"github.com/go-pg/pg/v10"
"net/http"
"github.com/gavv/httpexpect"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
)
var _ = Describe("更新", func() {
var upChainId int64
BeforeEach(func() {
_, err := pG.DB.QueryOne(
pg.Scan(&upChainId),
"INSERT INTO up_chains (up_chain_id, source, primary_id, issue_id, data, hash, up_chain_status, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING up_chain_id",
"testUpChainId", "testSource", "testPrimaryId", "testIssueId", "testData", "testHash", "testUpChainStatus", "testCreatedAt")
Expect(err).NotTo(HaveOccurred())
})
Describe("提交数据更新", func() {
Context("提交正确的上链数据数据", func() {
It("返回更新后的上链数据数据", func() {
httpExpect := httpexpect.New(GinkgoT(), server.URL)
body := map[string]interface{}{
"upChainId": "int64",
}
httpExpect.PUT("/block-chains/{blockChainId}").
WithJSON(body).
Expect().
Status(http.StatusOK).
JSON().
Object().
ContainsKey("code").ValueEqual("code", 0).
ContainsKey("msg").ValueEqual("msg", "ok").
ContainsKey("data").Value("data").Object().
ContainsKey("upChainId").ValueEqual("upChainId", upChainId)
})
})
})
AfterEach(func() {
_, err := pG.DB.Exec("DELETE FROM up_chains WHERE true")
Expect(err).NotTo(HaveOccurred())
})
})
... ...