diff --git a/v2/internal/binding/boundMethod.go b/v2/internal/binding/boundMethod.go index e7786734..7807bcfd 100644 --- a/v2/internal/binding/boundMethod.go +++ b/v2/internal/binding/boundMethod.go @@ -1,6 +1,7 @@ package binding import ( + "encoding/json" "fmt" "reflect" "strings" @@ -78,6 +79,26 @@ func (b *BoundMethod) OutputCount() int { return len(b.Outputs) } +// ParseArgs method converts the input json into the types expected by the method +func (b *BoundMethod) ParseArgs(args []json.RawMessage) ([]interface{}, error) { + + result := make([]interface{}, b.InputCount()) + for index, arg := range args { + typ := b.Inputs[index].reflectType + inputValue := reflect.New(typ).Interface() + err := json.Unmarshal(arg, inputValue) + if err != nil { + return nil, err + } + if inputValue == nil { + result[index] = reflect.Zero(typ).Interface() + } else { + result[index] = reflect.ValueOf(inputValue).Elem().Interface() + } + } + return result, nil +} + // Call will attempt to call this bound method with the given args func (b *BoundMethod) Call(args []interface{}) (interface{}, error) { // Check inputs @@ -94,17 +115,8 @@ func (b *BoundMethod) Call(args []interface{}) (interface{}, error) { // Iterate over given arguments for index, arg := range args { - - // Attempt to convert the argument to the type expected by the method - value, err := convertArgToValue(arg, b.Inputs[index]) - - // If it fails, return a suitable error - if err != nil { - return nil, fmt.Errorf("%s (parameter %d): %s", b.Name, index+1, err.Error()) - } - // Save the converted argument - callArgs[index] = value + callArgs[index] = reflect.ValueOf(arg) } // Do the call diff --git a/v2/internal/binding/reflect.go b/v2/internal/binding/reflect.go index 9723d3a9..5b2d47ba 100755 --- a/v2/internal/binding/reflect.go +++ b/v2/internal/binding/reflect.go @@ -1,6 +1,7 @@ package binding import ( + "encoding/json" "fmt" "reflect" ) @@ -84,7 +85,7 @@ func getMethods(value interface{}) ([]*BoundMethod, error) { } // convertArgToValue -func convertArgToValue(input interface{}, target *Parameter) (result reflect.Value, err error) { +func convertArgToValue(input json.RawMessage, target *Parameter) (result reflect.Value, err error) { // Catch type conversion panics thrown by convert defer func() { diff --git a/v2/internal/messagedispatcher/message/call.go b/v2/internal/messagedispatcher/message/call.go index a3fb4b60..946e00a9 100644 --- a/v2/internal/messagedispatcher/message/call.go +++ b/v2/internal/messagedispatcher/message/call.go @@ -6,9 +6,9 @@ import ( ) type CallMessage struct { - Name string `json:"name"` - Args []interface{} `json:"args"` - CallbackID string `json:"callbackID,omitempty"` + Name string `json:"name"` + Args []json.RawMessage `json:"args"` + CallbackID string `json:"callbackID,omitempty"` } // callMessageParser does what it says on the tin! @@ -22,6 +22,7 @@ func callMessageParser(message string) (*parsedMessage, error) { callMessage := new(CallMessage) m := message[1:] + err := json.Unmarshal([]byte(m), callMessage) if err != nil { println(err.Error()) diff --git a/v2/internal/subsystem/call.go b/v2/internal/subsystem/call.go index 85995777..0ae86a9b 100644 --- a/v2/internal/subsystem/call.go +++ b/v2/internal/subsystem/call.go @@ -106,7 +106,12 @@ func (c *Call) processCall(callMessage *servicebus.Message) { } c.logger.Trace("Got registered method: %+v", registeredMethod) - result, err := registeredMethod.Call(payload.Args) + args, err := registeredMethod.ParseArgs(payload.Args) + if err != nil { + c.sendError(fmt.Errorf("Error parsing arguments: %s", err.Error()), payload, callMessage.Target()) + } + + result, err := registeredMethod.Call(args) if err != nil { c.sendError(err, payload, callMessage.Target()) return