Skip to content
This repository has been archived by the owner on May 26, 2023. It is now read-only.

Commit

Permalink
feat: add support for core-command list
Browse files Browse the repository at this point in the history
This commit adds support for the `list` command of the `command` endpoint.

```
edgex-cli command list
```

Adds support for the `-j`, `-v` flags, which generate raw JSON output.
Adds support for the `-l` flag, which limits the number of items to return.
Adds support for the `-o` flag, which indicates the number of items to skip.

Signed-off-by: Mengyi <mengyi.wang@canonical.com>
  • Loading branch information
MonicaisHer committed Oct 19, 2021
1 parent 87a5b2f commit 337d45e
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
97 changes: 97 additions & 0 deletions internal/cmd/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
jsonpkg "encoding/json"
"errors"
"fmt"
"github.com/edgexfoundry/go-mod-core-contracts/v2/dtos"
"github.com/spf13/cobra"
"io/ioutil"
"os"
Expand All @@ -29,11 +30,13 @@ import (
var deviceName, commandName string
var pushEvent, noReturnEvent bool
var requestBody, requestFile string
var limit, offset int

func init() {
commandCmd := initCommandCommand()
initReadCommand(commandCmd)
initWriteCommand(commandCmd)
initListCommand(commandCmd)
}

func initCommandCommand() *cobra.Command {
Expand Down Expand Up @@ -84,6 +87,21 @@ func initWriteCommand(cmd *cobra.Command) {
addFormatFlags(writeCmd)
}

func initListCommand(cmd *cobra.Command) {
listCmd := &cobra.Command{
Use: "list",
Short: "A list of device supported commands",
Long: "Returns a paginated list contains all of the commands in the system associated with their respective device, optionally filtering by device name",
RunE: handleListCommand,
SilenceUsage: true,
}
listCmd.Flags().StringVarP(&deviceName, "device", "d", "", "List commands specified by device name")
listCmd.Flags().IntVarP(&limit, "limit", "l", 50, "The number of items to return. Specifying -1 will return all remaining items")
listCmd.Flags().IntVarP(&offset, "offset", "o", 0, "The number of items to skip")
cmd.AddCommand(listCmd)
addFormatFlags(listCmd)
}

func handleReadCommand(cmd *cobra.Command, args []string) error {
dsPushEvent := boolToString(pushEvent)
dsReturnEvent := boolToString(!noReturnEvent)
Expand Down Expand Up @@ -168,6 +186,85 @@ func handleWriteCommand(cmd *cobra.Command, args []string) error {
return nil
}

func handleListCommand(cmd *cobra.Command, args []string) error {
//LIST commands with specified device name
if deviceName != "" {
response, err := getCoreCommandService().ListCommandsByDeviceName(deviceName)
if err != nil {
return err
}

//print LIST commands with one of these formats: JSON, verbose or table
if json || verbose {
stringified, err := jsonpkg.Marshal(response)
if err != nil {
return err
}

if verbose {
url := getCoreCommandService().GetListByDeviceEndpoint(deviceName)
fmt.Printf("Result:%s\nURL: %s\n", string(stringified), url)
} else {
fmt.Printf(string(stringified))
}
} else {
w := tabwriter.NewWriter(os.Stdout, 1, 1, 2, ' ', 0)
fmt.Fprintln(w, "Name\tDevice Name\tProfile Name\tMethods\tURL")
for _, command := range response.DeviceCoreCommand.CoreCommands {
methods := methodsToString(command)
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
command.Name, response.DeviceCoreCommand.DeviceName, response.DeviceCoreCommand.ProfileName, methods, command.Url+command.Path)
}
w.Flush()
}
//LIST all commands, optionally specifying a limit and offset
} else {
response, err := getCoreCommandService().ListAllCommands(offset, limit)
if err != nil {
return err
}

//print LIST command's output with one of these formats: JSON, verbose or table
if json || verbose {
stringified, err := jsonpkg.Marshal(response)
if err != nil {
return err
}

if verbose {
url := getCoreCommandService().GetListAllEndpoint()
fmt.Printf("Result:%s\nURL: %s\n", string(stringified), url)
} else {
fmt.Printf(string(stringified))
}
} else {
w := tabwriter.NewWriter(os.Stdout, 1, 1, 2, ' ', 0)
fmt.Fprintln(w, "Name\tDevice Name\tProfile Name\tMethods\tURL")
for _, device := range response.DeviceCoreCommands {
for _, command := range device.CoreCommands {
methods := methodsToString(command)
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
command.Name, device.DeviceName, device.ProfileName, methods, command.Url+command.Path)
}
}
w.Flush()
}
}

return nil
}

//using by LIST when it shows in table format
func methodsToString(command dtos.CoreCommand) string {
if command.Get && command.Set {
return "Get, Put"
} else if command.Get {
return "Get"
} else {
return "Put"
}
}

//using by READ when it specified dsPushEvent or dsReturnEvent
func boolToString(b bool) string {
if b {
Expand Down
22 changes: 22 additions & 0 deletions internal/service/corecommandservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ func (c Service) IssueWriteCommand(deviceName string, commandName string, settin
return
}

func (c Service) ListAllCommands(offset int, limit int) (response responses.MultiDeviceCoreCommandsResponse, err error) {
client := c.getCommandClient()
response, err = client.AllDeviceCoreCommands(context.Background(), offset, limit)
return
}

func (c Service) ListCommandsByDeviceName(deviceName string) (response responses.DeviceCoreCommandResponse, err error) {
client := c.getCommandClient()
response, err = client.DeviceCoreCommandsByDeviceName(context.Background(), deviceName)
return
}

func (c Service) GetReadEndpoint(deviceName string, commandName string, dsPushEvent string, dsReturnEvent string) string {
url := c.getEndpointUrl(common.ApiDeviceNameCommandNameRoute)
replacer := strings.NewReplacer("{name}", deviceName, "{command}", commandName)
Expand All @@ -51,6 +63,16 @@ func (c Service) GetWriteEndpoint(deviceName string, commandName string, request
return replacer.Replace(url) + " -d '" + requestBody + "'"
}

func (c Service) GetListAllEndpoint() string {
return c.getEndpointUrl(common.ApiAllDeviceRoute)
}

func (c Service) GetListByDeviceEndpoint(deviceName string) string {
url := c.getEndpointUrl(common.ApiDeviceByNameRoute)
replacer := strings.NewReplacer("{name}", deviceName)
return replacer.Replace(url)
}

func (c Service) getEndpointUrl(endpoint string) string {
return fmt.Sprintf("http://%s:%v%s", c.Host, c.Port, endpoint)
}
Expand Down

0 comments on commit 337d45e

Please sign in to comment.