any-sync/util/cmd/debug/api/service.go
2022-12-03 13:09:15 +01:00

340 lines
8.6 KiB
Go

package api
import (
"context"
"errors"
"fmt"
clientproto "github.com/anytypeio/go-anytype-infrastructure-experiments/client/api/apiproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
nodeproto "github.com/anytypeio/go-anytype-infrastructure-experiments/node/api/apiproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cmd/debug/api/client"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cmd/debug/api/node"
"github.com/anytypeio/go-anytype-infrastructure-experiments/util/cmd/debug/peers"
"strconv"
)
const CName = "debug.api"
var log = logger.NewNamed(CName)
var (
ErrNoSuchCommand = errors.New("no such command")
ErrIncorrectPeerType = errors.New("incorrect peer type")
ErrIncorrectParamsCount = errors.New("incorrect params count")
)
type Command struct {
Cmd func(server peers.Peer, params []string) (string, error)
}
type Script struct {
Cmd func(params []string) (string, error)
}
type Service interface {
app.Component
Call(server peers.Peer, cmdName string, params []string) (string, error)
Script(scriptName string, params []string) (res string, err error)
}
type service struct {
clientCommands map[string]Command
nodeCommands map[string]Command
scripts map[string]Script
client client.Service
node node.Service
peers peers.Service
}
func New() Service {
return &service{
clientCommands: map[string]Command{},
nodeCommands: map[string]Command{},
scripts: map[string]Script{},
}
}
func (s *service) Init(a *app.App) (err error) {
s.client = a.MustComponent(client.CName).(client.Service)
s.node = a.MustComponent(node.CName).(node.Service)
s.peers = a.MustComponent(peers.CName).(peers.Service)
s.registerClientCommands()
s.registerNodeCommands()
s.registerScripts()
return nil
}
func (s *service) Name() (name string) {
return CName
}
func (s *service) Script(scriptName string, params []string) (res string, err error) {
script, ok := s.scripts[scriptName]
if !ok {
err = ErrNoSuchCommand
return
}
return script.Cmd(params)
}
func (s *service) Call(server peers.Peer, cmdName string, params []string) (res string, err error) {
var (
cmd Command
commands map[string]Command
)
switch server.PeerType {
case peers.PeerTypeClient:
commands = s.clientCommands
case peers.PeerTypeNode:
commands = s.nodeCommands
}
cmd, ok := commands[cmdName]
if !ok {
err = ErrNoSuchCommand
return
}
return cmd.Cmd(server, params)
}
func (s *service) registerClientCommands() {
s.clientCommands["create-space"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 0 {
err = ErrIncorrectParamsCount
return
}
resp, err := s.client.CreateSpace(context.Background(), server.Address, &clientproto.CreateSpaceRequest{})
if err != nil {
return
}
res = resp.Id
return
}}
s.clientCommands["derive-space"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 0 {
err = ErrIncorrectParamsCount
return
}
resp, err := s.client.DeriveSpace(context.Background(), server.Address, &clientproto.DeriveSpaceRequest{})
if err != nil {
return
}
res = resp.Id
return
}}
s.clientCommands["create-document"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 1 {
err = ErrIncorrectParamsCount
return
}
resp, err := s.client.CreateDocument(context.Background(), server.Address, &clientproto.CreateDocumentRequest{
SpaceId: params[0],
})
if err != nil {
return
}
res = resp.Id
return
}}
s.clientCommands["delete-document"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 2 {
err = ErrIncorrectParamsCount
return
}
_, err = s.client.DeleteDocument(context.Background(), server.Address, &clientproto.DeleteDocumentRequest{
SpaceId: params[0],
DocumentId: params[1],
})
if err != nil {
return
}
res = "deleted"
return
}}
s.clientCommands["add-text"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 3 {
err = ErrIncorrectParamsCount
return
}
resp, err := s.client.AddText(context.Background(), server.Address, &clientproto.AddTextRequest{
SpaceId: params[0],
DocumentId: params[1],
Text: params[2],
})
if err != nil {
return
}
res = resp.DocumentId + "->" + resp.HeadId
return
}}
s.clientCommands["load-space"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 1 {
err = ErrIncorrectParamsCount
return
}
_, err = s.client.LoadSpace(context.Background(), server.Address, &clientproto.LoadSpaceRequest{
SpaceId: params[0],
})
if err != nil {
return
}
res = params[0]
return
}}
s.clientCommands["all-trees"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 1 {
err = ErrIncorrectParamsCount
return
}
resp, err := s.client.AllTrees(context.Background(), server.Address, &clientproto.AllTreesRequest{
SpaceId: params[0],
})
if err != nil {
return
}
for treeIdx, tree := range resp.Trees {
treeStr := tree.Id + ":["
for headIdx, head := range tree.Heads {
treeStr += head
if headIdx != len(tree.Heads)-1 {
treeStr += ","
}
}
treeStr += "]"
res += treeStr
if treeIdx != len(resp.Trees)-1 {
res += "\n"
}
}
return
}}
s.clientCommands["dump-tree"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 2 {
err = ErrIncorrectParamsCount
return
}
resp, err := s.client.DumpTree(context.Background(), server.Address, &clientproto.DumpTreeRequest{
SpaceId: params[0],
DocumentId: params[1],
})
if err != nil {
return
}
res = resp.Dump
return
}}
s.clientCommands["all-spaces"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 0 {
err = ErrIncorrectParamsCount
return
}
resp, err := s.client.AllSpaces(context.Background(), server.Address, &clientproto.AllSpacesRequest{})
if err != nil {
return
}
for treeIdx, spaceId := range resp.SpaceIds {
res += spaceId
if treeIdx != len(resp.SpaceIds)-1 {
res += "\n"
}
}
return
}}
}
func (s *service) registerNodeCommands() {
s.nodeCommands["all-trees"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 1 {
err = ErrIncorrectParamsCount
return
}
resp, err := s.node.AllTrees(context.Background(), server.Address, &nodeproto.AllTreesRequest{
SpaceId: params[0],
})
if err != nil {
return
}
for treeIdx, tree := range resp.Trees {
treeStr := tree.Id + ":["
for headIdx, head := range tree.Heads {
treeStr += head
if headIdx != len(tree.Heads)-1 {
treeStr += ","
}
}
treeStr += "]"
res += treeStr
if treeIdx != len(resp.Trees)-1 {
res += "\n"
}
}
return
}}
s.nodeCommands["dump-tree"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 2 {
err = ErrIncorrectParamsCount
return
}
resp, err := s.node.DumpTree(context.Background(), server.Address, &nodeproto.DumpTreeRequest{
SpaceId: params[0],
DocumentId: params[1],
})
if err != nil {
return
}
res = resp.Dump
return
}}
s.nodeCommands["all-spaces"] = Command{Cmd: func(server peers.Peer, params []string) (res string, err error) {
if len(params) != 0 {
err = ErrIncorrectParamsCount
return
}
resp, err := s.node.AllSpaces(context.Background(), server.Address, &nodeproto.AllSpacesRequest{})
if err != nil {
return
}
for treeIdx, spaceId := range resp.SpaceIds {
res += spaceId
if treeIdx != len(resp.SpaceIds)-1 {
res += "\n"
}
}
return
}}
}
func (s *service) registerScripts() {
s.scripts["create-many"] = Script{Cmd: func(params []string) (res string, err error) {
if len(params) != 5 {
err = ErrIncorrectParamsCount
return
}
peer, err := s.peers.Get(params[0])
if err != nil {
return
}
last, err := strconv.Atoi(params[4])
if err != nil {
return
}
if last <= 0 {
err = fmt.Errorf("incorrect number of steps")
return
}
for i := 0; i < last; i++ {
_, err := s.client.AddText(context.Background(), peer.Address, &clientproto.AddTextRequest{
SpaceId: params[1],
DocumentId: params[2],
Text: params[3],
})
if err != nil {
return "", err
}
}
return
}}
}