Files
sendico/api/server/internal/server/ledgerapiimp/service.go

111 lines
3.2 KiB
Go

package ledgerapiimp
import (
"context"
"fmt"
"os"
"strings"
"time"
ledgerclient "github.com/tech/sendico/ledger/client"
api "github.com/tech/sendico/pkg/api/http"
"github.com/tech/sendico/pkg/auth"
"github.com/tech/sendico/pkg/merrors"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/mservice"
ledgerv1 "github.com/tech/sendico/pkg/proto/ledger/v1"
eapi "github.com/tech/sendico/server/interface/api"
mutil "github.com/tech/sendico/server/internal/mutil/param"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.uber.org/zap"
)
type ledgerClient interface {
ListAccounts(ctx context.Context, req *ledgerv1.ListAccountsRequest) (*ledgerv1.ListAccountsResponse, error)
GetBalance(ctx context.Context, req *ledgerv1.GetBalanceRequest) (*ledgerv1.BalanceResponse, error)
Close() error
}
type LedgerAPI struct {
logger mlogger.Logger
client ledgerClient
enf auth.Enforcer
oph mutil.ParamHelper
aph mutil.ParamHelper
permissionRef primitive.ObjectID
balancePerm primitive.ObjectID
}
func (a *LedgerAPI) Name() mservice.Type { return mservice.LedgerAccounts }
func (a *LedgerAPI) Finish(ctx context.Context) error {
if a.client != nil {
if err := a.client.Close(); err != nil {
a.logger.Warn("Failed to close ledger client", zap.Error(err))
}
}
return nil
}
func CreateAPI(apiCtx eapi.API) (*LedgerAPI, error) {
p := &LedgerAPI{
logger: apiCtx.Logger().Named(mservice.LedgerAccounts),
enf: apiCtx.Permissions().Enforcer(),
oph: mutil.CreatePH(mservice.Organizations),
aph: mutil.CreatePH("ledger_account"),
}
desc, err := apiCtx.Permissions().GetPolicyDescription(context.Background(), mservice.LedgerAccounts)
if err != nil {
p.logger.Warn("Failed to fetch ledger accounts permission description", zap.Error(err))
return nil, err
}
p.permissionRef = desc.ID
bdesc, err := apiCtx.Permissions().GetPolicyDescription(context.Background(), mservice.LedgerBalances)
if err != nil {
p.logger.Warn("Failed to fetch ledger balances permission description", zap.Error(err))
return nil, err
}
p.balancePerm = bdesc.ID
if err := p.initLedgerClient(apiCtx.Config().Ledger); err != nil {
p.logger.Error("Failed to initialize ledger client", zap.Error(err))
return nil, err
}
apiCtx.Register().AccountHandler(p.Name(), p.oph.AddRef("/"), api.Get, p.listAccounts)
apiCtx.Register().AccountHandler(p.Name(), p.aph.AddRef(p.oph.AddRef("/"))+"/balance", api.Get, p.getBalance)
return p, nil
}
func (a *LedgerAPI) initLedgerClient(cfg *eapi.LedgerConfig) error {
if cfg == nil {
return merrors.InvalidArgument("ledger configuration is not provided")
}
address := strings.TrimSpace(cfg.Address)
if address == "" {
address = strings.TrimSpace(os.Getenv(cfg.AddressEnv))
}
if address == "" {
return merrors.InvalidArgument(fmt.Sprintf("ledger address is not specified and address env %s is empty", cfg.AddressEnv))
}
clientCfg := ledgerclient.Config{
Address: address,
DialTimeout: time.Duration(cfg.DialTimeoutSeconds) * time.Second,
CallTimeout: time.Duration(cfg.CallTimeoutSeconds) * time.Second,
Insecure: cfg.Insecure,
}
client, err := ledgerclient.New(context.Background(), clientCfg)
if err != nil {
return err
}
a.client = client
return nil
}