greatape/components/core/api_client.go

115 wiersze
2.6 KiB
Go

package core
import (
"errors"
"fmt"
"reflect"
"time"
. "github.com/reiver/greatape/components/contracts"
. "github.com/xeronith/diamante/client"
. "github.com/xeronith/diamante/contracts/client"
. "github.com/xeronith/diamante/contracts/logging"
. "github.com/xeronith/diamante/contracts/operation"
. "github.com/xeronith/diamante/contracts/system"
. "github.com/xeronith/diamante/protobuf"
. "github.com/xeronith/diamante/serialization"
. "github.com/xeronith/diamante/server"
)
// noinspection GoSnakeCaseUsage
var API_RESULT = make(map[uint64]Pointer)
//--------------------------------------------------------------------------------------
type api struct {
client IClient
output chan *output
logger ILogger
debugMode bool
}
func NewApi(endpoint string, logger ILogger) IApi {
initialized := make(chan bool, 1)
httpClient := NewHttpClient()
httpClient.SetName("API-CLIENT")
httpClient.SetVersion(1)
httpClient.SetApiVersion(1)
httpClient.OnConnectionEstablished(func(client IClient) {
initialized <- true
})
_ = httpClient.Connect(endpoint, "AUTH-TOKEN")
<-initialized
api := &api{
client: httpClient,
output: make(chan *output, 1),
logger: logger,
}
api.client.SetOperationResultListener(api.handler)
return api
}
func (api *api) SetToken(token string) {
api.client.SetToken(token)
}
func (api *api) SetDebugMode(enabled bool) {
api.debugMode = enabled
}
func (api *api) call(operation uint64, payload Pointer) (Pointer, error) {
requestId := uint64(time.Now().UnixNano())
if api.debugMode {
api.logger.Debug(fmt.Sprintf("REQ { ID: %d, OP: %d }", requestId, operation))
}
if err := api.client.Send(requestId, operation, payload); err != nil {
return nil, err
}
result := <-api.output
if result.isError {
return nil, errors.New(result.payload.(*ServerError).Message)
}
return result.payload, nil
}
func (api *api) handler(bundle IOperationResult) {
isError := false
var result Pointer
_type, exists := API_RESULT[bundle.Type()]
if exists {
resultType := reflect.TypeOf(_type)
result = reflect.New(resultType).Interface()
} else {
switch bundle.Type() {
case ERROR:
result = new(ServerError)
isError = true
default:
api.logger.Fatal("unregistered_result_type")
}
}
if err := NewProtobufSerializer().Deserialize(bundle.Payload(), result); err != nil {
api.logger.Fatal(err)
}
api.output <- &output{payload: result, isError: isError}
}
//--------------------------------------------------------------------------------------
type output struct {
payload Pointer
isError bool
}
//--------------------------------------------------------------------------------------