diff --git a/services/connector/api.go b/services/connector/api.go index a383be0ba..5c43b1feb 100644 --- a/services/connector/api.go +++ b/services/connector/api.go @@ -1,15 +1,42 @@ package connector -func NewAPI(s *Service) *API { - return &API{ - s: s, - } -} +import ( + "encoding/json" + "fmt" +) type API struct { s *Service + r *CommandRegistry +} + +func NewAPI(s *Service) *API { + r := NewCommandRegistry() + + return &API{ + s: s, + r: r, + } +} + +type RPCRequest struct { + JSONRPC string `json:"jsonrpc"` + ID int `json:"id"` + Method string `json:"method"` + Params []interface{} `json:"params"` } func (api *API) CallRPC(inputJSON string) (string, error) { + var request RPCRequest + + err := json.Unmarshal([]byte(inputJSON), &request) + if err != nil { + return "", fmt.Errorf("error unmarshalling JSON: %v", err) + } + + if command, exists := api.r.GetCommand(request.Method); exists { + return command.Execute(inputJSON) + } + return api.s.rpcClient.CallRaw(inputJSON), nil } diff --git a/services/connector/api_test.go b/services/connector/api_test.go index 28bb1169a..6229fa5cf 100644 --- a/services/connector/api_test.go +++ b/services/connector/api_test.go @@ -40,9 +40,7 @@ func setupTestAPI(t *testing.T) (*API, func()) { service := NewService(rpcClient, nil) - return &API{ - s: service, - }, cancel + return NewAPI(service), cancel } func TestCallRPC(t *testing.T) { @@ -51,21 +49,25 @@ func TestCallRPC(t *testing.T) { tests := []struct { request string + expectError bool expectedContains string notContains bool }{ { request: "{\"method\": \"eth_blockNumber\", \"params\": []}", + expectError: false, expectedContains: "does not exist/is not available", notContains: true, }, { request: "{\"method\": \"eth_blockNumbers\", \"params\": []}", + expectError: false, expectedContains: "does not exist/is not available", notContains: false, }, { request: "", + expectError: true, expectedContains: "does not exist/is not available", notContains: true, }, @@ -74,12 +76,16 @@ func TestCallRPC(t *testing.T) { for _, tt := range tests { t.Run(tt.request, func(t *testing.T) { response, err := api.CallRPC(tt.request) - require.NoError(t, err) - require.NotEmpty(t, response) - if tt.notContains { - require.NotContains(t, response, tt.expectedContains) + if tt.expectError { + require.Error(t, err) } else { - require.Contains(t, response, tt.expectedContains) + require.NoError(t, err) + require.NotEmpty(t, response) + if tt.notContains { + require.NotContains(t, response, tt.expectedContains) + } else { + require.Contains(t, response, tt.expectedContains) + } } }) } diff --git a/services/connector/command_registry.go b/services/connector/command_registry.go new file mode 100644 index 000000000..2499d5f57 --- /dev/null +++ b/services/connector/command_registry.go @@ -0,0 +1,20 @@ +package connector + +type CommandRegistry struct { + commands map[string]RPCCommand +} + +func NewCommandRegistry() *CommandRegistry { + return &CommandRegistry{ + commands: make(map[string]RPCCommand), + } +} + +func (r *CommandRegistry) Register(method string, command RPCCommand) { + r.commands[method] = command +} + +func (r *CommandRegistry) GetCommand(method string) (RPCCommand, bool) { + command, exists := r.commands[method] + return command, exists +} diff --git a/services/connector/rpc_command.go b/services/connector/rpc_command.go new file mode 100644 index 000000000..dfd216d66 --- /dev/null +++ b/services/connector/rpc_command.go @@ -0,0 +1,5 @@ +package connector + +type RPCCommand interface { + Execute(inputJSON string) (string, error) +}