diff --git a/internal/cmd/common.go b/internal/cmd/common.go index aa0a782..1804599 100644 --- a/internal/cmd/common.go +++ b/internal/cmd/common.go @@ -41,6 +41,10 @@ func getSelectedServiceKey() string { } } +func getCoreDataService() service.Service { + return config.GetCoreService(common.CoreDataServiceKey) +} + func getSelectedServices() map[string]service.Service { key := getSelectedServiceKey() if key == "" { @@ -54,15 +58,18 @@ func getSelectedServices() map[string]service.Service { } +func addVerboseFlag(cmd *cobra.Command) { + cmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "show verbose/debug output") +} + func addFormatFlags(cmd *cobra.Command) { cmd.Flags().BoolVarP(&json, "json", "j", false, "show the raw JSON response") - cmd.Flags().BoolVarP(&verbose, "debug", "d", false, "show verbose/debug output") } func addStandardFlags(cmd *cobra.Command) { addFormatFlags(cmd) - cmd.Flags().BoolVarP(&data, "data", "", false, "use core-data service endpoint") + cmd.Flags().BoolVarP(&data, "data", "d", false, "use core-data service endpoint") cmd.Flags().BoolVarP(&command, "command", "c", false, "use core-command service endpoint") cmd.Flags().BoolVarP(&metadata, "metadata", "m", false, "use core-metadata service endpoint") cmd.Flags().BoolVarP(&scheduler, "scheduler", "s", false, "use support-scheduler service endpoint") diff --git a/internal/cmd/config.go b/internal/cmd/config.go index 4444110..f3ca1d3 100644 --- a/internal/cmd/config.go +++ b/internal/cmd/config.go @@ -18,6 +18,7 @@ package cmd import ( jsonpkg "encoding/json" + "fmt" "github.com/spf13/cobra" ) @@ -48,22 +49,22 @@ func showConfig(cmd *cobra.Command) error { if json { return err } else if verbose { - cmd.Printf("%s: %s: %s\n", serviceName, url, err.Error()) + fmt.Printf("%s: %s: %s\n", serviceName, url, err.Error()) } } else { if json { - cmd.Println(jsonValue) + fmt.Println(jsonValue) } else if verbose { - cmd.Printf("%s: %s: %s\n", serviceName, url, jsonValue) + fmt.Printf("%s: %s: %s\n", serviceName, url, jsonValue) } else { - cmd.Println(serviceName + ":") + fmt.Println(serviceName + ":") var result map[string]interface{} jsonpkg.Unmarshal([]byte(jsonValue), &result) b, err := jsonpkg.MarshalIndent(result["config"], "", " ") if err != nil { return err } - cmd.Println(string(b)) + fmt.Println(string(b)) } } } diff --git a/internal/cmd/event.go b/internal/cmd/event.go new file mode 100644 index 0000000..478c112 --- /dev/null +++ b/internal/cmd/event.go @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2021 Canonical Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0' + */ + +package cmd + +import ( + "fmt" + "os" + "text/tabwriter" + "time" + + "github.com/spf13/cobra" +) + +var eventLimit, eventOffset int +var eventDevice, eventProfile, eventSource, readingsValueType string +var eventAge int +var numberOfReadings int + +func init() { + eventCmd := initEventCommand() + initListEventCommand(eventCmd) + initCountEventCommand(eventCmd) + initRmEventCommand(eventCmd) + initAddEventCommand(eventCmd) +} + +func initEventCommand() *cobra.Command { + var cmd = &cobra.Command{ + Use: "event", + Short: "Add, remove and list events", + Long: ``, + SilenceUsage: true, + } + + rootCmd.AddCommand(cmd) + return cmd +} + +func initListEventCommand(cmd *cobra.Command) { + var listCmd = &cobra.Command{ + Use: "list", + Short: "List events", + Long: `List all events, optionally specifying a limit and offset`, + RunE: handleListEvents, + SilenceUsage: true, + } + + cmd.AddCommand(listCmd) + addFormatFlags(listCmd) + addVerboseFlag(listCmd) + listCmd.Flags().IntVarP(&eventLimit, "limit", "l", 50, "The number of items to return. Specifying -1 will return all remaining items") + listCmd.Flags().IntVarP(&eventOffset, "offset", "o", 0, "The number of items to skip") +} + +func initCountEventCommand(cmd *cobra.Command) { + var countCmd = &cobra.Command{ + Use: "count", + Short: "Count available events", + Long: `Count the number of events in core data, optionally filtering by device name`, + RunE: handleCountEvents, + SilenceUsage: true, + } + + countCmd.Flags().StringVarP(&eventDevice, "device", "d", "", "Device name") + cmd.AddCommand(countCmd) + addFormatFlags(countCmd) +} + +func initRmEventCommand(cmd *cobra.Command) { + var rmCmd = &cobra.Command{ + Use: "rm", + Short: "Remove events", + Long: `Remove events, specifying either device name or maximum event age in milliseconds + +'edgex-cli event rm --device {devicename}' removes all events for the specified device +'edgex-cli event rm --age {ms}' removes all events generated in the last {ms} milliseconds`, + RunE: handleRmEvents, + SilenceUsage: true, + } + + rmCmd.Flags().StringVarP(&eventDevice, "device", "d", "", "Device name") + rmCmd.Flags().IntVarP(&eventAge, "age", "a", 0, "Event age (in milliseconds)") + cmd.AddCommand(rmCmd) +} + +func initAddEventCommand(cmd *cobra.Command) { + var addCmd = &cobra.Command{ + Use: "add", + Short: "Create an event", + Long: `Create an event with a specified number of random readings`, + RunE: handleAddEvents, + SilenceUsage: true, + } + addCmd.Flags().StringVarP(&eventDevice, "device", "d", "", "Device name") + addCmd.Flags().StringVarP(&eventProfile, "profile", "p", "", "Profile name") + addCmd.Flags().StringVarP(&readingsValueType, "type", "t", "string", "Readings value type [bool | string | uint8 | uint16 | uint32 | uint64 | int8 | int16 | int32 | int64 | float32 | float64 ]") + addCmd.Flags().StringVarP(&eventSource, "source", "s", "", "Event source name (ResourceName or CommandName)") + addCmd.Flags().IntVarP(&numberOfReadings, "readings", "r", 1, "Number of sample readings to create") + addCmd.MarkFlagRequired("device") + addCmd.MarkFlagRequired("profile") + addCmd.MarkFlagRequired("source") + cmd.AddCommand(addCmd) +} + +func handleAddEvents(cmd *cobra.Command, args []string) error { + id, err := getCoreDataService().CreateEvent(eventDevice, eventProfile, eventSource, readingsValueType, numberOfReadings) + if err != nil { + return err + } + + fmt.Println("Event " + id + " created") + return nil +} + +func handleRmEvents(cmd *cobra.Command, args []string) error { + err := getCoreDataService().RemoveEvents(eventDevice, eventAge) + return err +} + +func handleCountEvents(cmd *cobra.Command, args []string) error { + if json { + var json string + var err error + + if eventDevice != "" { + json, _, err = getCoreDataService().CountEventsByDeviceJSON(eventDevice) + } else { + json, _, err = getCoreDataService().CountEventsJSON() + } + + if err != nil { + return err + } + fmt.Print(json) + + } else { + count, err := getCoreDataService().CountEvents(eventDevice) + if err != nil { + return err + } + if eventDevice != "" { + fmt.Printf("Total %s events: %v\n", eventDevice, count.Count) + } else { + fmt.Printf("Total events: %v\n", count.Count) + } + } + return nil +} + +func handleListEvents(cmd *cobra.Command, args []string) error { + var err error + + if json { + var json string + + json, _, err = getCoreDataService().ListAllEventsJSON(eventOffset, eventLimit) + + if err != nil { + return err + } + + fmt.Print(json) + + } else { + events, err := getCoreDataService().ListAllEvents(eventOffset, eventLimit) + if err != nil { + return err + } + if len(events) == 0 { + fmt.Println("No events available") + return nil + } + + w := tabwriter.NewWriter(os.Stdout, 1, 1, 2, ' ', 0) + if verbose { + fmt.Fprintln(w, "Origin\tDevice\tProfile\tSource\tId\tVersionable\tReadings") + for _, event := range events { + fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\n", + time.Unix(0, event.Origin).Format(time.RFC822), + event.DeviceName, + event.ProfileName, + event.SourceName, + event.Id, + event.Versionable, + event.Readings) + } + + } else { + fmt.Fprintln(w, "Origin\tDevice\tProfile\tSource\tNumber of readings") + for _, event := range events { + tm := time.Unix(0, event.Origin) + sTime := tm.Format(time.RFC822) + nReadings := 0 + if event.Readings != nil { + nReadings = len(event.Readings) + } + fmt.Fprintf(w, "%s\t%s\t%s\t%v\t%d\n", + sTime, event.DeviceName, event.ProfileName, event.SourceName, nReadings) + } + } + w.Flush() + } + return nil +} diff --git a/internal/cmd/metrics.go b/internal/cmd/metrics.go index ca8ddde..71c21b5 100644 --- a/internal/cmd/metrics.go +++ b/internal/cmd/metrics.go @@ -51,9 +51,9 @@ func showMetrics(cmd *cobra.Command) error { return err } else { if json { - cmd.Println(jsonValue) + fmt.Println(jsonValue) } else { - cmd.Printf("%s: %s: %s\n", serviceName, url, jsonValue) + fmt.Printf("%s: %s: %s\n", serviceName, url, jsonValue) } } } diff --git a/internal/cmd/ping.go b/internal/cmd/ping.go index 4e1b892..04cafff 100644 --- a/internal/cmd/ping.go +++ b/internal/cmd/ping.go @@ -18,6 +18,7 @@ package cmd import ( jsonpkg "encoding/json" + "fmt" "github.com/spf13/cobra" ) @@ -49,17 +50,17 @@ func showPing(cmd *cobra.Command) error { if json { return err } else if verbose { - cmd.Printf("%s: %s: %s\n", serviceName, url, err.Error()) + fmt.Printf("%s: %s: %s\n", serviceName, url, err.Error()) } } else { if json { - cmd.Println(jsonValue) + fmt.Println(jsonValue) } else if verbose { - cmd.Printf("%s: %s: %s\n", serviceName, url, jsonValue) + fmt.Printf("%s: %s: %s\n", serviceName, url, jsonValue) } else { var result map[string]interface{} jsonpkg.Unmarshal([]byte(jsonValue), &result) - cmd.Println(serviceName + ": " + result["timestamp"].(string)) + fmt.Println(serviceName + ": " + result["timestamp"].(string)) } } diff --git a/internal/cmd/reading.go b/internal/cmd/reading.go new file mode 100644 index 0000000..228c56a --- /dev/null +++ b/internal/cmd/reading.go @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2021 Canonical Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0' + */ + +package cmd + +import ( + "fmt" + "os" + "text/tabwriter" + "time" + + "github.com/spf13/cobra" +) + +var readingDevice string +var readingLimit, readingOffset int + +func init() { + readingCmd := initReadingCommand() + initListReadingCommand(readingCmd) + initCountReadingCommand(readingCmd) +} + +func initReadingCommand() *cobra.Command { + var cmd = &cobra.Command{ + Use: "reading", + Short: "Count and list readings", + Long: ``, + SilenceUsage: true, + } + rootCmd.AddCommand(cmd) + return cmd +} + +func initListReadingCommand(cmd *cobra.Command) { + var listCmd = &cobra.Command{ + Use: "list", + Short: "List all readings", + Long: `List all readings, optionally specifying a limit and offset`, + RunE: handleListReadings, + SilenceUsage: true, + } + listCmd.Flags().IntVarP(&readingLimit, "limit", "l", 50, "The number of items to return. Specifying -1 will return all remaining items") + listCmd.Flags().IntVarP(&readingOffset, "offset", "o", 0, "The number of items to skip") + cmd.AddCommand(listCmd) + addFormatFlags(listCmd) + addVerboseFlag(listCmd) + +} + +func initCountReadingCommand(cmd *cobra.Command) { + var countCmd = &cobra.Command{ + Use: "count", + Short: "Count available readings", + Long: `Count the number of readings in core data, optionally filtering by device name`, + RunE: handleCountReadings, + SilenceUsage: true, + } + + countCmd.Flags().StringVarP(&readingDevice, "device", "d", "", "Device name") + cmd.AddCommand(countCmd) + addFormatFlags(countCmd) +} + +func handleCountReadings(cmd *cobra.Command, args []string) error { + if json { + var json string + var err error + + if readingDevice != "" { + json, _, err = getCoreDataService().CountReadingsByDeviceJSON(readingDevice) + } else { + json, _, err = getCoreDataService().CountReadingsJSON() + } + + if err != nil { + return err + } + fmt.Print(json) + + } else { + count, err := getCoreDataService().CountEvents(readingDevice) + if err != nil { + return err + } + if readingDevice != "" { + fmt.Printf("Total %s readings: %v\n", readingDevice, count.Count) + } else { + fmt.Printf("Total readings: %v\n", count.Count) + } + } + return nil +} + +func handleListReadings(cmd *cobra.Command, args []string) error { + var err error + + if json { + var json string + + json, _, err = getCoreDataService().ListAllReadingsJSON(readingOffset, readingLimit) + + if err != nil { + return err + } + + fmt.Print(json) + + } else { + readings, err := getCoreDataService().ListAllReadings(readingOffset, readingLimit) + if err != nil { + return err + } + if len(readings) == 0 { + fmt.Println("No readings available") + return nil + } + + w := tabwriter.NewWriter(os.Stdout, 1, 1, 2, ' ', 0) + if verbose { + fmt.Fprintln(w, "Origin\tDeviceName\tProfileName\tValue\tValueType\tId\tMediaType\tBinaryValue") + for _, reading := range readings { + + fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", + time.Unix(0, reading.Origin).Format(time.RFC822), + reading.DeviceName, + reading.ProfileName, + reading.Value, + reading.ValueType, + reading.Id, + reading.MediaType, + reading.BinaryValue) + } + } else { + fmt.Fprintln(w, "Origin\tDevice\tProfileName\tValue\tValueType") + for _, reading := range readings { + tm := time.Unix(0, reading.Origin) + sTime := tm.Format(time.RFC822) + fmt.Fprintf(w, "%s\t%s\t%s\t%v\t%v\n", + sTime, reading.DeviceName, reading.ProfileName, reading.Value, reading.ValueType) + + } + } + w.Flush() + } + return nil +} diff --git a/internal/cmd/version.go b/internal/cmd/version.go index 27e6d9d..abf644b 100644 --- a/internal/cmd/version.go +++ b/internal/cmd/version.go @@ -18,6 +18,7 @@ package cmd import ( jsonpkg "encoding/json" + "fmt" "github.com/edgexfoundry/edgex-cli" "github.com/spf13/cobra" @@ -32,7 +33,7 @@ func init() { SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) (err error) { if !json { - cmd.Println("EdgeX CLI version: ", edgex.BuildVersion) + fmt.Println("EdgeX CLI version: ", edgex.BuildVersion) } err = showVersion(cmd) @@ -53,17 +54,17 @@ func showVersion(cmd *cobra.Command) error { if json { return err } else if verbose { - cmd.Printf("%s: %s: %s\n", serviceName, url, err.Error()) + fmt.Printf("%s: %s: %s\n", serviceName, url, err.Error()) } } else { if json { - cmd.Println(jsonValue) + fmt.Println(jsonValue) } else if verbose { - cmd.Printf("%s: %s: %s\n", serviceName, url, jsonValue) + fmt.Printf("%s: %s: %s\n", serviceName, url, jsonValue) } else { var result map[string]interface{} jsonpkg.Unmarshal([]byte(jsonValue), &result) - cmd.Println(serviceName + ": " + result["version"].(string)) + fmt.Println(serviceName + ": " + result["version"].(string)) } } } diff --git a/internal/service/coredataservice.go b/internal/service/coredataservice.go new file mode 100644 index 0000000..6efbe51 --- /dev/null +++ b/internal/service/coredataservice.go @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2021 Canonical Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0' + */ + +package service + +import ( + "context" + "errors" + "fmt" + "math/rand" + "strconv" + "strings" + + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/http" + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/interfaces" + "github.com/edgexfoundry/go-mod-core-contracts/v2/common" + "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos" + dtoCommon "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos/common" + "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos/requests" +) + +// RemoveEvents removes events, filtering either using a device name or +// a maximum event age, specified in milliseconds +func (c Service) RemoveEvents(device string, age int) error { + client := c.getEventClient() + + if device != "" && age != 0 { + return errors.New("either specify device name or event age, but not both") + } else if device != "" { + client.DeleteByDeviceName(context.Background(), device) + } else if age != 0 { + client.DeleteByAge(context.Background(), age) + } else { + return errors.New("event ID, device name or event age must be specified") + } + + return nil +} + +// CreateEvent creates a new event using the specified device, profile and source name and value type, with +// generating one or more sample readings +func (c Service) CreateEvent(deviceName string, profileName string, sourceName string, valueType string, numberOfReadings int) (string, error) { + + if numberOfReadings < 1 { + return "", errors.New("the number of readings must be at least 1") + + } + + client := c.getEventClient() + event := dtos.NewEvent(profileName, deviceName, sourceName) + valueType = strings.Title(strings.ToLower(valueType)) + + event.Readings = make([]dtos.BaseReading, numberOfReadings) + for i := 0; i < numberOfReadings; i++ { + var reading dtos.BaseReading + var err error + r64 := uint64(rand.Uint32())<<32 + uint64(rand.Uint32()) + var value interface{} + switch valueType { + case common.ValueTypeBool: + value = (r64&1 == 0) + case common.ValueTypeString: + value = "Reading " + strconv.Itoa(i) + case common.ValueTypeUint8: + value = uint8(r64) + case common.ValueTypeUint16: + value = uint16(r64) + case common.ValueTypeUint32: + value = uint32(r64) + case common.ValueTypeUint64: + value = r64 + case common.ValueTypeInt8: + value = int8(r64) + case common.ValueTypeInt16: + value = int16(r64) + case common.ValueTypeInt32: + value = int32(r64) + case common.ValueTypeInt64: + value = int64(r64) + case common.ValueTypeFloat32: + value = float32(r64) / 100 + case common.ValueTypeFloat64: + value = float64(r64) / 100 + default: + return "", errors.New("type must be one of [bool | string | uint8 | uint16 | uint32 | uint64 | int8 | int16 | int32 | int64 | float32 | float64 ]") + } + + reading, err = dtos.NewSimpleReading(profileName, deviceName, sourceName, valueType, value) + + if err != nil { + return "", err + } + event.Readings[i] = reading + + } + + response, err := client.Add(context.Background(), requests.NewAddEventRequest(event)) + return response.Id, err +} + +// ListAllEvents returns a sorted list of all available events, optionally limiting the list by +// specifying the offset and limit parameters. +// offset: The number of items to skip. Default is 0. +// limit: The number of items to return (-1 will return all remaining items). +func (c Service) ListAllEvents(offset, limit int) (events []dtos.Event, err error) { + + client := c.getEventClient() + response, err := client.AllEvents(context.Background(), offset, limit) + + if err != nil { + return nil, err + } + return response.Events, nil +} + +// ListAllReadings returns a sorted list of all available readings, optionally limiting the list by +// specifying the offset and limit parameters. +// offset: The number of items to skip. Default is 0. +// limit: The number of items to return (-1 will return all remaining items). +func (c Service) ListAllReadings(offset, limit int) (events []dtos.BaseReading, err error) { + + client := c.getReadingClient() + response, err := client.AllReadings(context.Background(), offset, limit) + + if err != nil { + return nil, err + } + return response.Readings, nil +} + +// CountEvents returns the number of events available, optionally filtered by a device name +func (c Service) CountEvents(device string) (response dtoCommon.CountResponse, err error) { + + client := c.getEventClient() + + if device != "" { + response, err = client.EventCountByDeviceName(context.Background(), device) + } else { + response, err = client.EventCount(context.Background()) + } + return +} + +func (c Service) getEventClient() interfaces.EventClient { + url := fmt.Sprintf("http://%s:%v", c.Host, c.Port) + return http.NewEventClient(url) + +} + +func (c Service) getReadingClient() interfaces.ReadingClient { + url := fmt.Sprintf("http://%s:%v", c.Host, c.Port) + return http.NewReadingClient(url) + +} diff --git a/internal/service/jsonservice.go b/internal/service/jsonservice.go new file mode 100644 index 0000000..b47ff63 --- /dev/null +++ b/internal/service/jsonservice.go @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2021 Canonical Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0' + */ + +package service + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "strings" + + "github.com/edgexfoundry/go-mod-core-contracts/v2/common" +) + +//GetVersionJSON returns the request URL and response for the 'version' endpoint. +func (c Service) GetVersionJSON() (json string, url string, err error) { + return c.callEndpoint(common.ApiVersionRoute) +} + +//GetPingJSON returns the request URL and response for the 'ping' endpoint. +func (c Service) GetPingJSON() (json string, url string, err error) { + return c.callEndpoint(common.ApiPingRoute) +} + +//GetConfigJSON returns the request URL and response for the 'config' endpoint. +func (c Service) GetConfigJSON() (json string, url string, err error) { + return c.callEndpoint(common.ApiConfigRoute) +} + +//GetMetricsJSON returns the request URL and response for the 'metrics' endpoint. +func (c Service) GetMetricsJSON() (json string, url string, err error) { + return c.callEndpoint(common.ApiMetricsRoute) +} + +//CountEventsByDeviceJSON returns the request URL and response for the 'event/count/device/name' endpoint. +func (c Service) CountEventsByDeviceJSON(device string) (json string, url string, err error) { + endpoint := strings.Replace(common.ApiEventCountByDeviceNameRoute, "{name}", device, 1) + return c.callEndpoint(endpoint) +} + +//CountEventsJSON returns the request URL and response for the 'event/count' endpoint. +func (c Service) CountEventsJSON() (json string, url string, err error) { + return c.callEndpoint(common.ApiEventCountRoute) +} + +//CountReadingsByDeviceJSON returns the request URL and response for the 'reading/count/device/name' endpoint. +func (c Service) CountReadingsByDeviceJSON(device string) (json string, url string, err error) { + + endpoint := strings.Replace(common.ApiReadingCountByDeviceNameRoute, "{name}", device, 1) + + return c.callEndpoint(endpoint) +} + +//CountReadingsJSON returns the request URL and response for the 'reading/count' endpoint. +func (c Service) CountReadingsJSON() (json string, url string, err error) { + return c.callEndpoint(common.ApiReadingCountRoute) +} + +//ListReadingsJSON returns all readings +func (c Service) ListAllReadingsJSON(offset, limit int) (json string, urlString string, err error) { + return c.getList(offset, limit, "", common.ApiAllReadingRoute) +} + +//ListEventsJSON returns all events +func (c Service) ListAllEventsJSON(offset, limit int) (json string, urlString string, err error) { + return c.getList(offset, limit, "", common.ApiAllEventRoute) +} + +func (c Service) getList(offset, limit int, labels string, endpoint string) (json string, urlString string, err error) { + if limit == -1 && offset == 0 && labels == "" { + json, urlString, err = c.callEndpoint(endpoint) + + } else { + var u *url.URL + u, err = url.Parse(endpoint) + if err != nil { + return "", "", err + } + + requestParams := url.Values{} + requestParams.Set(common.Offset, strconv.Itoa(offset)) + requestParams.Set(common.Limit, strconv.Itoa(limit)) + if len(labels) > 0 { + requestParams.Set(common.Labels, labels) + } + u.RawQuery = requestParams.Encode() + json, urlString, err = c.callEndpoint(u.String()) + } + return +} + +//callEndpoint calls an endpoint on this service and returns the result and the URL used +func (c Service) callEndpoint(endpoint string) (string, string, error) { + url := fmt.Sprintf("http://%s:%v%s", c.Host, c.Port, endpoint) + + resp, err := http.Get(url) + if err != nil { + return "", "", err + } + data, err := ioutil.ReadAll(resp.Body) + defer resp.Body.Close() + if err != nil { + return "", "", err + } + + return string(data), url, nil + +} diff --git a/internal/service/service.go b/internal/service/service.go index f9d1c88..b8befad 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -19,11 +19,8 @@ package service import ( "context" "fmt" - "io/ioutil" - gohttp "net/http" "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/http" - "github.com/edgexfoundry/go-mod-core-contracts/v2/common" dtoCommon "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos/common" ) @@ -36,30 +33,6 @@ type Service struct { Port int } -//GetVersionJSON returns the request URL and response for the 'version' endpoint. -func (c Service) GetVersionJSON() (json string, url string, err error) { - json, url, err = c.callEndpoint(common.ApiVersionRoute) - return -} - -//GetPingJSON returns the request URL and response for the 'ping' endpoint. -func (c Service) GetPingJSON() (json string, url string, err error) { - json, url, err = c.callEndpoint(common.ApiPingRoute) - return -} - -//GetConfigJSON returns the request URL and response for the 'config' endpoint. -func (c Service) GetConfigJSON() (json string, url string, err error) { - json, url, err = c.callEndpoint(common.ApiConfigRoute) - return -} - -//GetMetricsJSON returns the request URL and response for the 'metrics' endpoint. -func (c Service) GetMetricsJSON() (json string, url string, err error) { - json, url, err = c.callEndpoint(common.ApiMetricsRoute) - return -} - //GetMetrics returns the metrics for this service. func (c Service) GetMetrics() (result dtoCommon.Metrics, err error) { url := fmt.Sprintf("http://%s:%v", c.Host, c.Port) @@ -72,21 +45,3 @@ func (c Service) GetMetrics() (result dtoCommon.Metrics, err error) { return response.Metrics, nil } - -//callEndpoint calls an endpoint on this service and returns the result and the URL used -func (c Service) callEndpoint(endpoint string) (string, string, error) { - url := fmt.Sprintf("http://%s:%v%s", c.Host, c.Port, endpoint) - - resp, err := gohttp.Get(url) - if err != nil { - return "", "", err - } - data, err := ioutil.ReadAll(resp.Body) - defer resp.Body.Close() - if err != nil { - return "", "", err - } - - return string(data), url, nil - -} diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 8f8637c..3d0df3e 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -45,6 +45,7 @@ parts: - go/1.16/stable override-build: | cd $SNAPCRAFT_PART_SRC + make tidy make build install -DT "./bin/edgex-cli" "$SNAPCRAFT_PART_INSTALL/bin/edgex-cli" install -DT "./Attribution.txt" "$SNAPCRAFT_PART_INSTALL/usr/share/doc/edgex-cli/Attribution.txt"