Skip to content

Commit

Permalink
Merge pull request #19 from kaleido-io/error-details
Browse files Browse the repository at this point in the history
Move RPC Client code to shared package
  • Loading branch information
peterbroadhurst authored Aug 24, 2022
2 parents 57d32cc + 4c67bb1 commit 1370254
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 34 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ endef

$(eval $(call makemock, pkg/ethsigner, Wallet, ethsignermocks))
$(eval $(call makemock, internal/rpcserver, Server, rpcservermocks))
$(eval $(call makemock, internal/rpcbackend, Backend, rpcbackendmocks))
$(eval $(call makemock, pkg/rpcbackend, Backend, rpcbackendmocks))

firefly-signer: ${GOFILES}
$(VGO) build -o ./firefly-signer -ldflags "-X main.buildDate=`date -u +\"%Y-%m-%dT%H:%M:%SZ\"` -X main.buildVersion=$(BUILD_VERSION)" -tags=prod -tags=prod -v ./ffsigner
Expand Down
2 changes: 1 addition & 1 deletion internal/rpcserver/rpchandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import (
"github.com/hyperledger/firefly-common/pkg/fftypes"
"github.com/hyperledger/firefly-common/pkg/i18n"
"github.com/hyperledger/firefly-common/pkg/log"
"github.com/hyperledger/firefly-signer/internal/rpcbackend"
"github.com/hyperledger/firefly-signer/internal/signermsgs"
"github.com/hyperledger/firefly-signer/pkg/rpcbackend"
)

func (s *rpcServer) rpcHandler(w http.ResponseWriter, r *http.Request) {
Expand Down
2 changes: 1 addition & 1 deletion internal/rpcserver/rpchandler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ import (
"testing/iotest"

"github.com/hyperledger/firefly-common/pkg/fftypes"
"github.com/hyperledger/firefly-signer/internal/rpcbackend"
"github.com/hyperledger/firefly-signer/mocks/ethsignermocks"
"github.com/hyperledger/firefly-signer/mocks/rpcbackendmocks"
"github.com/hyperledger/firefly-signer/pkg/ethsigner"
"github.com/hyperledger/firefly-signer/pkg/ethtypes"
"github.com/hyperledger/firefly-signer/pkg/rpcbackend"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
Expand Down
2 changes: 1 addition & 1 deletion internal/rpcserver/rpcprocessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ import (

"github.com/hyperledger/firefly-common/pkg/fftypes"
"github.com/hyperledger/firefly-common/pkg/i18n"
"github.com/hyperledger/firefly-signer/internal/rpcbackend"
"github.com/hyperledger/firefly-signer/internal/signermsgs"
"github.com/hyperledger/firefly-signer/pkg/ethsigner"
"github.com/hyperledger/firefly-signer/pkg/ethtypes"
"github.com/hyperledger/firefly-signer/pkg/rpcbackend"
)

func (s *rpcServer) processRPC(ctx context.Context, rpcReq *rpcbackend.RPCRequest) (*rpcbackend.RPCResponse, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/rpcserver/rpcprocessor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import (
"testing"

"github.com/hyperledger/firefly-common/pkg/fftypes"
"github.com/hyperledger/firefly-signer/internal/rpcbackend"
"github.com/hyperledger/firefly-signer/mocks/ethsignermocks"
"github.com/hyperledger/firefly-signer/mocks/rpcbackendmocks"
"github.com/hyperledger/firefly-signer/pkg/ethtypes"
"github.com/hyperledger/firefly-signer/pkg/rpcbackend"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
Expand Down
5 changes: 3 additions & 2 deletions internal/rpcserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ import (

"github.com/gorilla/mux"
"github.com/hyperledger/firefly-common/pkg/config"
"github.com/hyperledger/firefly-common/pkg/ffresty"
"github.com/hyperledger/firefly-common/pkg/httpserver"
"github.com/hyperledger/firefly-common/pkg/i18n"
"github.com/hyperledger/firefly-signer/internal/rpcbackend"
"github.com/hyperledger/firefly-signer/internal/signerconfig"
"github.com/hyperledger/firefly-signer/internal/signermsgs"
"github.com/hyperledger/firefly-signer/pkg/ethsigner"
"github.com/hyperledger/firefly-signer/pkg/ethtypes"
"github.com/hyperledger/firefly-signer/pkg/rpcbackend"
)

type Server interface {
Expand All @@ -40,7 +41,7 @@ type Server interface {
func NewServer(ctx context.Context, wallet ethsigner.Wallet) (ss Server, err error) {

s := &rpcServer{
backend: rpcbackend.NewRPCBackend(ctx),
backend: rpcbackend.NewRPCClient(ffresty.New(ctx, signerconfig.BackendConfig)),
apiServerDone: make(chan error),
wallet: wallet,
chainID: config.GetInt64(signerconfig.BackendChainID),
Expand Down
2 changes: 1 addition & 1 deletion internal/signermsgs/en_error_messges.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var ffe = func(key, translation string, statusHint ...int) i18n.ErrorMessageKey
var (
MsgInvalidOutputType = ffe("FF22010", "Invalid output type: %s")
MsgInvalidParam = ffe("FF22011", "Invalid parameter at position %d for method %s: %s")
MsgRPCRequestFailed = ffe("FF22012", "Backend RPC request failed")
MsgRPCRequestFailed = ffe("FF22012", "Backend RPC request failed: %s")
MsgReadDirFile = ffe("FF22013", "Directory listing failed")
MsgWalletNotAvailable = ffe("FF22014", "Wallet for address '%s' not available")
MsgWalletFailed = ffe("FF22015", "Wallet for address '%s' could not be initialized")
Expand Down
2 changes: 1 addition & 1 deletion mocks/rpcbackendmocks/backend.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 32 additions & 23 deletions internal/rpcbackend/backend.go → pkg/rpcbackend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ import (
"sync/atomic"

"github.com/go-resty/resty/v2"
"github.com/hyperledger/firefly-common/pkg/ffresty"
"github.com/hyperledger/firefly-common/pkg/fftypes"
"github.com/hyperledger/firefly-common/pkg/i18n"
"github.com/hyperledger/firefly-common/pkg/log"
"github.com/hyperledger/firefly-signer/internal/signerconfig"
"github.com/hyperledger/firefly-signer/internal/signermsgs"
"github.com/sirupsen/logrus"
)

type RPCCode int64
Expand All @@ -45,14 +44,14 @@ type Backend interface {
SyncRequest(ctx context.Context, rpcReq *RPCRequest) (rpcRes *RPCResponse, err error)
}

// NewRPCBackend Constructor
func NewRPCBackend(ctx context.Context) Backend {
return &rpcBackend{
client: ffresty.New(ctx, signerconfig.BackendConfig),
// NewRPCClient Constructor
func NewRPCClient(client *resty.Client) Backend {
return &RPCClient{
client: client,
}
}

type rpcBackend struct {
type RPCClient struct {
client *resty.Client
requestCounter int64
}
Expand All @@ -65,9 +64,9 @@ type RPCRequest struct {
}

type RPCError struct {
Code int64 `json:"code"`
Message string `json:"message"`
Data []*fftypes.JSONAny `json:"data,omitempty"`
Code int64 `json:"code"`
Message string `json:"message"`
Data fftypes.JSONAny `json:"data,omitempty"`
}

type RPCResponse struct {
Expand All @@ -84,12 +83,12 @@ func (r *RPCResponse) Message() string {
return ""
}

func (rb *rpcBackend) allocateRequestID(req *RPCRequest) {
reqID := atomic.AddInt64(&rb.requestCounter, 1)
func (rc *RPCClient) allocateRequestID(req *RPCRequest) {
reqID := atomic.AddInt64(&rc.requestCounter, 1)
req.ID = fftypes.JSONAnyPtr(fmt.Sprintf(`"%.9d"`, reqID))
}

func (rb *rpcBackend) CallRPC(ctx context.Context, result interface{}, method string, params ...interface{}) error {
func (rc *RPCClient) CallRPC(ctx context.Context, result interface{}, method string, params ...interface{}) error {
req := &RPCRequest{
JSONRpc: "2.0",
Method: method,
Expand All @@ -102,7 +101,7 @@ func (rb *rpcBackend) CallRPC(ctx context.Context, result interface{}, method st
}
req.Params[i] = fftypes.JSONAnyPtrBytes(b)
}
res, err := rb.SyncRequest(ctx, req)
res, err := rc.SyncRequest(ctx, req)
if err != nil {
return err
}
Expand All @@ -114,32 +113,42 @@ func (rb *rpcBackend) CallRPC(ctx context.Context, result interface{}, method st
//
// In all return paths *including error paths* the RPCResponse is populated
// so the caller has an RPC structure to send back to the front-end caller.
func (rb *rpcBackend) SyncRequest(ctx context.Context, rpcReq *RPCRequest) (rpcRes *RPCResponse, err error) {
func (rc *RPCClient) SyncRequest(ctx context.Context, rpcReq *RPCRequest) (rpcRes *RPCResponse, err error) {

// We always set the back-end request ID - as we need to support requests coming in from
// multiple concurrent clients on our front-end that might use clashing IDs.
var beReq = *rpcReq
beReq.JSONRpc = "2.0"
rb.allocateRequestID(&beReq)
rc.allocateRequestID(&beReq)
rpcRes = new(RPCResponse)

log.L(ctx).Infof("RPC:%s:%s --> %s", beReq.ID, rpcReq.ID, rpcReq.Method)
res, err := rb.client.R().
log.L(ctx).Debugf("RPC:%s:%s --> %s", rpcReq.ID, rpcReq.ID, rpcReq.Method)
if logrus.IsLevelEnabled(logrus.TraceLevel) {
jsonInput, _ := json.Marshal(rpcReq)
log.L(ctx).Tracef("RPC:%s:%s INPUT: %s", rpcReq.ID, rpcReq.ID, jsonInput)
}
res, err := rc.client.R().
SetContext(ctx).
SetBody(&beReq).
SetResult(rpcRes).
SetBody(beReq).
SetResult(&rpcRes).
SetError(rpcRes).
Post("")

// Restore the original ID
rpcRes.ID = rpcReq.ID
if err != nil {
err := i18n.NewError(ctx, signermsgs.MsgRPCRequestFailed)
log.L(ctx).Errorf("RPC:%s:%s <-- ERROR: %s", beReq.ID, rpcReq.ID, err)
log.L(ctx).Errorf("RPC[%d] <-- ERROR: %s", rpcReq.ID, err)
rpcRes = RPCErrorResponse(err, rpcReq.ID, RPCCodeInternalError)
return rpcRes, err
}
if res.IsError() {
log.L(ctx).Errorf("RPC:%s:%s <-- [%d]: %s", beReq.ID, rpcReq.ID, res.StatusCode(), rpcRes.Message())
if logrus.IsLevelEnabled(logrus.TraceLevel) {
jsonOutput, _ := json.Marshal(rpcRes)
log.L(ctx).Tracef("RPC:%s:%s OUTPUT: %s", rpcReq.ID, rpcReq.ID, jsonOutput)
}
// JSON/RPC allows errors to be returned with a 200 status code, as well as other status codes
if res.IsError() || rpcRes.Error != nil && rpcRes.Error.Code != 0 {
log.L(ctx).Errorf("RPC[%d] <-- [%d]: %s", rpcReq.ID, res.StatusCode(), rpcRes.Message())
err := fmt.Errorf(rpcRes.Message())
return rpcRes, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import (

type testRPCHander func(rpcReq *RPCRequest) (int, *RPCResponse)

func newTestServer(t *testing.T, rpcHandler testRPCHander) (context.Context, *rpcBackend, func()) {
func newTestServer(t *testing.T, rpcHandler testRPCHander) (context.Context, *RPCClient, func()) {

ctx, cancelCtx := context.WithCancel(context.Background())
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -60,7 +60,7 @@ func newTestServer(t *testing.T, rpcHandler testRPCHander) (context.Context, *rp
prefix := signerconfig.BackendConfig
prefix.Set(ffresty.HTTPConfigURL, fmt.Sprintf("http://%s", server.Listener.Addr()))

rb := NewRPCBackend(ctx).(*rpcBackend)
rb := NewRPCClient(ffresty.New(ctx, signerconfig.BackendConfig)).(*RPCClient)

return ctx, rb, func() {
cancelCtx()
Expand Down

0 comments on commit 1370254

Please sign in to comment.