Skip to content

Commit

Permalink
fix: control messages not using uuid
Browse files Browse the repository at this point in the history
This commits fix the use of uuid in control messages by modifying
Command message to just contains the Content structure of the Control
message.

This commits also fix some logic on generateControlMessage.

Signed-off-by: Alba Hita Catala <[email protected]>
  • Loading branch information
ahitacat committed May 17, 2023
1 parent 7797bf3 commit ded1b12
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 52 deletions.
2 changes: 1 addition & 1 deletion cmd/yggctl/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func generateMessage(messageType, responseTo, directive, content string, metadat
}
return data, nil
case "command":
msg, err := generateCommandMessage(yggdrasil.MessageType(messageType), responseTo, version, []byte(content))
msg, err := generateControlMessage(yggdrasil.MessageType(messageType), responseTo, version, []byte(content))
if err != nil {
return nil, err
}
Expand Down
39 changes: 16 additions & 23 deletions cmd/yggctl/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,20 @@ func generateDataMessage(messageType yggdrasil.MessageType, responseTo string, d
func generateControlMessage(messageType yggdrasil.MessageType, responseTo string, version int, content []byte) (*yggdrasil.Control, error) {
switch messageType {
case yggdrasil.MessageTypeCommand:
msg, err := generateCommandMessage(messageType, responseTo, version, content)
if err != nil {
return nil, fmt.Errorf("cannot generate command message: %v", err)
ctrl := yggdrasil.Control{
Type: messageType,
MessageID: uuid.New().String(),
ResponseTo: responseTo,
Version: version,
Sent: time.Now(),
}
data, err := json.Marshal(msg)

command, err := generateCommandContent(content)
cmd, err := json.Marshal(command)
if err != nil {
return nil, fmt.Errorf("cannot marshal command message: %v", err)
}
var ctrl yggdrasil.Control
if err := json.Unmarshal(data, &ctrl); err != nil {
return nil, fmt.Errorf("cannot unmarshal control message: %v", err)
return nil, fmt.Errorf("cannot generate command message: %v", err)
}
ctrl.Content = cmd
return &ctrl, nil
case yggdrasil.MessageTypeEvent:
msg, err := generateEventMessage(messageType, responseTo, version, content)
Expand All @@ -61,21 +63,12 @@ func generateControlMessage(messageType yggdrasil.MessageType, responseTo string
}
}

// generateCommandMessage unmarshals bytes into a command message.
func generateCommandMessage(messageType yggdrasil.MessageType, responseTo string, version int, content []byte) (*yggdrasil.Command, error) {
msg := yggdrasil.Command{
Type: messageType,
MessageID: uuid.New().String(),
ResponseTo: responseTo,
Version: version,
Sent: time.Now(),
func generateCommandContent(content []byte) (*yggdrasil.Command, error) {
var command yggdrasil.Command
if err := json.Unmarshal(content, &command); err != nil {
return &command, fmt.Errorf("cannot unmarshal content: %v", err)
}

if err := json.Unmarshal(content, &msg.Content); err != nil {
return nil, fmt.Errorf("cannot unmarshal content: %v", err)
}

return &msg, nil
return &command, nil
}

func generateEventMessage(messageType yggdrasil.MessageType, responseTo string, version int, content []byte) (*yggdrasil.Event, error) {
Expand Down
29 changes: 18 additions & 11 deletions cmd/yggctl/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,22 +96,15 @@ func TestGenerateCommandMessage(t *testing.T) {
version: 1,
},
want: &yggdrasil.Command{
Type: yggdrasil.MessageTypeCommand,
Version: 1,
Content: struct {
Command yggdrasil.CommandName "json:\"command\""
Arguments map[string]string "json:\"arguments\""
}{
Command: "ping",
Arguments: map[string]string{},
},
Command: "ping",
Arguments: map[string]string{},
},
},
}

for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
got, err := generateCommandMessage(yggdrasil.MessageType(test.input.messageType), test.input.responseTo, test.input.version, test.input.content)
got, err := generateCommandContent(test.input.content)

if test.wantError != nil {
if !cmp.Equal(err, test.wantError, cmpopts.EquateErrors()) {
Expand All @@ -121,7 +114,7 @@ func TestGenerateCommandMessage(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !cmp.Equal(got, test.want, cmpopts.IgnoreFields(yggdrasil.Command{}, "MessageID", "Sent")) {
if !cmp.Equal(got, test.want) {
t.Errorf("%#v != %#v", got, test.want)
}
}
Expand All @@ -137,6 +130,7 @@ func TestGenerateControlMessage(t *testing.T) {
wantError error
}{
{
description: "control event",
input: Input{
messageType: "event",
content: []byte(`pong`),
Expand All @@ -148,6 +142,19 @@ func TestGenerateControlMessage(t *testing.T) {
Content: json.RawMessage(`"pong"`),
},
},
{
description: "control command",
input: Input{
messageType: "command",
content: []byte(`{"command":"ping","arguments":{}}`),
version: 1,
},
want: &yggdrasil.Control{
Type: yggdrasil.MessageTypeCommand,
Version: 1,
Content: json.RawMessage(`{"command":"ping","arguments":{}}`),
},
},
}

for _, test := range tests {
Expand Down
16 changes: 8 additions & 8 deletions cmd/yggd/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,20 +257,20 @@ func (c *Client) ReceiveControlMessage(msg *yggdrasil.Control) error {
switch msg.Type {
case yggdrasil.MessageTypeCommand:
var cmd yggdrasil.Command
if err := json.Unmarshal(msg.Content, &cmd.Content); err != nil {
if err := json.Unmarshal(msg.Content, &cmd); err != nil {
return fmt.Errorf("cannot unmarshal command message: %w", err)
}

log.Debugf("received message %v", cmd.MessageID)
log.Tracef("command: %+v", cmd)
log.Tracef("Control message: %v", cmd)
log.Debugf("received message %v", msg.MessageID)
log.Tracef("command: %+v", cmd.Command)
log.Tracef("Control message: %v", msg)

switch cmd.Content.Command {
switch cmd.Command {
case yggdrasil.CommandNamePing:
event := yggdrasil.Event{
Type: yggdrasil.MessageTypeEvent,
MessageID: uuid.New().String(),
ResponseTo: cmd.MessageID,
ResponseTo: msg.MessageID,
Version: 1,
Sent: time.Now(),
Content: string(yggdrasil.EventNamePong),
Expand All @@ -290,7 +290,7 @@ func (c *Client) ReceiveControlMessage(msg *yggdrasil.Control) error {
case yggdrasil.CommandNameReconnect:
log.Info("reconnecting...")
c.transporter.Disconnect(500)
delay, err := strconv.ParseInt(cmd.Content.Arguments["delay"], 10, 64)
delay, err := strconv.ParseInt(cmd.Arguments["delay"], 10, 64)
if err != nil {
return fmt.Errorf("cannot parse data to int: %w", err)
}
Expand All @@ -300,7 +300,7 @@ func (c *Client) ReceiveControlMessage(msg *yggdrasil.Control) error {
return fmt.Errorf("cannot reconnect to broker: %w", err)
}
default:
return fmt.Errorf("unknown command: %v", cmd.Content.Command)
return fmt.Errorf("unknown command: %v", cmd.Command)
}
default:
return fmt.Errorf("unsupported control message: %v", msg)
Expand Down
11 changes: 2 additions & 9 deletions messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,8 @@ type ConnectionStatus struct {
// A Command message is published by the server on the "control" topic when it
// needs to instruct a client to perform an operation.
type Command struct {
Type MessageType `json:"type"`
MessageID string `json:"message_id"`
ResponseTo string `json:"response_to"`
Version int `json:"version"`
Sent time.Time `json:"sent"`
Content struct {
Command CommandName `json:"command"`
Arguments map[string]string `json:"arguments"`
} `json:"content"`
Command CommandName `json:"command"`
Arguments map[string]string `json:"arguments"`
}

// An Event message is published by the client on the "control" topic when it
Expand Down

0 comments on commit ded1b12

Please sign in to comment.